使用itextsharp合并文件夹中的pdf文件

时间:2017-09-08 08:27:15

标签: c# pdf itext

我尝试使用下面的代码将pdf文件合并到一个文件夹中并输出到一个新文件中,但显然生成的文件似乎已损坏。

public Boolean MergeForm(String destinationFile, String sourceFolder)
    {
        try
        {
            using (MemoryStream stream = new MemoryStream())
            using (Document doc = new Document())
            using (PdfCopy pdf = new PdfCopy(doc, stream))
            {
                doc.Open();

                PdfReader reader = null;
                PdfImportedPage page = null;

                foreach (var file in Directory.GetFiles(sourceFolder))
                {
                    reader = new PdfReader(file);
                    for (int i = 0; i < reader.NumberOfPages; i++)
                    {
                        page = pdf.GetImportedPage(reader, i + 1);
                        pdf.AddPage(page);
                    }

                    pdf.FreeReader(reader);
                    reader.Close();
                }
                using (FileStream streamX = new FileStream(destinationFile, FileMode.Create))
                {
                    stream.WriteTo(streamX);
                }
            }
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

有人可以发现问题所在吗?谢谢。

1 个答案:

答案 0 :(得分:3)

  

有人能发现问题所在吗?

您的主要问题是您在MemoryStreamDocument完成创建PDF之前使用了PdfCopy的内容(在Dispose期间结束时using阻止)。因此,您可以保存不完整的PDF文件。

这样做应该起作用:

    using (MemoryStream stream = new MemoryStream())
    {
        using (Document doc = new Document())
        {
            PdfCopy pdf = new PdfCopy(doc, stream);
            pdf.CloseStream = false;
            doc.Open();

            PdfReader reader = null;
            PdfImportedPage page = null;

            foreach (var file in Directory.GetFiles(sourceFolder))
            {
                reader = new PdfReader(file);
                for (int i = 0; i < reader.NumberOfPages; i++)
                {
                    page = pdf.GetImportedPage(reader, i + 1);
                    pdf.AddPage(page);
                }

                pdf.FreeReader(reader);
                reader.Close();
            }
        }
        using (FileStream streamX = new FileStream(destinationFile, FileMode.Create))
        {
            stream.WriteTo(streamX);
        }
    }
顺便说一句,你也看到我没有将PdfCopy放入using块。这是因为Document在处置时隐式关闭PDFCopy。因此,首先处理PdfCopy然后再处理Document(尝试再次关闭PdfCopy)是不必要的,并且可能导致隐藏由于发生的其他异常而在块内抛出的异常在这个闭幕式马戏团里。

此外,我需要添加pdf.CloseStream = false,否则当PdfCopy关闭时内存流将会关闭。

有人说过,

  1. 当然你也应该使用AddDocument而不是像@Bruno所解释的那样自己迭代文档页面。
  2. 如果您立即写入文件流而不是内存流,则内存占用量会减少。