首页 > 解决方案 > Error about indirect object with some PDF when splitting / merging

问题描述

I need to split or merge some pdf and I have some rare pdf that create the following exception.

com.itextpdf.kernel.PdfException: Pdf indirect object belongs to other PDF document. Copy object to current pdf document.at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:216)
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:206)
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:112)
at com.itextpdf.kernel.pdf.PdfWriter.writeToBody(PdfWriter.java:393)
at com.itextpdf.kernel.pdf.PdfWriter.flushObject(PdfWriter.java:301)
at com.itextpdf.kernel.pdf.PdfDocument.flushObject(PdfDocument.java:1743)
at com.itextpdf.kernel.pdf.PdfObject.flush(PdfObject.java:183)
at com.itextpdf.kernel.pdf.PdfObject.flush(PdfObject.java:152)
at com.itextpdf.kernel.pdf.PdfObjectWrapper.flush(PdfObjectWrapper.java:94)
at com.itextpdf.kernel.pdf.PdfPage.flush(PdfPage.java:505)
at com.itextpdf.kernel.pdf.PdfPage.flush(PdfPage.java:462)
at com.itextpdf.kernel.pdf.PdfDocument.close(PdfDocument.java:847)
at testPDF.PDF.splitByPage(PDF.java:564)
at testPDF.Main.main(Main.java:153)

After a bit of searching, i found this post about a similar problem :

Itext7 generate pdf with Exception "Pdf indirect object belongs to other PDF document. Copy object to current pdf document."

In my case, I only split and merge the pdf, I don't touch to the content of the pdf, so I don't know why this exception happens. (From what I understood, the exception come from a problem in the copying of some font).

My code is the following :

public static void splitByPage(File pdfToSplit, int nbPageByPDF){
    try {
        // Open the document in reading mode
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(pdfToSplit));

        List<PdfDocument> splitDocuments = new PdfSplitter(pdfDoc) {
            int partNumber = 1;

            @Override
            protected PdfWriter getNextPdfWriter(PageRange documentPageRange) {
                try {
                    return new PdfWriter(pdfToSplit.getAbsolutePath()
                                                   .substring(0,
                                                              pdfToSplit.getAbsolutePath()
                                                                        .lastIndexOf(".")
                                                              ) 
                                            + "splitPage_part" 
                                            + String.valueOf(partNumber++) 
                                            + ".pdf");
                } catch (FileNotFoundException e) {
                    throw new RuntimeException();
                }
            }
        }.splitByPageCount(nbPageByPDF);

        // Close all the part created
        for (PdfDocument doc : splitDocuments) {
            doc.close(); // exception throws at the first closing
        }

        // Close the initial pdf to split
        pdfDoc.close();

    }

This code is inspired from this example : https://developers.itextpdf.com/examples/stamping-content-existing-pdfs/clone-splitting-pdf-file

For the merging, the same error happens when i try to close the new pdf where I appended the pdf that cause the exceptions. (But i can do it the other way. I can append another pdf (without this problem) to the pdf with the problem).

I think that i need to find the way to copy the font directly from the initial pdf to each pdf i create, but i can't find the way to do it.

If needed, i can send you in private the pdf with which the error occur, only in private since this pdf is a bit confidential.

Thanks in advance for any help or suggestion.

标签: javapdfitext7

解决方案


此问题已在当前 7.1.3-SNAPSHOT 开发版本状态下得到修复。更准确地说,它已在解决问题 DEVSIX-1913(修复继承的页面条目的复制)的过程中于 2018 年 4 月 23 日 13:46:25 的提交 251606e55768a47cb68eb8c58f2f5fe36324d85b 中得到修复。

原因是在PdfPage.copyInheritedProperties(PdfPage, PdfDocument)某些属性中,值按原样添加到目标文档中。

这对于直接对象是可以的;在大多数 PDF 中,这些属性的值是直接对象,这在很长一段时间内都被忽视了。

有问题的页面属性是CropBox,在您的示例文档中,它恰好是从页面树的根继承而来的,并且具有间接值。

因此,您可以

  • 等待 7.1.3 版本,或
  • 使用 7.1.3-SNAPSHOT,或
  • 将修复程序反向移植到您的 iText 版本。在这种情况下,您只需更换

    copyPdfPage.put(PdfName.CropBox, cropBox);
    

    经过

    copyPdfPage.put(PdfName.CropBox, cropBox.copyTo(pdfDocument));
    

    PdfPage.copyInheritedProperties(PdfPage, PdfDocument).


推荐阅读