Search code examples
javamergeitextitext7

itext 7 (java) add image on a new page to the end of an existing pdf document


i'm new to itext 7. I have a list of documents with different content that I want to merge into a single PDF. The content types are PDF, JPG & PNG. My problem is that as soon as I merge a PDF and an image, the image is written over the already inserted content of the target PDF. How do I get each image to be added to a new page of the target PDF?

This is my Code:

    byte[] mergeInhalt(List<Dokument> dokumentList) throws IOException {
      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      PdfWriter pdfWriter = new PdfWriter(byteOut);
      PdfDocument pdfDocument = new PdfDocument(pdfWriter);
      Document completeDocument = new Document(pdfDocument);

      for (Dokument dokument : dokumentList) {
        byte[] inhalt = dokument.getInhalt();
        if (Objects.nonNull(inhalt)) {
            switch (dokument.getFormat().name()) {
                case "PDF":
                    addPdf(pdfDocument, inhalt);
                    break;
                case "JPG":
                case "PNG":
                    ImageData data = ImageDataFactory.create(inhalt);
                    Image image = new Image(data);
                    completeDocument.add(image);
                    break;
            }
        }
    }
    completeDocument.close();
    return byteOut.toByteArray();
}

private void addPdf(PdfDocument pdfDocument, byte[] inhalt) throws IOException {
    PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(inhalt));
    PdfDocument pdfDocumentToMerge = new PdfDocument(pdfReader);
    pdfDocumentToMerge.copyPagesTo(1, pdfDocumentToMerge.getNumberOfPages(), pdfDocument);
}

Merging PDFs only works well, but everytime i merge a Image i get this:

enter image description here

The image with the pink one was placed over the text of the previous PDF


Solution

  • In your code you add the image via the Document completeDocument but you add the pdf via the underlying PdfDocument pdfDocument. Thus, the completeDocument doesn't know about the added pdf, continues on its current page, and draws over the imported pages.

    To make sure each image is added on a new page after the currently last one, you have to tell completeDocument to move its current page:

    case "JPG":
    case "PNG":
        ImageData data = ImageDataFactory.create(inhalt);
        Image image = new Image(data);
        completeDocument.add(new AreaBreak(AreaBreakType.LAST_PAGE));
        completeDocument.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        completeDocument.add(image);
        break;
    

    For an example compare the tests testMergeLikeAndreasHuber and testMergeLikeAndreasHuberImproved in CopyPdfsAndImages and their outputs.