生成PDF时出错:ITextFontResolver:java.lang.RuntimeException:无法识别带有'Cp1252'的字体'Courier-BoldOblique'

时间:2018-02-23 12:13:05

标签: grails flying-saucer pdfrenderer

最近需要进行一些库更改,以便Apache POI用于docx支持。这包括将Itext版本从2.1.0更改为4.2.1

同时使用带飞碟的Grails Renderer插件。来自build.gradle:

compile 'org.xhtmlrenderer:flying-saucer-core:9.1.12'
compile 'org.xhtmlrenderer:flying-saucer-pdf:9.1.12'
compile 'org.xhtmlrenderer:flying-saucer-log4j:9.1.12'

compile ('org.grails.plugins:rendering:2.0.3') {
    exclude group: 'org.xhtmlrenderer', module: 'core-renderer'
}

compile("com.lowagie:itext:4.2.1")

生成PDF时,我得到以下例外:

java.lang.RuntimeException: Font 'Courier-BoldOblique' with 'Cp1252' is not recognized.
    at org.xhtmlrenderer.pdf.ITextFontResolver.createInitialFontMap(ITextFontResolver.java:470) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextFontResolver.<init>(ITextFontResolver.java:40) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.<init>(ITextRenderer.java:124) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.<init>(ITextRenderer.java:110) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.<init>(ITextRenderer.java:106) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.<init>(ITextRenderer.java:102) ~[flying-saucer-pdf-9.1.12.jar:na]
Caused by: com.lowagie.text.DocumentException: Font 'Courier-BoldOblique' with 'Cp1252' is not recognized.
    at com.lowagie.text.pdf.BaseFont.createFont(BaseFont.java:696) ~[itext-4.2.1.jar:na]
    at com.lowagie.text.pdf.BaseFont.createFont(BaseFont.java:603) ~[itext-4.2.1.jar:na]
    at com.lowagie.text.pdf.BaseFont.createFont(BaseFont.java:438) ~[itext-4.2.1.jar:na]
    at org.xhtmlrenderer.pdf.ITextFontResolver.createFont(ITextFontResolver.java:483) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextFontResolver.createFont(ITextFontResolver.java:479) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextFontResolver.addCourier(ITextFontResolver.java:491) ~[flying-saucer-pdf-9.1.12.jar:na]
    at org.xhtmlrenderer.pdf.ITextFontResolver.createInitialFontMap(ITextFontResolver.java:459) ~[flying-saucer-pdf-9.1.12.jar:na]

在查看代码时,上述异常发生在我的代码

  ITextRenderer theRenderer = new ITextRenderer()

我的代码在Tomcat上部署的war中运行。我可以看到字体文件(例如Courier-BoldOblique.afm,但它们位于itext-4.2.1.jar的jar /com/lowagie/text/pdf/fonts中。

如何让代码正确找到字体,以便ITextRenderer的创建成功?

2 个答案:

答案 0 :(得分:2)

发现问题:

  • 字体在com.lowagie.text.pdf.BaseFont中在静态初始化程序中初始化为本地变量BuiltinFonts14
  • 但是在内级fr.opensagres.xdocreport.itext.extension.font.AbstractFontRegistry的{​​{1}}中,有一个方法ExtendedBaseFont正在清除已初始化的clearBuiltinFonts

因此(丑陋)解决方案如下:

创建一个类:

BuiltinFonts14

然后每次在初始化public abstract class FixBaseFont extends BaseFont { public static void fixBuiltinFonts() { if (BuiltinFonts14.size() != 14) { BuiltinFonts14.clear(); BuiltinFonts14.put(COURIER, PdfName.COURIER); BuiltinFonts14.put(COURIER_BOLD, PdfName.COURIER_BOLD); BuiltinFonts14.put(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE); BuiltinFonts14.put(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE); BuiltinFonts14.put(HELVETICA, PdfName.HELVETICA); BuiltinFonts14.put(HELVETICA_BOLD, PdfName.HELVETICA_BOLD); BuiltinFonts14.put(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE); BuiltinFonts14.put(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE); BuiltinFonts14.put(SYMBOL, PdfName.SYMBOL); BuiltinFonts14.put(TIMES_ROMAN, PdfName.TIMES_ROMAN); BuiltinFonts14.put(TIMES_BOLD, PdfName.TIMES_BOLD); BuiltinFonts14.put(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC); BuiltinFonts14.put(TIMES_ITALIC, PdfName.TIMES_ITALIC); BuiltinFonts14.put(ZAPFDINGBATS, PdfName.ZAPFDINGBATS); } } }

之前添加对此课程的调用
ITextRenderer

答案 1 :(得分:2)

这个最新的依赖(xhtmlrenderer 9.1.22)将解决这个问题。 以某种方式 fr.opensagres.xdocreport.itext.extension.font.AbstractFontRegistry 清除 BuiltinFonts14。

<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf-itext5</artifactId>
    <version>9.1.22</version>
</dependency>