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

使用itext编辑pdf时遇到异常

冯沛
2023-03-14

我在尝试使用iText编辑pdf文档时遇到以下异常。这个问题是非常零星的,就像有时它是工作的,有时它是抛出错误。

at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.access$6100(PdfContentStreamProcessor.java:60)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor$Do.invoke(PdfContentStreamProcessor.java:991)
at com.itextpdf.text.pdf.pdfcleanup.PdfCleanUpContentOperator.invoke(PdfCleanUpContentOperator.java:140)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.invokeOperator(PdfContentStreamProcessor.java:286)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.processContent(PdfContentStreamProcessor.java:425)
at com.itextpdf.text.pdf.pdfcleanup.PdfCleanUpProcessor.cleanUpPage(PdfCleanUpProcessor.java:160)
at com.itextpdf.text.pdf.pdfcleanup.PdfCleanUpProcessor.cleanUp(PdfCleanUpProcessor.java:135)
at RedactionClass.tgestRedactJavishsInput(RedactionClass.java:56)
at RedactionClass.main(RedactionClass.java:23)

下面是我用来编辑的代码:

public static void testRedact() throws IOException, DocumentException {

    InputStream resource = new FileInputStream("D:/itext/edited_120192824_5 (1).pdf");
    OutputStream result = new FileOutputStream(new File(OUTPUTDIR,
            "aviteshs.pdf"));

    PdfReader reader = new PdfReader(resource);
    PdfStamper stamper = new PdfStamper(reader, result);
    int pageCount = reader.getNumberOfPages();
    Rectangle linkLocation1 = new Rectangle(440f, 700f, 470f, 710f);
    Rectangle linkLocation2 = new Rectangle(308f, 205f, 338f, 215f);
    Rectangle linkLocation3 = new Rectangle(90f, 155f, 130f, 165f);
    List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
    for (int currentPage = 1; currentPage <= pageCount; currentPage++) {
        if (currentPage == 1) {
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation1, BaseColor.BLACK));
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation2, BaseColor.BLACK));
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation3, BaseColor.BLACK));
        } else {
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation1, BaseColor.BLACK));
        }
    }
    PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations,
            stamper);
    try {
        cleaner.cleanUp();
    } catch (Exception e) {
        e.printStackTrace();
    }
    stamper.close();
    reader.close();

}

共有1个答案

松英喆
2023-03-14

简而言之:这里出现NullPointerException的原因是iText不支持表单XObject资源从显示它们的页面继承。根据PDF规范,这个构造是过时的,但它可以在遵循早期PDF参考而不是规范的PDF中遇到。

该文档的第1页包含4个XObject资源,分别名为I1、M0、P1和Q0:

正如您在屏幕截图中所看到的,Q0特别没有自己的资源字典。但它最后的指示是

q
413 0 0 125 75 3086 cm
/I1 Do
Q

现在,对于表单XObjects,iText假设其内容引用的资源包含在自己的资源字典中。

结果:iText访问null字典,并出现nullPointerException

PDF规范ISO 32000-1规定:

按照PDF的早期版本编写的PDF文件可能省略了页面上使用的所有form XObjects和Type 3字体中的Resources条目。从这些表单和字体引用的所有资源都应从使用它们的页面的资源字典中继承。此构造已过时,一致性编写器不应使用。

(ISO 32000-1,第7.8.3节-资源词典)

因此,在目前的例子中,我们处于过时的选项三的情况下,Q0引用了在Q0所用于的页面的资源字典中定义的XObject I1。

有问题的文档有一个声称符合PDF 1.5的版本头(与PDF规范的PDF 1.7相反)。让我们看看PDF参考文献1.5。与备选案文三相对应的段落是:

  • form XObject或Type 3字体的字形描述可能会省略Resources条目,在这种情况下,将在使用该表单或字体的页面的Resources条目中查找资源。不建议使用此做法。

因此,总结起来,有问题的PDF使用了PDF规范(发布于2008年,使用了9年!)的构造调用过时,甚至PDF参考文件声称符合建议反对。另一方面,iText不支持这种过时的构造。

基本上,PDF清理代码必须扩展到

  • 记住PDFCleanupProcessor
  • 中当前页的资源
  • 如果Do运算符引用表单XObject时没有自己的资源,请在PDFCleanupContentOperator方法Invoke中使用这些当前页资源。

不幸的是,invoke中使用的一些成员是私有的。因此,必须复制PdfCleanUp代码或返回反射。

(iText 5.5.12-快照)

iText 7 PDF清理工具也遇到了PDF的问题,这里的例外情况是IllegalStateException声明“在事件调度后,图形状态总是被删除。如果要将其保留在呈现器信息中,请在收到呈现器信息后使用preserveGraphicsState方法。”

由于此异常是在事件调度期间抛出的,因此此错误消息没有意义。不幸的是,PDF清理工具在iText7中已成为封闭源码,因此不太容易确定问题。

(iText 7.0.3-快照;PDF清理1.0.2-快照)

 类似资料:
  • 我正在使用iText向现有pdf文件添加文本。它适用于简单的pdf,但与AcroForms的pdf存在问题。 我的代码: 错误消息:“此文档在Adobe Acrobat Reader DC中启用了扩展功能。文档自创建以来已更改,扩展功能的使用不再可用。请与作者联系以获取此文档的原始版本。” 并且没有我想添加到文件中的文本 知道我错过了什么吗?

  • 问题内容: 全部 我正在使用IText在PDF上添加文本层。现在我想编辑PDF上的现有图层,图层也仅由IText创建。似乎IText没有支持这种方法。 我想到的另一种方法是删除现有图层并在其位置放置新图层。似乎IText也不支持删除。有什么办法吗? 非常感谢。 问题答案: 事实证明,所讨论的图层是iText确实称为图层的,但实际上在PDF术语中却称为 可选内容组。 实际上,确实存在一个实用程序类,

  • 问题内容: 有谁知道用PHP编辑PDF的好方法?最好是开源/零许可证费用方法。:) 我是否正在考虑打开PDF文件,替换PDF中的文本然后写出PDF的修改版本? 我过去曾使用FPDF以编程方式创建PDF文件,但有时发现它有些笨拙。 问题答案: 如果您采用“填空”方法,则可以将文本精确地定位在页面上的任何位置。因此,将丢失的文本添加到文档中相对容易(即使不是很乏味)。例如,使用Zend Framewo

  • 问题内容: 有没有办法可以从Java编辑PDF? 我有一个PDF文档,其中包含需要使用Java替换的文本占位符,但是我看到的所有库都是从头开始创建PDF并具有小的编辑功能。 无论如何,我可以编辑PDF吗? 问题答案: 您可以使用iText做到这一点。我用以下代码对其进行了测试。它会在现有PDF的每一页上添加一段文本和一个红色圆圈。

  • null 有人能解释一下,当我使用PdfReader阅读模板后,我如何制作模板的副本吗?有没有办法把表格写到模板副本上,而不是一个新文档上? 为了将来的参考,我做了以下工作:

  • 我正在使用iText生成Pdf。但当我试图在pdf中添加图像时, 我mage.get实例(新的URL(timetableResource.getImageUrl()));document.add(学校标志); 但我得到的错误是 HTTP状态500-服务器为URL返回了HTTP响应代码400:http://139.59.72.150:8080/sms/attachments/23/42/school