使用 iTextSharp 将带有内存流的 PDF 保存在列表中

Save PDF with memory stream in a list using iTextSharp

我想从文件系统中读取一个多页 pdf 文件并将其拆分为单独的页面。我喜欢将拆分的页面保存到列表对象中。列表中的页面我想保存在 xml 中的 base64 编码结构中,并通过休息 api 服务发送它。

我已经做了什么:

  1. 阅读pdf文件
  2. 将 pdf 文件拆分为页面
  3. 将页面保存到列表

与我的问题的完整性无关的内容:

  1. 休息后发送页面api 服务 waqsy(当前未实现代码)
  2. Xml结构

我的问题是什么? 如果我将字节数组列表中的页面保存到文件系统并打开 pdf(只有原始页面的一页),pdf 文件有缺陷并且无法打开

我在这个过程中犯了什么错误?

我使用什么版本的 iTextSharp? 5.4.2

public List<byte[]> SplitAndSaveWithMemoryStream(string inputFilePath)
{
   // create the list
   List<byte[]> pages = new List<byte[]>();

    // get the input pdf
    using (PdfReader reader = new PdfReader(inputFilePath))
    {
        // iterate over the pages
        for (int pagenumber = 1; pagenumber <= reader.NumberOfPages; pagenumber++)
        {
             Document document = new Document();
             MemoryStream memoryStream = new MemoryStream();
            
             PdfCopy copy = new PdfCopy(document, memoryStream);

             document.Open();

             // copy the n-th page to the memory stream
             copy.AddPage(copy.GetImportedPage(reader, pagenumber));

             memoryStream.Position = 0;

             // save the page from the memory stream to the list
             pages.Add(memoryStream.ToArray());

             // -- TEST ---
             // save the file, only for test
             // string fullfilePath = "C://temp/temp.pdf";
             // File.WriteAllBytes(fullfilePath, pages[pagenumber]);

             document.Close();
      }

      return pages;
}
          

Xml结构:

<document>
  <page>
    <number>1</number>
    <content>dZwmxjwiduasmma...</content>
  </page>
  <page>
    <number>2</number>
    <content>ddiw92kjd2002jd929...</content>
  </page>
  <page>
    <number>3</number>
    <content>d82kdjEiuwowpdo...</content>
  </page>
</document>

解决方案 'mkl'

public List<byte[]> SplitAndSaveWithMemoryStream(string inputFilePath)
{
   // create the list
   List<byte[]> pages = new List<byte[]>();

    // get the input pdf
    using (PdfReader reader = new PdfReader(inputFilePath))
    {
        // iterate over the pages
        for (int pagenumber = 1; pagenumber <= reader.NumberOfPages; pagenumber++)
        {
             Document document = new Document();
             MemoryStream memoryStream = new MemoryStream();
            
             PdfCopy copy = new PdfCopy(document, memoryStream);

             document.Open();

             // copy the n-th page to the memory stream
             copy.AddPage(copy.GetImportedPage(reader, pagenumber));

             document.Close();

             // save the page from the memory stream to the list
             pages.Add(memoryStream.ToArray());

             // -- TEST ---
             // save the file, only for test
             // string fullfilePath = "C://temp/temp.pdf";
             // File.WriteAllBytes(fullfilePath, pages[pagenumber]);
      }

      return pages;
}

MemoryStream 中的 PDF 在 document 关闭之前尚未完成。因此,您存储的 PDF 不完整。

要解决此问题,请移动

document.Close();

紧接着

copy.AddPage(...);

顺便说一句,如果我没记错的话,在 memoryStream.ToArray() 之前不需要 memoryStream.Position = 0,因为 ToArray 总是获取内存流的全部内容。