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

PdfBox无法导入页面

赵修诚
2023-03-14

我有以下代码

0. templatePage = (PDPage) PDDocument.load(file).getDocumentCatalog().getAllPages().get(0);
1. ...
2. document.importPage(templatePage); //first page
3. ... //draw stuff
4. document.importPage(templatePage); //next page
5. ...

如果在第三行我只画了一些东西,那么一切都很好。然而,如果我画了很多东西,那么我会得到:

Index: 12, Size: 0. Stacktrace follows:
java.lang.IndexOutOfBoundsException: Index: 12, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at org.apache.pdfbox.io.RandomAccessBuffer.seek(RandomAccessBuffer.java:84)
at org.apache.pdfbox.io.RandomAccessFileInputStream.read(RandomAccessFileInputStream.java:96)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at org.apache.pdfbox.pdmodel.PDDocument.importPage(PDDocument.java:654)
at xxx.PdfReport.breakPage(PdfReport.java:145)
at xxx.PdfReport.print(PdfReport.java:84)

以上代码在95%的情况下都能正常工作,只有当页面真正满了时才会出现问题。

如果在第2行。

 document.addPage(new PDPage());

那么它工作得很好。但目标是使用pdf模板。

共有2个答案

岳鸿畴
2023-03-14

主要问题是从文件中加载PDDocument,

PDDocument.load(file)

从中提取PDPage对象,

....getDocumentCatalog().getAllPages().get(0)

但是在使用页面时,不要再保留PDDocument实例。

document.importPage(templatePage)

因此,您允许垃圾回收机制声明PDDocument实例从PDPage实例下拉地毯:

一个PDPage对象不包含所有页面内容的所有信息,而只是一些对象标识符,这些标识符必须在document.importPage调用期间解析;如果源PDDocument同时已最终确定(由于未被引用,因此最终由垃圾回收机制处理),它们将无法再解析。

这方面的症状可能有所不同,在我的测试中,我没有得到任何异常,而是得到了一个严重的日志输出

No Kids found in getAllKids(). Probably a malformed pdf.

并且要么没有导入页面,要么导入的页面缺少一些资源,例如嵌入式字体。

(顺便说一句,我实际上更喜欢在这里得到一个异常,因为如果没有它,代码会假定它成功导入了页面)

只要您使用PDDocument实例,请坚持使用它:

0. PDDocument sourceDocument = PDDocument.load(file);
   templatePage = (PDPage) sourceDocument .getDocumentCatalog().getAllPages().get(0);
1. ...
2. document.importPage(templatePage); //first page
3. ... //draw stuff
4. document.importPage(templatePage); //next page
5. ...
   sourceDocument.close();

最终的源文档。closecall在您选择的时间释放资源,而不是在垃圾收集控制的时间释放资源。

将相同的模板PDPage导入两次的一个问题是,相同的内容流在结果文件中出现了两次,可能还有它的资源。根据相关页面的性质,这可能意味着相当大的开销。您可以通过将模板页面作为表单xject导入一次并在目标文档中的任意多页上包含对此xject的引用来解决此开销。

这个关于如何使用pdfbox在另一个PDPage中插入PDPage的答案解释了如何将模板页作为表单xobject导入,并将其放在当前pdfbox 2.0.0开发快照中的某个目标页上。当前版本1.8应该可以使用类似的功能。十、 我也是。

米迪
2023-03-14

黑客解决方案是:

每次使用前加载模板。确保模板文档不是GCd。然后它就会工作。

如果有人有正式的解决方案,请让我知道。

 类似资料:
  • 我试图从djangotoolbox.fields使用Listfield,但它给我一个错误说: 我做错了什么?

  • 所以我对Node和Webpack还不熟悉,我很难让我的项目正确编译。每次我将其加载到浏览器时,都会出现错误:。这是我的一份网页。配置。js文件: 这是我的主要作品的副本。js文件: 最后,这里是我已安装的节点包的列表: Babel-core Babel-loader Babel-preet-es2015 巴贝尔-预设-反应 巴贝尔-预设-阶段-0 Babelify 反应 report-dom we

  • 问题内容: 我已经开始编写可以在Google App Engine上运行的应用程序。 但是,当我想使用从Netbeans到Eclipse的代码时,出现以下错误: 和 错误是: 我尝试将Eclipse导入到Eclipse中,但还是一样,还尝试构建和清理项目。我不在Eclipse上使用Tomcat,而仅在Netbeans上使用它。我该如何解决这个问题? 问题答案: 我尝试将servlet-api.ja

  • 我觉得我把一切都安排好了。我遵循这些指示。 并从tar文件安装。 我的主目录现在有一个文件夹“gsutil”。我运行了配置来为oauth2设置我的应用程序,并且能够从命令行调用gsutil。为了使用gsutil和Google App Engine,我在我的主目录中的.bashrc文件中添加了以下行,并将其来源化: 但是,当我尝试导入我的python脚本: 或者类似这样的东西(直接从留档)。 我得到

  • 在添加vaadin依赖项后,我刚刚尝试导入PropertysetItem,但无法导入。有人能帮我找到正确的依赖吗

  • 我正在尝试编译一个示例Mahout代码。然而,我在导入GenericBooleanPrefitemBasedRecommiter时遇到问题。当我检查我的系统时,找到了库,目录中的其他库导入时没有问题。有人能指出我的错误吗?下面是我的代码片段和结果输出。谢谢 [信息]正在扫描项目。。。 [信息] [信息]------------------------------------------------