Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add an existing PDF from file to an unwritten document using iTextSharp

How do I correctly add the page(s) from an existing on-disk PDF file, to a currently-being-generated in-memory PDF document?

We have a class that produces a PDF document using iTextSharp. This works fine. At the moment we add a Terms & Conditions as an image at the last page:

this.nettPriceListDocument.NewPage();
this.currentPage++;
Image logo = Image.GetInstance("/inetpub/Applications/Trade/Reps/images/TermsAndConditions.gif");
logo.SetAbsolutePosition(0, 0);
logo.ScaleToFit(this.nettPriceListDocument.PageSize.Width, this.nettPriceListDocument.PageSize.Height);
this.nettPriceListDocument.Add(logo);

I have this image as a PDF document and would prefer to append it. If I can figure this out it would be possible to append other PDF documents we might need to what I am generating.

I have tried:

string tcfile = "/inetpub/Applications/Trade/Reps/images/TermsAndConditions.pdf";
PdfReader reader = new PdfReader(tcfile);
PdfWriter writer = PdfWriter.GetInstance(this.nettPriceListDocument, this.nettPriceListMemoryStream);
PdfContentByte content = writer.DirectContentUnder;
for (int pageno = 1; pageno < reader.NumberOfPages + 1; pageno++)
{
    this.nettPriceListDocument.NewPage();
    this.currentPage++;
    PdfImportedPage newpage = writer.GetImportedPage(reader, pageno);
    content.AddTemplate(newpage, 1f, 1f);
}

Which results in a "document not open" exception at the writer.DirectContentUnder

I've also tried:

string tcfile = "/inetpub/Applications/Trade/Reps/images/TermsAndConditions.pdf";
PdfReader reader = new PdfReader(tcfile);
PdfConcatenate concat = new PdfConcatenate(this.nettPriceListMemoryStream);
concat.AddPages(reader);

Which results in inserting a blank, oddly sized page over the usual first page of the document.

I've also tried:

string tcfile = "/inetpub/Applications/Trade/Reps/images/TermsAndConditions.pdf";
PdfReader reader = new PdfReader(tcfile);
PdfCopy copier = new PdfCopy(nettPriceListDocument, nettPriceListMemoryStream);
for (int pageno = 1; pageno < reader.NumberOfPages + 1; pageno++)
{
    this.currentPage++;
    PdfImportedPage newpage = copier.GetImportedPage(reader, pageno);
    copier.AddPage(newpage);
}
copier.Close();
reader.Close();

Which results in a NullReferenceException at copier.AddPage(newpage).

I've also tried:

string tcfile = "/inetpub/Applications/Trade/Reps/images/TermsAndConditions.pdf";
PdfReader reader = new PdfReader(tcfile);
PdfCopyFields copier = new PdfCopyFields(nettPriceListMemoryStream);
copier.AddDocument(reader);

This also results in a NullReferenceException at copier.AddDocument(reader).

I've got most of these ideas from various StackOverflow questions and answers. One thing that nobody seemed to deal with, is adding new page(s) from an existing PDF file, to an already-existing in-memory document that is not yet written to a PDF file on disk. This document has already been opened and had pages of data written into it. If I leave this Terms & Conditions procedure out, or just write it is an image (like originally), the resulting PDF comes out just fine.

To finish as I started: How do I correctly add the page(s) from an existing on-disk PDF file, to a currently-being-generated in-memory PDF document?

Thanks and appreciation in advance for your musings on this. Please let me know if I can provide further information.

like image 430
Troy Avatar asked Jul 25 '12 04:07

Troy


1 Answers

Here's a simple merge method that copies PDF files into one PDF. I use this method quite often when merging pdfs. I have used this to merge different sized pages as well without issue. Hope it helps.

public MemoryStream MergePdfForms(List<byte[]> files)
{
    if (files.Count > 1)
    {
        PdfReader pdfFile;
        Document doc;
        PdfWriter pCopy;
        MemoryStream msOutput = new MemoryStream();

        pdfFile = new PdfReader(files[0]);

        doc = new Document();
        pCopy = new PdfSmartCopy(doc, msOutput);

        doc.Open();

        for (int k = 0; k < files.Count; k++)
        {
            pdfFile = new PdfReader(files[k]);
            for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
            {
                ((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
            }
            pCopy.FreeReader(pdfFile);
        }

        pdfFile.Close();
        pCopy.Close();
        doc.Close();

        return msOutput;
    }
    else if (files.Count == 1)
    {
        return new MemoryStream(files[0]);
    }

    return null;
}
like image 157
Jonathan Avatar answered Sep 20 '22 01:09

Jonathan