Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PDFBox嵌入的TTF字体不工作_Java_Pdfbox_Truetype - Fatal编程技术网

Java PDFBox嵌入的TTF字体不工作

Java PDFBox嵌入的TTF字体不工作,java,pdfbox,truetype,Java,Pdfbox,Truetype,我正在使用PDFBox从现有的PDF模板构建文档,因此它会打开文件,向其中添加文本并保存。除了尝试使用外部TTF字体外,它工作正常。我尝试了不同的方法,花了2天的时间寻找解决方案,但PDFBox上的内容并不多 这里有一些使用字体的代码,因为它不会被误认为其他任何东西,并且不可能是任何标准库的一部分 代码执行良好,显示println中的“TardyKid”(显示字体已加载且名称可获取),并显示文本——但它在Helvetica中。代码中使用getStringWidth()计算宽度的更复杂部分似乎也表

我正在使用PDFBox从现有的PDF模板构建文档,因此它会打开文件,向其中添加文本并保存。除了尝试使用外部TTF字体外,它工作正常。我尝试了不同的方法,花了2天的时间寻找解决方案,但PDFBox上的内容并不多

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

代码执行良好,显示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();
         }
     }
 }

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


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

我也遇到过类似的问题,这是因为在构建war文件时,pom更新损坏了pdf模板文件

堆栈跟踪声明“无法读取字体TimesNewRoman,Bold的嵌入式TTF”,这当然是在看到与“pushback size”相关的错误之后,我们为其设置了一个新的属性值以使其通过(我看到的异常仅供参考:
org.apache.pdfbox.exceptions.WrappedIOException:无法回推480478字节以重新分析流。请尝试使用系统属性org.apache.pdfbox.baseParser.pushBackSize增加回推缓冲区。

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

问题的根本原因是我们在pom中为资源文件夹添加了“筛选”。我们这样做是为了使用一些反射来获取健康检查页面中的一些值,但这破坏了pdf文件,我们从以下参考中了解到:

下面是我们设置的筛选的一个示例:

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

src/main/resources
真的

我们的解决方案是将其从pom中删除,并重新修改我们获取健康页面信息的方式。

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

我也遇到了同样的问题,我发现在我的例子中,使用PDDocument.saveIncremental()时出现了一些问题,这与您需要调用getCOSObject().setNeedToBeUpdated(true)有关在许多地方,这些问题很难马上解决。为了以防万一,并缩小可能出现的问题,请检查simple PDDocument.save()是否有效


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

经过进一步测试,似乎只有在之后再次调用SetFont以获取另一段文本时才会出现问题。所有文本似乎都会恢复到上一个字体集。如果我只设置了一段文本,或在同一字体中设置了多段文本(Tardy Kid),则会正常工作。