PDF由ItextSharp合并

时间:2013-03-20 11:15:19

标签: c# itextsharp

如何将多个pdf页面合并到一个iTextSharp的页面中,该页面还支持合并具有 form 元素的页面,例如textboxes,{{1等等。

我通过谷歌搜索尝试了这么多,但没有什么效果很好。

4 个答案:

答案 0 :(得分:7)

请在此处查看我的回答Merging Memory Streams。我举一个如何将PDF与itextsharp合并的例子。

要更新表单字段名称,请添加使用压模更改表单字段名称的代码。

/// <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;
}

答案 1 :(得分:2)

答案 2 :(得分:2)

这是我的Jonathan合并代码的简化版本,添加了名称空间,并删除了标记。

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;
}

答案 3 :(得分:1)

以下是我的pdf合并代码。感谢 Jonathan 提供建议abt重命名字段,这解决了将pdf页面与表单字段合并时的问题。

 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();
        }
    }