2

How would I merge several pdf pages into one with iTextSharp which also supports merging pages having form elements like textboxes, checkboxes, etc.

I have tried so many by googling, but nothing has worked well.

gunr2171
  • 16,104
  • 25
  • 61
  • 88
mns
  • 663
  • 2
  • 8
  • 22
  • Do you mean *merge several pdf pages into one* **page** or *one* **PDF**? And are the source pages in the same PDF or not? – mkl Mar 20 '13 at 14:04
  • i want to do in a single pdf – mns Mar 20 '13 at 14:13
  • So pages from one or more source documents shall be copied including form elements into one target PDF as separate pages? In that case @Jonathan's [answer](http://stackoverflow.com/a/6780582/1729265) he refers to in his answer here looks like what you need. – mkl Mar 20 '13 at 14:20
  • Yes i have tried Jonathan's code also which using PdfSmartCopy class to copy all the contents.But not working in some scenarios – mns Mar 20 '13 at 14:28
  • http://stackoverflow.com/questions/6029142/merging-multiple-pdfs-using-itextsharp-in-c-net/6056801#6056801 – Frank Myat Thu Mar 31 '14 at 05:03

4 Answers4

7

See my answer here Merging Memory Streams. I give an example of how to merge PDFs with itextsharp.

For updating form field names add this code that uses the stamper to change the form field names.

/// <summary>
/// Merges pdf files from a byte list
/// </summary>
/// <param name="files">list of files to merge</param>
/// <returns>memory stream containing combined pdf</returns>
public MemoryStream MergePdfForms(List<byte[]> files)
{
    if (files.Count > 1)
    {
        string[] names;
        PdfStamper stamper;
        MemoryStream msTemp = null;
        PdfReader pdfTemplate = null;
        PdfReader pdfFile;
        Document doc;
        PdfWriter pCopy;
        MemoryStream msOutput = new MemoryStream();

        pdfFile = new PdfReader(files[0]);

        doc = new Document();
        pCopy = new PdfSmartCopy(doc, msOutput);
        pCopy.PdfVersion = PdfWriter.VERSION_1_7;

        doc.Open();

        for (int k = 0; k < files.Count; k++)
        {
            for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
            {
                msTemp = new MemoryStream();
                pdfTemplate = new PdfReader(files[k]);

                stamper = new PdfStamper(pdfTemplate, msTemp);

                names = new string[stamper.AcroFields.Fields.Keys.Count];
                stamper.AcroFields.Fields.Keys.CopyTo(names, 0);
                foreach (string name in names)
                {
                    stamper.AcroFields.RenameField(name, name + "_file" + k.ToString());
                }

                stamper.Close();
                pdfFile = new PdfReader(msTemp.ToArray());
                ((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;
}
Community
  • 1
  • 1
Jonathan
  • 1,719
  • 1
  • 15
  • 19
  • If u take a single pdf page with form fields(just to try with one might be there many pages available) and the final processed pdf will come of with excellent result but if you will take the same for merging 3 to 4 times more, the first page is coming with all the form fields values but rest are coming blank :(... – mns Mar 20 '13 at 14:26
  • @mns Okay what you are having is the form fields have the same name and when you merge multiple of the same page it does not like them to all be the same. What you can do is update their names to name + _p1 for page 1 and so forth. See updated Answer. – Jonathan Mar 20 '13 at 14:42
  • @mns I threw this together from other code snippets i have, haven't tested it, hope it works for you. – Jonathan Mar 20 '13 at 14:55
  • @Jonathan..u r absolutely right.Thanks Jonathan for giving the best answer above all throughout the community ..:) – mns Mar 20 '13 at 15:13
  • @mns glad to be able to help. – Jonathan Mar 20 '13 at 15:30
  • 1
    If for some PDF with fields issues remain, you might want to try the class `PdfCopyFields` instead of `PdfSmartCopy` or `PdfCopy`... – mkl Mar 20 '13 at 15:30
  • It is a common mistake to tell iText that fields need to be merged too when merging forms. See http://stackoverflow.com/questions/23726947/itextsharp-adding-new-instances-of-an-existing-page/23731720#23731720 – Bruno Lowagie Oct 15 '14 at 06:46
3

Here is my simplified version of Jonathan's Merge code with namespaces added, and stamping removed.

public IO.MemoryStream MergePdfForms(System.Collections.Generic.List<byte[]> files)
{
    if (files.Count > 1) {
        using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream()) {
            using (iTextSharp.text.Document doc = new iTextSharp.text.Document()) {
                using (iTextSharp.text.pdf.PdfSmartCopy pCopy = new iTextSharp.text.pdf.PdfSmartCopy(doc, msOutput) { PdfVersion = iTextSharp.text.pdf.PdfWriter.VERSION_1_7 }) {
                    doc.Open();
                    foreach (byte[] oFile in files) {
                        using (iTextSharp.text.pdf.PdfReader pdfFile = new iTextSharp.text.pdf.PdfReader(oFile)) {
                            for (i = 1; i <= pdfFile.NumberOfPages; i++) {
                                pCopy.AddPage(pCopy.GetImportedPage(pdfFile, i));
                                pCopy.FreeReader(pdfFile);
                            }
                        }
                    }
                }
            }

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

    return null;
}
Carter Medlin
  • 11,857
  • 5
  • 62
  • 68
2

to merge PDF see "Merging two pdf pages into one using itextsharp"

Jeromy French
  • 11,812
  • 19
  • 76
  • 129
pdp
  • 609
  • 9
  • 22
  • Those asp.net forum posts unfortunately use `PdfWriter` with `GetImportedPage` but without annotation post processing; thus, form elements are lost while @mns explicitly mentioned forms being important. – mkl Mar 20 '13 at 14:01
1

Below is my code for pdf merging.Thanks Jonathan for giving suggestion abt renaming fields,which resolved the issues while merging pdf pages with form fields.

 private static void CombineAndSavePdf(string savePath, List<string> lstPdfFiles)
    {
        using (Stream outputPdfStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None))
        {

            Document document = new Document();
            PdfSmartCopy copy = new PdfSmartCopy(document, outputPdfStream);
            document.Open();
            PdfReader reader;
            int totalPageCnt;
            PdfStamper stamper;
            string[] fieldNames;
            foreach (string file in lstPdfFiles)
            {
                reader = new PdfReader(file);
                totalPageCnt = reader.NumberOfPages;
                for (int pageCnt = 0; pageCnt < totalPageCnt; )
                {
                     //have to create a new reader for each page or PdfStamper will throw error
                    reader = new PdfReader(file);
                    stamper = new PdfStamper(reader, outputPdfStream);
                    fieldNames = new string[stamper.AcroFields.Fields.Keys.Count];
                    stamper.AcroFields.Fields.Keys.CopyTo(fieldNames, 0);
                    foreach (string name in fieldNames)
                    {
                        stamper.AcroFields.RenameField(name, name + "_file" + pageCnt.ToString());
                    }
                    copy.AddPage(copy.GetImportedPage(reader, ++pageCnt));                     
                }
                copy.FreeReader(reader);                    
            }
            document.Close();
        }
    }
Brian Ogden
  • 18,439
  • 10
  • 97
  • 176
mns
  • 663
  • 2
  • 8
  • 22