当前位置: 首页 > 知识库问答 >
问题:

PDFBox嵌入式TTF字体不工作

商冠玉
2023-03-14

我正在使用PDFBox从现有的PDF模板构建文档,因此它会打开文件,向其中添加文本,然后保存。除了尝试使用外部TTF字体外,它工作得很好。我尝试了不同的方法,花了两天时间寻找解决方案,但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();
         }
     }
 }

共有3个答案

楚皓君
2023-03-14

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

我正在努力解决同样的问题,我发现在我的例子中,使用PDDocument.save增量()时出了问题——恕我直言,这需要仔细考虑一个事实,即您需要在许多地方调用getCOSObject(). setNeedToBeUpdate(true),这并不容易立即弄清楚。所以以防万一,并缩小可能的问题,检查简单的PDDocument.save()是否有效。

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

茅星雨
2023-03-14

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

堆栈跟踪显示“无法读取字体TimesNewRoman的嵌入式TTF,粗体”,这当然是在看到与“pushback size”相关的错误之后,我们为其设置了一个新的属性值以通过(我看到的例外作为参考:org.apache.pdfbox.exceptions.WrappeIOException:无法回推480478字节以重新解析流。尝试使用系统属性增加回推缓冲区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中删除,并重新设计我们获取健康页面信息的方式。

徐鸿文
2023-03-14

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

文档或示例代码中没有提到这一点,充其量也非常微妙。我称之为bug,尤其是因为它“有效”(不会抛出任何异常),但会在页面上创建不确定和/或错误的结果。

 类似资料:
  • 请,我想知道从pdf中提取的字体是否嵌入,如何使用PDFBox实现这一点?

  • 我用PDFBox填写一个PDF表单,我在保存它之前把它变平。窗体具有文本和窗体字段的自定义字体。当我在未安装此自定义字体的设备上打开输出文档(具有平坦字段)时,普通文本的字体仍然正确,但平坦字段的字体显示为回退(?)字体。在安装了这种自定义字体的设备上,一切看起来都和预期的一样。 有没有办法在展平窗体后,强制对所有文本使用相同的自定义字体? 使用PDFBOX填写PDF表单时使用的代码(简化):

  • 我创建了一个网站,使用tcpdf动态创建PDF,并将字体嵌入到PDF中。用户可以选择一系列标准字体,如Arial、Verdana等。然后系统直接从我的服务器选择ttf字体,并使用下面的代码嵌入。这种字体的文本在大多数pdf浏览器上都可以看到,但iPad/iPhone的viewer没有显示出来。我下载了新(随机)版本的Arial。ttf作为测试(不确定文件中的差异,但现在似乎显示良好)。 我需要为许

  • 我的系统: Qt Embedded(开源版)4.8 用于图形的Linux帧缓冲区 字体:(拉丁语、日语、希腊语)。(/usr/lib/fonts) 我正在尝试将拉丁字母与其他类型的字符(例如日语)混合使用。我有拉丁字母和日语字符的字体,但它们不是同一种字体。我研究了帖子: Qt同时使用多个字体以及如何在Qt-embedded中正确输出多语言文本 我按照步骤操作,但无法正确显示所有字符 有没有办法表

  • 我在apache fop 1.0环境中使用嵌入式字体: 配置文件如下所示: 这工作得很好,文本以字体hnlt57con呈现。 我现在想做的是用粗体呈现一些文本: 配置文件如下所示: 不幸的是,文本没有以粗体显示,但是以和上面例子一样的方式显示。 添加一个额外的字体三元组(如 http://www.scriptorium.com/whitepapers/fop_fonts/FOP_fonts5.ht

  • 如果有人做了类似的事情,一个代码示例将非常有帮助。 提前谢了。