ITEXT7 создает pdf файл с Exception “Pdf indirect object belongs to other PDF document. Copy object to current pdf document.”?

174
05 апреля 2019, 12:40

Я хочу создать pdf файл с использованием iText 7, но что-то не так:

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;

будет инициализирован в вызываемом конструкторе службы.

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

Я пробовал установить мой шрифт как static, но это не помогает. В этом месте я получаю exception:

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);
        }
    }

Это означает, что у меня два разных документа, но я не знаю каким образом я создал второй документ. Заранее благодарю за помощь!

Answer 1

Я столкнулся с такой же проблемой (у меня ушли часы, чтобы разобраться в том, что я делал не так). Как оказалось, вы можете использовать конкретный экземпляр 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 создает правильный PDF при первом вызове createPdf(), но показывает exception как у вас, когда вы вызываете его повторно.

Я нашел такое решение проблемы:

class ThisWorksOK {
    public ThisWorksOK() {
    }
    public void createPdf() {
        ...
        PdfFont font = PdfFontFactory.createFont(...);
        Paragraph p = new Paragraph("test").setFont(font);
        document.add(p);
        ...
    }
}
READ ALSO
Не распечатывается файл javax.print

Не распечатывается файл javax.print

пытаюсь распечатать файл, все отрабатывает без ошибок, Process finished with exit code 0 но файл не распечатываетсяпринтер рабочий, стандартными средствами...

143
При помощи Сканера удалить элементы Set [дубликат]

При помощи Сканера удалить элементы Set [дубликат]

На данный вопрос уже ответили:

127
Android, полный путь до директории

Android, полный путь до директории

Недавно начал изучать AndroidДелаю приложение, которое удаляет файлы из своей корневой папки

169
Не работает svg анимация

Не работает svg анимация

в анимации не отрабатывает fill-opacity

168