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

Itext7使用异常生成pdf"pdf间接对象属于其他PDF文档。将对象复制到当前pdf文档。"

陶山
2023-03-14

我想生成一个pdf与itext7,但一些错误发生在我们身上:

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:195) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:185) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:115) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:187) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:115) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:187) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfOutputStream.write(PdfOutputStream.java:115) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfWriter.writeToBody(PdfWriter.java:383) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfWriter.flushObject(PdfWriter.java:289) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfDocument.flushObject(PdfDocument.java:1572) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfObject.flush(PdfObject.java:159) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfObject.flush(PdfObject.java:127) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfObjectWrapper.flush(PdfObjectWrapper.java:94) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfPage.flush(PdfPage.java:495) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfPage.flush(PdfPage.java:454) ~[kernel-7.0.2.jar:na]
at com.itextpdf.kernel.pdf.PdfDocument.close(PdfDocument.java:785) ~[kernel-7.0.2.jar:na]
at com.itextpdf.layout.Document.close(Document.java:120) ~[layout-7.0.2.jar:na]
at com.xcz.afbp.thirdparty.service.impl.GeneratePDFService.generatePDF(GeneratePDFService.java:160) ~[classes/:na]

我的生成代码:

public void generatePDF(CreditQueryData creditQueryData, Map<String, UserCreditContentView> contentViewMap, List<PackageCreditContentView> needRetrievedCreditContentList, File pdfFile, BigDecimal score) throws Exception {

    if (!pdfFile.exists()) {
        boolean x = pdfFile.createNewFile();
        if (!x) {
            LOG.error("生成文件出错" + pdfFile.getPath());
            return;
        }
    }

    PdfDocument pdf = new PdfDocument(new PdfWriter(new FileOutputStream(pdfFile)));
    Document document = new Document(pdf, PageSize.A4);
    document.setRenderer(new DocumentRenderer(document));

    pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new WatermarkingEventHandler());

    try {
        //operate code just add tableA tableB tableC...

    } catch (Exception e) {
        LOG.info();
    } finally {
        document.close(); //exception throws here
    }


}

itext7中我唯一的样式代码:

 private PdfFont bfChinese = null;

将在服务构造函数中调用init:

 public GeneratePDFService() {
    String PdfFontPath = EnvironmentUtils.getClasspathFilePath("font/MSYH.TTF");
    try {
        bfChinese =  PdfFontFactory.createFont(PdfFontPath, "Identity-H", true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我试过将字体设置为静态,但不起作用。

这是地方抛异常:

private void write(PdfIndirectReference indirectReference) {
        if (document != null && !indirectReference.getDocument().equals(document)) {
            throw new PdfException(PdfException.PdfIndirectObjectBelongsToOtherPdfDocument);
        }
        if (indirectReference.getRefersTo() == null) {
            write(PdfNull.PDF_NULL);
        } else if (indirectReference.getGenNumber() == 0) {
            writeInteger(indirectReference.getObjNumber()).
                    writeBytes(endIndirectWithZeroGenNr);
        } else {
            writeInteger(indirectReference.getObjNumber()).
                    writeSpace().
                    writeInteger(indirectReference.getGenNumber()).
                    writeBytes(endIndirect);
        }
    }

这意味着我有两个不同的文件,但我不知道我什么时候创建了另一个文件。提前感谢您的建议。

共有3个答案

魏彦
2023-03-14

我就是这样解决这个问题的。

>

  • 创建了一个DocumentUtil类
  • 添加静态方法

    public class DocumentUtils {    
        public static PdfFont setFont() throws Exception {
                return PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN);
        }
    }
    

    使用如下字体:

    PDfFont font = DocumentUtil.setFont();
    

  • 罗河
    2023-03-14

    为了提高性能,您应该重新使用FontProgram:

    private FontProgram bfChinese = null;
    
    public GeneratePDFService() {
        String PdfFontPath = EnvironmentUtils.getClasspathFilePath("font/MSYH.TTF");
        try {
            bfChinese =  FontProgramFactory.createFont(PdfFontPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    然后:

    public void createPdf() {
        ...
        PdfFont font = PdfFontFactory.createFont(bfChinese, "Identity-H", true);
        Paragraph p = new Paragraph("test").setFont(font);
        document.add(p);
        ...
    }
    
    索令
    2023-03-14

    我自己也经历过同样的问题(我花了几个小时才发现自己做错了什么)。事实证明,您只能对一个文档使用特定的PdfFont实例。一旦您使用了PdfFont实例,它就会链接到该文档,并且您不能再在另一个文档中使用它。

    例如:

    class ThisGoesWrong {
    
        protected PdfFont font;
    
        public ThisGoesWrong() {
            font = PdfFontFactory.createFont(...);
        }
    
        public void createPdf() {
            ...
            Paragraph p = new Paragraph("test").setFont(font);
            document.add(p);
            ...
        }
    }
    

    ThisGoesWrong在您第一次调用createPdf()时会创建一个正确的PDF,但在您第二次调用它时,它会显示异常。

    我发现这解决了问题:

    class ThisWorksOK {
    
        public ThisWorksOK() {
        }
    
        public void createPdf() {
            ...
            PdfFont font = PdfFontFactory.createFont(...);
            Paragraph p = new Paragraph("test").setFont(font);
            document.add(p);
            ...
        }
    }
    

    我不知道这是否是一个bug(感觉肯定像个bug),所以我将在iText Group创建一个内部票据。

     类似资料:
    • 问题内容: 我想用itext 7生成pdf,但是我们发生了一些错误: 我的生成代码: 我在itext7中唯一的样式代码: 将在服务构造函数中初始化init: 我尝试将我的字体设置为 static ,但是不起作用。 这是地方抛出异常: 这意味着我有两个不同的文档,但是我不知道何时创建另一个文档。在此先感谢您的建议。 问题答案: 我本人也遇到过同样的问题(花了我几个小时才能发现我做错了什么)。事实证明

    • 我现在试图修改一个只有文本内容的PDF文件。当我使用 谢谢

    • 问题内容: 我想使用命令 将一个PDF拆分为许多其他PDF。但是我发现有一个问题:拆分的PDF为“ ActiveMQ In Action(Manning-2011).pdf”,它的大小为14.1MB。但是当我跑步时 每个PDF都大于79MB!我该如何预防? 问题答案: 这是PDFBox 2.0.2中的一个已知错误。拆分在2.0.1中工作正常,在2.0.3中又可以工作。“错误的”代码已经恢复。问题的

    • 我有一本书的多份副本。不同用户评论的pdf文档。我想把所有这些评论合并成一个新的pdf“合并”。 我在一个名为“路径”和“目录”属性的文档类中编写了这个子类。 这段代码导致了一个我无法解决的异常。 iText。内核PDFEException:“Pdf间接对象属于其他Pdf文档。将对象复制到当前pdf文档。' 要执行此任务,我需要更改什么?还是我完全摆脱了我的代码块?

    • 在上载PDF过程开始之前,我需要检查PDF是否具有以下属性,

    • 我使用了Swagger UI来显示我的REST Web服务,并将其托管在服务器上。 然而,这种招摇过市的服务只能在特定的服务器上访问。如果我想脱机工作,有人知道我如何使用Swagger UI创建静态PDF并使用它吗?此外,PDF很容易与无权访问服务器的人共享。 非常感谢!