Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iText - how to add pages to a document created with PdfCopy

I am using iText (specifically iTextSharp 4.1.6) and I want to create a PDF by combining pages from existing PDFs but also inserting new pages created from an image.

I have got these two parts working separately using PdfCopy and PdfWriter respectively. The code to create a page from an image looks like this:

PdfWriter pw = PdfWriter.GetInstance(doc, outputStream);
Image img = Image.GetInstance(inputStream);
doc.Add(img);
doc.NewPage();

Now, Since PdfCopy inherits from PdfWriter, I thought I would be able to add such "image pages" to my PdfCopy object using the same technique, but it doesn't work (if you instantiate a PdfCopy instead of a PdfWriter in the above example, nothing comes out on the page).

From a quick peek at the source code I notice that when the contstructor for PdfCopy calls the superclass constructor it does so with a new Document object, not the one passed in, so I guess this is the reason.

Is there a better way to go about this? At the moment my best guess is to create a single page Pdf from the image using PdfWriter and then add it to the document using PdfCopy, but that seems like a bit of a workaround.

like image 882
Andy Avatar asked Dec 21 '12 09:12

Andy


1 Answers

I recently had this issue, and the answers here arent actually that helpful. My use-case was basically "Take a bunch of PDFs and images (.jpg, .png etc) and combine them all into 1 PDF". I had to use PdfCopy because it preserves things like form fields and labels, where PdfWriter doesnt.

Basically, because PdfCopy wont allow you to create new pages with addPage(), you have to create a new PDF in memory with the image on the page, and then use PdfCopy to copy out the page from that PDF.

For example:

    Document pdfDocument = new Document();
    ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
    PdfCopy copy = new PdfCopy(pdfDocument, pdfOutputStream);

    pdfDocument.open();

    for (File file : allFiles) {
       if (/* file is PDF */) {
           /* Copy all the pages in the PDF file into the new PDF */
           PdfReader reader = new PdfReader(file.getAllBytes());
           for (int i = 1; i <= reader.getNumberOfPages(); i++) {
              copy.addPage(copy.getImportedPage(reader, i);
           }
       } else {
           /* File is image. Create a new PDF in memory, write the image to its first page, and then use PdfCopy to copy that first page back into the main PDF */
           Document imageDocument = new Document();
           ByteArrayOutputStream imageDocumentOutputStream = new ByteArrayOutputStream();
           PdfWriter imageDocumentWriter = PdfWriter.getInstance(imageDocument, imageDocumentOutputStream);

            imageDocument.open();

            if (imageDocument.newPage()) {

                image = Image.getInstance(file.getAllBytes());

                if (!imageDocument.add(image)) {
                   throw new Exception("Unable to add image to page!");
                }

                imageDocument.close();
                imageDocumentWriter.close();

                PdfReader imageDocumentReader = new PdfReader(imageDocumentOutputStream.toByteArray());

                copy.addPage(copy.getImportedPage(imageDocumentReader, 1));

                imageDocumentReader.close();
         }

     }
like image 141
Erin Drummond Avatar answered Nov 19 '22 11:11

Erin Drummond