首页 > 解决方案 > 合并两个 PdfDocument 对象

问题描述

简单的问题,如何使用 itext7 .net 库合并两个 PdfDocument 对象?

这就是我正在尝试的方式,但它不起作用

PdfDocument GlobalPdfDocument = new PdfDocument(new PdfWriter(multiContentPdf));

PdfDocument InitialPdfDoc = new PdfDocument(new PdfWriter(memStreamOfAddressAndBarcode));
InitialPdfDoc.CopyPagesTo(1, InitialPdfDoc.GetNumberOfPages(), GlobalPdfDocument);

此代码也抛出相同的异常

Merger.Merge(InitialPdfDoc,1,InitialPdfDoc.GetNumberOfPages());

无法从正在写入的文档中复制间接对象

还尝试将嵌套的pdf写入磁盘--->读取->另一个异常

有任何想法吗 !!

标签: c#pdfitext7

解决方案


首先:您的代码

PdfDocument GlobalPdfDocument = new PdfDocument(new PdfWriter(multiContentPdf));

PdfDocument InitialPdfDoc = new PdfDocument(new PdfWriter(memStreamOfAddressAndBarcode));
InitialPdfDoc.CopyPagesTo(1, InitialPdfDoc.GetNumberOfPages(), GlobalPdfDocument);

确实有效!它不会抛出任何异常,而是不会将任何内容复制到GlobalPdfDocument. 这是正确的,因为InitialPdfDoc它是新创建的并且还不包含任何页面。

但是让我们假设您根本没有提供足够的代码来重现问题,让我们假设您的实际代码InitialPdfDoc在调用该CopyPagesTo方法之前添加了一些内容,例如

PdfDocument GlobalPdfDocument = new PdfDocument(new PdfWriter(multiContentPdf));

PdfDocument InitialPdfDoc = new PdfDocument(new PdfWriter(memStreamOfAddressAndBarcode));
InitialPdfDoc.AddNewPage();
InitialPdfDoc.CopyPagesTo(1, InitialPdfDoc.GetNumberOfPages(), GlobalPdfDocument);

现在确实有声称的例外:

iText.Kernel.PdfException : Cannot copy indirect object from the document that is being written.

异常清楚地说明了代码有什么问题:您的文档InitialPdfDoc被写入(即它具有关联的PdfWriter),因此无法从中复制页面。

无法从写入的文档复制页面的限制是由于 iText 架构:当写入文档时,iText 会尝试尽快将这些新内容推送到PdfWriter输出流中,然后忘记它。这允许 iText 轻松生成大型结果 PDF,而无需大量内存。缺点是您面临的限制。

因此,显而易见的解决方案是完成创建要从中复制的 PDF,将其读取到没有编写器的文档对象中,然后从那里复制:

PdfDocument GlobalPdfDocument = new PdfDocument(new PdfWriter(multiContentPdf));

PdfWriter Writer = new PdfWriter(memStreamOfAddressAndBarcode);
Writer.SetCloseStream(false);                     // Prevent the Writer from closing the MemoryStream
PdfDocument InitialPdfDoc = new PdfDocument(Writer);
InitialPdfDoc.AddNewPage();
InitialPdfDoc.Close();                            // Closing the document finishes the result PDF

memStreamOfAddressAndBarcode.Position = 0;        // Re-position the stream to the start of the PDF
InitialPdfDoc = new PdfDocument(new PdfReader(memStreamOfAddressAndBarcode)); // Create r/o document

InitialPdfDoc.CopyPagesTo(1, InitialPdfDoc.GetNumberOfPages(), GlobalPdfDocument);

推荐阅读