Adobe Reader 无法从我的项目中读取字体?

Adobe Reader cannot read fonts from my project?

我正在使用 iTextPdf version 5 生成 PDF,并在该 PDF 中使用 Calibri font。我在使用 Boot 时从 src/resource/fonts 文件夹加载了该字体。一切正常,因为我可以在我的项目中查看该 PDF 并下载,除了当我尝试使用 Adob​​e Reader 打开 PDF 时,页面显示类似的内容 -

我已经使用 Google Chrome、WPS office 和其他 PDF Reader 打开了那个 PDF,那个 PDF 工作得很好,但我似乎无法理解哪里出了问题当我尝试使用 Adob​​e 查看 PDF 时。下面我也附上了WPS office中PDF的截图-

这是我在 PDF 中加载字体的代码 -

static URL calibriFont = UserProfileController.class.getResource("/static/fonts/Calibri Regular.ttf");
static Font namefont = FontFactory.getFont(calibriFont.toString(), 20, Font.BOLD, new BaseColor(139, 0, 0));
FontFactory.register(calibriFont.toString());

这是下面分享的 PDF 文件 link - Sample PDF

简而言之

初始生成后向 PDF 添加了额外数据,引入了交叉引用错误。取文件的前1019493字节得到原始工作文件

我的第一个猜测是另一个程序错误地对 PDF 进行了后处理,但结果是 iText 对象被错误地关闭导致了那个错误。

详细

您共享的 PDF 的最终版本不是由 iText 生成的,至少不是由 iText 的正确使用生成的。

文件大小为 1021972 字节。最初的 1019493 字节构成了一个有效的 PDF。

额外的 2479 字节扩展了 PDF,提供了一些更新的旧对象、一些新对象和完整的交叉引用 table。而在这个交叉引用table中第一个新对象33的偏移条目是不正确的,它应该是0001019493(原始内容后添加的第一个字节,即第一个新对象的开始)但它是0001018667(原始 PDF 的交叉引用 table 的开始)。

因此,PDF 处理器在查找新对象 33 时将错误地找到原始交叉引用。

由于对象 33 恰好包含更新对象 1 中字体 Calibri 的 FontDescriptor,因此尝试解析此字体失败。所有文档页面都引用了该字体。

因此,Adobe Reader 在遇到使用该字体的指令时立即停止绘制每一页。

其他一些 PDF 查看器会在后台修复该错误,因此会显示您想要查看的内容。

实际原因

在您写的评论中

The error was coming due to PdfWriter instance object was closed before document.

确实,您根本不需要关闭 PdfWriter,尤其是在 Document 之前。

当使用 PdfWriter.getInstanceDocument 请求 PdfWriter 时,会创建一个 PdfDocument 实例并将其注册为 Document 的侦听器;然后创建 PdfWriter 并注册为 PdfDocument.

的侦听器

要完成 PDF 生成,您需要关闭 Document。这将调用它的监听器各自的 close 方法,即 PdfDocument.close,它将完成一些最后的对象,写入它们,然后调用它自己的监听器的 close 方法,即 PdfWriter.close ,这将写入交叉引用。

在您的代码中,您首先显式调用了 PdfWriter.close(它编写了第一个交叉引用 table),然后是 Document.close(这导致 PdfDocument 编写了一些对象和然后再次触发 PdfWriter.close 以编写第二个交叉引用)。这个不正确的序列也导致了不正确的交叉引用偏移。

我已经找到了我的问题的解决方案,我已经关闭了文档之前的 PdfWriter 个实例。当我在文档后关闭那个实例时,它工作正常。