【发布时间】: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这样的附加信息进入你的问题,下面有一个链接。
-
感谢您为我指明正确使用此处工具的正确方向。第一次发布问题,所以不确定协议。另外,我注意到您已经为我编辑了它。非常感谢和关注!