2017-06-20 4 views
3

Ich möchte ein pdf mit itext 7, aber einige falsch mit uns geschieht generieren:Itext7 PDF mit Ausnahme generieren "Pdf indirektes Objekt gehört zu einem anderen PDF-Dokument. Kopiere Objekt in aktuelles PDF-Dokument."

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] 

mein Code generieren: in itext7

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 
    } 


} 

meine einzige Art Code:

private PdfFont bfChinese = null; 

wird init im Servicekonstruktor aufgerufen:

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

Ich habe versucht, meine Schriftart auf statische setzen, funktioniert aber nicht.

dies ist der Ort, throw Ausnahme:

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

es bedeutet, dass ich zwei verschiedene Dokument haben, aber ich weiß nicht, wenn ich ein anderes Dokument erstellen haben. Vielen Dank im Voraus für Anregungen.

Antwort

3

Ich habe das selbe Problem selbst erlebt (und es dauerte Stunden, bis ich entdeckte, was ich falsch gemacht hatte). Wie sich herausstellt, können Sie eine spezifische PdfFont Instanz für nur ein Dokument verwenden. Sobald Sie eine PdfFont Instanz verwenden, ist sie mit diesem Dokument verknüpft, und Sie können sie nicht mehr in einem anderen Dokument verwenden.

Zum Beispiel:

class ThisGoesWrong { 

    protected PdfFont font; 

    public ThisGoesWrong() { 
     font = PdfFontFactory.createFont(...); 
    } 

    public void createPdf() { 
     ... 
     Paragraph p = new Paragraph("test").setFont(font); 
     document.add(p); 
     ... 
    } 
} 

Die Klasse ThisGoesWrong schafft eine korrekte PDF zum ersten Mal createPdf() nennen, aber es zeigt die Ausnahme, die Sie haben, wenn Sie es ein zweites Mal anrufen.

entdeckte ich, dass dies das Problem löst:

class ThisWorksOK { 

    public ThisWorksOK() { 
    } 

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

Ich weiß nicht, ob dies ein Fehler ist (es fühlt sich sicher wie ein Fehler), so dass ich ein internes Ticket bei iText Gruppe erstellen.

+0

* Ich weiß nicht, ob dies ein Fehler ist (es fühlt sich sicher wie ein Bug) * - wenn Die Schriftart kann schließlich als Teilmenge der Glyphen aus einem in einem Dokument verwendeten Zeichensatzprogramm eingebettet werden. Es ist daher sinnvoll, sie als mit einem Dokument verknüpft zu betrachten. Andernfalls müssten Sie Daten über die verwendeten Glyphen pro Dokument sammeln. Natürlich kann man argumentieren, dass der Klassenname 'PdfFont' falsch ist, dass es' PdfDocumentFont' sein sollte. – mkl

+0

danke ein lottttttttttt. Es klappt . –

+0

@ Cheng.T Es gibt ein Häkchen auf der linken Seite, direkt neben der Null-Punktzahl für meine Antwort. Bitte überprüfen Sie diese Markierung, da meine Antwort Ihr Problem gelöst hat. –

1

preformance zu verbessern, sollten Sie FontProgram wiederverwenden:

private FontProgram bfChinese = null; 

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

Und dann:

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

yeah, mache Schrift privat, ich habe das gelöst, danke irgendwie. –

Verwandte Themen