【发布时间】:2012-08-19 01:31:51
【问题描述】:
我们使用 iText 从 Java 代码生成 PDF 文件,这在大多数情况下运行良好。几天前,我们开始生成 PDF/A,而不是需要嵌入所有字体的普通 PDF 文件。 iText Document 主要由自定义 PdfPTable 和其他我们直接控制字体的类构建。所有使用的字体都是从通过以下代码加载的 TTF 文件创建的 - 效果很好:
private BaseFont load(String path) {
try {
URL fontResource = PrintSettings.class.getResource(path);
if (fontResource == null) {
return null;
}
String fontPath = fontResource.toExternalForm();
BaseFont baseFont = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
baseFont.setSubset(true);
return baseFont;
}
catch (DocumentException ex) {
Logger.getLogger(PrintSettings.class).warn("...");
}
catch (IOException ex) {
Logger.getLogger(PrintSettings.class).warn("...");
}
return FontFactory.getFont(PrintSettings.FONT, "UTF-8", true, 8f, Font.NORMAL, PrintSettings.COLOR_TEXT).getBaseFont();
}
现在我们在从 HTML 代码生成的 PDF 中使用一种特定的内容类型。我们使用XMLWorker 来处理该部分。这工作得很好,只要我们没有嵌入字体。但是对于 PDF/A,我们需要嵌入所有字体,而现在我们正在努力解决 Helvetica 用法的未知来源。
我们已经尝试通过使用我们自己的 FontProvider 类来解决这个问题:
public class PrintFontProvider extends FontFactoryImp {
@Override
public Font getFont(String fontName, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {
// LiberationSans – http://de.wikipedia.org/wiki/Liberation_(Schriftart) – http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web
if (style == Font.NORMAL) return new Font(this.load("fonts/Liberation/LiberationSans-Regular.ttf"), size, Font.NORMAL, color);
if (style == Font.BOLD) return new Font(this.load("fonts/Liberation/LiberationSans-Bold.ttf"), size, Font.NORMAL, color);
if (style == Font.BOLDITALIC) return new Font(this.load("fonts/Liberation/LiberationSans-BoldItalic.ttf"), size, Font.NORMAL, color);
if (style == Font.ITALIC) return new Font(this.load("fonts/Liberation/LiberationSans-Italic.ttf"), size, Font.NORMAL, color);
return new Font(this.load("fonts/Liberation/LiberationSans-Regular.ttf"), size, style, color);
}
private BaseFont load(String path) { ... }
}
它使用以下代码与XMLWorker 连接:
HtmlPipelineContext html = new HtmlPipelineContext(null);
html.setTagFactory(Tags.getHtmlTagProcessorFactory());
CSSResolver css = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
// We need to control the FontProdiver!
html.setCssAppliers(new CssAppliersImpl(new PrintFontProvider()));
Pipeline<?> pipeline = new CssResolverPipeline(css, new HtmlPipeline(html, new PdfWriterPipeline(this.document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(StringUtils.iTextHTML(string).getBytes()));
大多数简单的 HTML 元素都以这种方式工作...但是有些似乎忽略了 FontProvider 并继续使用不会嵌入到 PDF/A 中的 Helvetica(我们不有那个字体)。例如<ol><li>...</li></ol> 使用这个。
Caused by: com.itextpdf.text.pdf.PdfXConformanceException: All the fonts must be embedded. This one isn't: Helvetica
at com.itextpdf.text.pdf.internal.PdfXConformanceImp.checkPDFXConformance(PdfXConformanceImp.java:225)
at com.itextpdf.text.pdf.PdfWriter.addSimple(PdfWriter.java:2192)
at com.itextpdf.text.pdf.PdfContentByte.setFontAndSize(PdfContentByte.java:1444)
at com.itextpdf.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1463)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:968)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:841)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1189)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1208)
at com.itextpdf.text.pdf.PdfDocument.flushLines(PdfDocument.java:1193)
at com.itextpdf.text.pdf.PdfDocument.newPage(PdfDocument.java:830)
at com.itextpdf.text.Document.newPage(Document.java:367)
我现在已经没有如何摆脱 Helvetica 的想法了......现在尝试解决这个问题 8 多个小时......还有更多想法吗?
【问题讨论】:
-
<ol>目前是我们的问题...<ul>工作正常。我注意到<ul>要求 ZapfDingbats 但<ol>根本不要求任何字体。我想它使用 Helvetica 而不问...当我应用 list-style-type: disc; 它不会尝试嵌入该字体。 -
更新到 iText v5.3.2 和 XMLWorker v1.1.6... 还是一样。无法摆脱 Helvetica für
<ol> -
即使我们从从 OSX Helvetica.dfont 文件中提取的 TTF 文件中嵌入 Helvetica 也会引发异常。它只是忽略了先前嵌入的字体。
-
你能重新实现 CssAppliersImpl 并看看 css 究竟适用于
- 标签吗?
-
我发现它完全忽略了符号/数字的任何字体系列...使用 ZapfDingbats 表示项目符号,默认 (Helvetica) 表示编号列表。只有
ol { list-style-type: disc; }有所作为... font-family 没有涉及数字和项目符号。
标签: java pdf fonts embed itext