当前位置: 首页 > 知识库问答 >
问题:

iText7合并2个PDF内存流不工作

东方骏
2023-03-14

我正在将一些旧的iTextSharp代码升级到新的iText 7库。我很难确定将2个PDF MemoryStream合并为一个PDF MemoryStream的正确方法,该PDF MemoryStream包含来自两个源PDF MemoryStream的所有页面。这看起来很简单,我认为下面的代码设置正确,但生成的PDF内存流只包含第一个文件。第二个PDF文件从未出现,也从未连接到第一个PDF文件。

我在互联网上找到了多种方法作为合并的“正确”方式。iText 7的实际示例代码似乎html" target="_blank">异常复杂(即反复将多个概念混合到一个示例中,因为在中没有将概念简化为尽可能简单的代码),并且似乎无法演示简单的概念。例如,他们的PDFMerge文档中根本没有示例代码(我在类文档中也没有看到任何其他内容)。他们在网上的例子实际上总是将文件合并(而不是MemoryStream)与其他概念混合在一起,比如添加页码或添加目录。所以他们从不只是展示一个概念,也从不从文件以外的任何东西开始。我的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 MemoryStream出现在目标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文档。

共有1个答案

彭展
2023-03-14

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

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

结果,我在twopdfmergedinmemoryStream中获得了两个源文件的内容。pdf原样。关于你的观察

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

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

为了测试这一点,你可以像我上面那样将字节数组的内容保存到一个文件中;然后你可以检查数组中到底有什么。

 类似资料:
  • 我试图从多个内存流生成一个PDF文件,但在确定将2个PDF MemoryStream合并为一个PDF MemoryStream的正确方法时遇到了很多困难,该PDF MemoryStream包含来自两个源PDF MemoryStream的所有页面。这看起来很简单,我认为下面的代码设置正确,但生成的PDF内存流并不包含这两个文件的组合。 我很难确定将2个PDF MemoryStream合并为一个PDF

  • 我必须将多个1页pdf合并为一个pdf。我使用iTextSHarp 5.5.5.0来实现这一点,但当我合并超过900-1000个pdf时,会出现内存不足异常。我注意到,即使我释放并关闭阅读器,内存也不会得到正确的清理(进程使用的内存量永远不会减少),所以我想知道我可能做错了什么。这是我的代码: 它从来没有开始写文件,我在p.Copy()过程中得到一个内存不足的异常。AddPage()部分。我甚至尝

  • 我有几份产品数据表。每个文件都是一个单独的文件。我想做的是使用iText根据Web表单的答案生成一组摘要/建议的操作,然后将所有相关的数据表附加到这些操作中。这样,我只需要在浏览器中打开一个新选项卡来打印所有信息,而不是为摘要打开一个选项卡,为所需的每个数据表打开一个选项卡。 那么,使用iText可以做到这一点吗?

  • 我有一本书的多份副本。不同用户评论的pdf文档。我想把所有这些评论合并成一个新的pdf“合并”。 我在一个名为“路径”和“目录”属性的文档类中编写了这个子类。 这段代码导致了一个我无法解决的异常。 iText。内核PDFEException:“Pdf间接对象属于其他Pdf文档。将对象复制到当前pdf文档。' 要执行此任务,我需要更改什么?还是我完全摆脱了我的代码块?

  • 我想将至少2个PDF文件合并为一个,同时保留原始PDF中的所有表单元素。表单元素包括文本字段、单选按钮、复选框、下拉菜单等。请查看此示例PDF文件的表单: 你能做到吗? 编辑:至于实现,我更希望在linux平台上使用开源工具(如'ghostscript'或任何其他您认为适合解决此任务的工具)的命令行解决方案。 当然,欢迎每个人提供解决这个问题的任何工作解决方案,包括一个编码解决方案,它涉及编写一个

  • 我试图通过文件上传合并来自JSP页面的两个PDF文档。我正在获取文件,将它们放入列表中,但当我试图读取它们以进行合并时,我收到了一条“流已关闭”的消息。我搜索了很多关于这个例外的回复,但没有一个有帮助。所以,再说一遍,不确定它在哪里失败。 以下是Java代码: 我在线路上遇到了一个例外: 例外情况: 确切的问题是什么?正在关闭的inputStream在哪里? ===================