7

我正在使用 PDFBox 从现有的 PDF 模板构建文档,因此它会打开文件、向其中添加文本并保存它。它运行良好,除非尝试使用外部 TTF 字体。我尝试了不同的方法并搜索了 2 天的解决方案,但 PDFBox 上没有太多内容。

这是一些代码,使用字体“Tardy Kid”,因为它不会被误认为是其他任何东西,并且不太可能是任何标准库的一部分。

代码执行良好,从 println 显示“TardyKid”(显示字体已加载且名称可获取),并显示文本——但它在 Helvetica 中。用于计算宽度的更复杂的代码部分getStringWidth()似乎也表明宽度表的成功加载。它只是无法正确显示。

该代码在一个更大的程序的上下文中运行,该程序打开一个现有的 PDF 文档(一个模板)并向其中添加文本。一切似乎都很好,除了

 public void setText ( PDDocument document, String text ) throws IOException {
     int lastPage = document.getNumberOfPages() - 1;
     PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(lastPage);
     PDPageContentStream contentStream = null;
     try {
         contentStream = new PDPageContentStream(document,page,true,true,false);
         File fontFile = new File(m_fontDir, "Tardy_Kid.ttf");
         PDFont font = PDTrueTypeFont.loadTTF(document, fontFile);
         Color color =  new Color(196, 18, 47);
         float x = 100f, y = 700f;
         System.out.println(font.getBaseFont());
         contentStream.setFont(font, 32);
         contentStream.setNonStrokingColor(color);
         contentStream.beginText();
         contentStream.moveTextPositionByAmount(x,y);
         contentStream.drawString(text);
         contentStream.endText();
     } finally {
         if (contentStream != null) {
             contentStream.close();
         }
     }
 }
4

3 回答 3

5

我找到了答案。我不确定这是否是 PDFBox 中的错误,但如果您在同一页面上多次打开/关闭内容流(由 PDPageContentStream 返回),则它无法正常工作。因此,当在页面上多次调用例程时,在 setText 例程中打开/关闭内容流不起作用。将流移到例程之外并为整个页面打开/关闭一次似乎可以解决这个问题(以及其他几个问题)。

这在文档或示例代码的任何地方都没有提到,充其量是非常微妙的。我将其称为错误,尤其是因为它“有效”(不会引发任何异常)但会在页面上产生不确定和/或错误的结果。

于 2013-05-31T01:29:13.347 回答
2

我有一个类似的问题,它来自一个 pom 更新,它在构建我们的 war 文件时损坏了 pdf 模板文件。

堆栈跟踪表明“无法读取字体 TimesNewRoman,Bold 的嵌入式 TTF”,当然这是在看到与“推回大小”相关的错误之后,我们设置了一个新的属性值以使其过去(我看到的异常以供参考:org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 480478 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize)。

我们花了一段时间,但是在爆炸战争并试图打开战争中的pdf文件后,我们注意到它已损坏,但源中的pdf文件并没有损坏。

问题的根本原因是我们在 pom 中为资源文件夹添加了“过滤”。我们这样做是为了在我们的健康检查页面中使用一些反射来获取一些值,但这破坏了 pdf 文件,我们从以下参考中发现:https ://bitbucket.org/petermr/xhtml2stm/issues/ 12/pdf-files-are-being-corrupted-at-some

下面是我们设置的过滤示例:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>

我们的解决方案是从我们的 pom 中删除它,并重新设计我们如何获取健康页面的信息。

于 2018-01-17T01:00:26.900 回答
0

多年后,随着 PDFBOX 接近 3.0.0 版本(但正式在 2.0.23 版本上),上述(尤其是对于 Unicode)似乎是使用 PDType0Font.load() 完成的(在 2.0 版本的迁移指南中提到)根据关于SO的问题。

我在同样的问题上苦苦挣扎,我发现在我的情况下,使用 PDDocument.saveIncremental() 时出现问题 - 恕我直言,需要仔细考虑与您需要调用 getCOSObject().setNeedToBeUpdated(true ) 在许多不容易弄清楚的地方。因此,以防万一,并缩小可能出现的问题,检查简单的 PDDocument.save() 是否有效。

顺便说一句,我确实检查了其他建议,即打开并写入 PDPageContentStream 一次而不是多次,并检查字体本身是否被 Maven 资源过滤损坏,但事实并非如此。为了排除第二个问题,仅供参考,如果您需要 LiberationSans-Regular TTF 字体,它作为资源嵌入在 PDFBOX 本身中,无需添加到您自己的资源中。

于 2021-03-26T06:28:17.513 回答