Why does the function to concatenate / merge PDFs cause issues in some cases?

Tags: merge documentsconcatenatePdfCopyPdfSmartCopyiText 5

I'm using the following code to merge PDFs together using iText:

public static void concatenatePdfs(List<File> listOfPdfFiles, File outputFile)
    throws DocumentException, IOException {
    Document document = new Document();
    FileOutputStream outputStream = new FileOutputStream(outputFile);
    PdfWriter writer = PdfWriter.getInstance(document, outputStream);
    document.open();
    PdfContentByte cb = writer.getDirectContent();
    for (File inFile : listOfPdfFiles) {
        PdfReader reader = new PdfReader(inFile.getAbsolutePath());
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            document.newPage();
            PdfImportedPage page = writer.getImportedPage(reader, i);
            cb.addTemplate(page, 0, 0);
        }
    }
    document.close();
}
This usually works great! But once and a while, it's rotating some of the pages by 90 degrees? Anyone ever have this happen?

Posted on StackOverflow on Apr 14, 2014 by Nicholas DiPiazza

There are errors once in a while because you are using the wrong method to concatenate documents. You should not use PdfWriter to concatenate (or merge) PDF documents. That is wrong because:

  • You completely ignore the page size of the pages in the original document (you assume they are all of size A4),
  • You ignore page boundaries such as the crop box (if present),
  • You ignore the rotation value stored in the page dictionary,
  • You throw away all interactivity that is present in the original document, and so on.

Concatenating PDFs is done using PdfCopy, see for instance:

Document document = new Document();
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
document.open();
PdfReader reader;
String line = br.readLine();
// loop over readers
    // add the PDF to PdfCopy
    reader = new PdfReader(baos.toByteArray());
    copy.addDocument(reader);
    reader.close();
// end loop
document.close();

If you are merging documents that contain fields, you need to add the following line:

copy.SetMergeFields();