1

Simple question , how to merge two PdfDocument objects using itext7 .net Library ?

this is how am trying but it's not working

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

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

also this code throw same exception

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

Cannot copy indirect object from the document that is being written

tried also to write the nested pdf to the disk ---> read --> another exception

any ideas !!

Mohamed
  • 342
  • 1
  • 2
  • 11
  • The error message tells you that you cannot copy pages from a document that is in the process of being written. Thus, you have to finish that `InitialPdfDoc` and load it again. If you don't want it to be written to file, simply use a memory stream. Thus, you should concentrate on solving "read --> another exception". – mkl Dec 15 '18 at 08:06
  • "use a memory stream" this is exactly what I am doing, the parameters multipdfcontent, memStreamOfAddressAndBarcode are memory stream objects – Mohamed Dec 15 '18 at 10:32
  • Thus, you have to finish that `InitialPdfDoc` and load it again. – mkl Dec 15 '18 at 11:26
  • Finish? You mean write it to the disk an reload it? – Mohamed Dec 16 '18 at 00:47
  • If you don't want it to be written to file, simply use a memory stream. You can reload it from there, too. – mkl Dec 16 '18 at 11:45
  • I don't want it to be written, what do you mean with finish the doc and load it again, any examples? – Mohamed Dec 17 '18 at 10:50
  • I created an answer illustrating what I described here in comments. – mkl Dec 17 '18 at 13:06

1 Answers1

3

First of all: Your code

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

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

does work! It does not throw any exception but instead copies nothing to the GlobalPdfDocument. Which is correct because InitialPdfDoc is freshly created and does not contain any pages yet.

But let's assume you simply did not supply enough code to reproduce the issue, let's assume your actual code adds some content to InitialPdfDoc before calling that CopyPagesTo method, e.g.

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

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

Now there indeed is the claimed exception:

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

The exception clearly states what is wrong with the code: Your document InitialPdfDoc is written to (i.e. it has an associated PdfWriter), and therefore pages cannot be copied from it.

This restriction that pages cannot be copied from documents written to is due to the iText architecture: When a document is written to, iText attempts to push this new content out into the PdfWriter output stream as soon as possible and then forget about it. This allows iText to easily produce large result PDFs without requiring a large amount of memory. The downside is the restriction you're confronted with.

Thus, the obvious solution is to finish creating the PDF to copy from, reading it into a document object without a writer, and copying from there:

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);
mkl
  • 90,588
  • 15
  • 125
  • 265