【问题标题】:iText7 Merge of 2 PDF MemorStreams Not Working2个PDF MemorStreams的iText7合并不起作用
【发布时间】:2020-01-14 19:23:42
【问题描述】:

我正在将一些较旧的 iTextSharp 代码升级到新的 iText 7 库。我在确定将 2 个 PDF MemoryStreams 合并为一个 PDF MemoryStreams 的正确方法时遇到了很多麻烦,该 PDF MemoryStreams 包含来自两个源 PDF MemoryStreams 的所有页面。看起来很简单,我认为下面的代码设置正确,但生成的 PDF 内存流只包含第一个文件。第二个 PDF 文件永远不会出现,也永远不会连接到第一个。

我在 Internet 上发现了多种“正确”的合并方式。 iText 7 的实际示例代码似乎异常复杂(即重复地将多个概念混合到一个示例中 - 因为不会将概念简化为最简单的代码),并且似乎无法演示简单的概念。例如,他们的 PDFMerge 文档在文档中根本没有示例代码(我在类文档中也没有其他任何内容)。他们在线提供的示例实际上总是将文件(而不是 MemoryStreams)与其他概念(例如添加页码或添加目录)混合在一起。所以他们从不只展示一个概念,他们从不从文件以外的任何东西开始。我的 PDF 来自数据库,我们只需要将它们合并到一个 PDF 内存流中并将其保存回来。我担心的是,当我初始化 PDFWriter 时,我可能没有正确创建 MemoryStream。由于他们的样本除了初始文件之外没有做任何事情,我无法确认这是否正确完成。我还完全限定了代码中的所有对象,因为我想在升级到新的 iText 7 时保留旧的 iTextSharp 代码。这样做是为了确保不会无意中使用同名的 iTextSharp 对象.

此外,为了使源代码尽可能易于阅读,我删除了一些正在使用的对象的声明和初始化。当您跟踪代码时,所有内容都被跟踪,并且所有值都完全加载了适当的值。唯一的问题是第二个 PDFMerge 似乎没有做任何事情。我假设问题是我没有正确准备 PDF 对象,或者在使用 PDFMerge 对象写出第二个 PDF 之前,我必须对目标 PDF 文档 (p_pdfDocument) 上的 PDFWriter 执行一些特殊操作。

Dim p_bResult As Boolean = False

Dim p_bArray As Byte() = Nothing

Dim p_memStream As New System.IO.MemoryStream
Dim p_pdfWriter As New iText.Kernel.Pdf.PdfWriter(p_memStream)
Dim p_pdfDocument As New iText.Kernel.Pdf.PdfDocument(p_pdfWriter)

Dim p_pdf1Stream As New System.IO.MemoryStream(CType(p_cImage1.ImageFile, Byte()))
Dim p_pdf2Stream As New System.IO.MemoryStream(CType(p_cImage2.ImageFile, Byte()))

Dim p_pdf1Reader As New iText.Kernel.Pdf.PdfReader(p_pdf1Stream)
Dim p_pdf2Reader As New iText.Kernel.Pdf.PdfReader(p_pdf2Stream)

Dim p_pdf1Document As New iText.Kernel.Pdf.PdfDocument(p_pdf1Reader)
Dim p_pdf2Document As New iText.Kernel.Pdf.PdfDocument(p_pdf2Reader)

Dim p_pdfMerger As New iText.Kernel.Utils.PdfMerger(p_pdfDocument)


  p_pdfMerger.Merge(p_pdf1Document, 1, p_pdf1Document.GetNumberOfPages())
  p_pdfMerger.Merge(p_pdf2Document, 1, p_pdf2Document.GetNumberOfPages())


  'Problem is here... the array only has the first PDF in it
  'The second p_pdfMerger.Merge didn't seem to do anything

  p_bArray = p_memStream.ToArray

  p_pdf1Document.Close()
  p_pdf2Document.Close()

  p_pdfDocument.Close()

我希望 2 个源 PDF MemoryStreams 出现在目标 MemoryStream 中,但它只包含第一个 PDF。

编辑:

我把结尾改成...

p_pdfMerger.Merge(p_pdf1Document, 1, p_pdf1Document.GetNumberOfPages()) 
p_pdfMerger.Merge(p_pdf2Document, 1, p_pdf2Document.GetNumberOfPages()) 
p_cImage1.PageCount = p_pdfDocument.GetNumberOfPages() 
p_pdfDocument.Close() 
p_bArray = p_memStream.ToArray 
p_pdf1Document.Close() 
p_pdf2Document.Close()

问题是p_pdfDocument.GetNumberOfPages() 是正确的,但是当保存到数据库并查看时,字节仍然只是第一个 PDF 文档。

【问题讨论】:

  • 就像旧的 itext 变体一样:在关闭写入它的文档之前永远不要检索内存流的内容!
  • 如您所见,cmets 不适合发布单行代码以外的代码。你应该edit这样的附加信息进入你的问题,下面有一个链接。
  • 感谢您为我指明正确使用此处工具的正确方向。第一次发布问题,所以不确定协议。另外,我注意到您已经为我编辑了它。非常感谢和关注!

标签: vb.net pdf merge itext7


【解决方案1】:

我测试了您的用例,稍微压缩了您的代码,从文件中读取输入内存流,并将输出内存流写入文件,因为我没有您的数据库环境:

Using MemoryStream As New MemoryStream,
      Pdf1MemoryStream As New MemoryStream(File.ReadAllBytes(MY_FIRST_PDF_FILE)),
      Pdf2MemoryStream As New MemoryStream(File.ReadAllBytes(MY_SECOND_PDF_FILE))

    Using PdfDocument As New PdfDocument(New PdfWriter(MemoryStream)),
          Pdf1 As New PdfDocument(New PdfReader(Pdf1MemoryStream)),
          Pdf2 As New PdfDocument(New PdfReader(Pdf2MemoryStream))
        Dim Merger As New PdfMerger(PdfDocument)
        Merger.Merge(Pdf1, 1, Pdf1.GetNumberOfPages)
        Merger.Merge(Pdf2, 1, Pdf2.GetNumberOfPages)
    End Using

    Dim PdfBytes As Byte() = MemoryStream.ToArray()

    Using FileStream As Stream = File.Create("TwoPdfsMergedInMemoryStream.pdf")
        FileStream.Write(PdfBytes, 0, PdfBytes.Length)
    End Using

End Using

结果我得到了TwoPdfsMergedInMemoryStream.pdf 中两个源文件的内容。关于你的观察

问题是p_pdfDocument.GetNumberOfPages() 是正确的,但是当保存到数据库并查看时,字节仍然只是第一个 PDF 文档。

因此,我假设p_bArray 确实包含一个包含两个源 PDF 内容的 PDF,但是 保存到数据库 中存在问题em>正在查看

要对此进行测试,您可以将字节数组的内容保存到文件中,就像我在上面所做的那样;然后你可以检查数组中的真正内容。

【讨论】:

  • 我确认这是一个保存问题。实际上,在更新。感谢你的帮助。非常感激。答案就在我面前,只是假设我在转换到 iText7 时做错了,而不是明显的答案。有时你需要另一双眼睛来看待某事。再次感谢!
  • 太棒了!那么您可能想将我的答案标记为已接受的答案?只需单击投票箭头下方左上角的勾号即可。
猜你喜欢
  • 2020-10-19
  • 2022-01-12
  • 2019-11-17
  • 2017-03-28
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
相关资源
最近更新 更多