生成 PDF 时出错:ITextFontResolver:java.lang.RuntimeException:无法识别带有 'Cp1252' 的字体 'Courier-BoldOblique'
Error Generating PDF: ITextFontResolver: java.lang.RuntimeException: Font 'Courier-BoldOblique' with 'Cp1252' is not recognized
最近需要对库进行一些更改,以便可以将 Apache POI
用于 docx
支持。这包括将 Itext
版本从 2.1.0
更改为 4.2.1
。
还将 Grails 渲染器插件与飞碟一起使用。来自 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
,但它们在 /com/lowagie/text/pdf/fonts
中的 jar itext-4.2.1.jar
中。
如何获取正确查找字体的代码,以便创建 ITextRenderer
成功?
发现问题:
- 字体在
com.lowagie.text.pdf.BaseFont
中在静态初始化程序中初始化为局部变量 BuiltinFonts14
- 然而在
fr.opensagres.xdocreport.itext.extension.font.AbstractFontRegistry
中inner-classExtendedBaseFont
有一个方法clearBuiltinFonts
清除初始化的BuiltinFonts14
因此(丑陋的)解决方案如下:
创建 class:
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
之前添加对这个class的调用
FixBaseFont.fixBuiltinFonts()
ITextRenderer renderer = new ITextRenderer()
这个最新的依赖项 (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>
最近需要对库进行一些更改,以便可以将 Apache POI
用于 docx
支持。这包括将 Itext
版本从 2.1.0
更改为 4.2.1
。
还将 Grails 渲染器插件与飞碟一起使用。来自 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
,但它们在 /com/lowagie/text/pdf/fonts
中的 jar itext-4.2.1.jar
中。
如何获取正确查找字体的代码,以便创建 ITextRenderer
成功?
发现问题:
- 字体在
com.lowagie.text.pdf.BaseFont
中在静态初始化程序中初始化为局部变量BuiltinFonts14
- 然而在
fr.opensagres.xdocreport.itext.extension.font.AbstractFontRegistry
中inner-classExtendedBaseFont
有一个方法clearBuiltinFonts
清除初始化的BuiltinFonts14
因此(丑陋的)解决方案如下:
创建 class:
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
FixBaseFont.fixBuiltinFonts()
ITextRenderer renderer = new ITextRenderer()
这个最新的依赖项 (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>