简体   繁体   中英

How to create multiple copies documents with iText

I'm using iText to generate a PDF document that consists of several copies of almost the same information.

Eg: An invoice. One copy is given to the customer, another is filed and a third one is given to an accountant for book-keeping.

All the copies must be exactly the same except for a little piece of text that indicates who is the copy to ( Customer , Accounting , File , ...).

There are two possible scenarios (I don't know if the solution is the same for both of them):

a) Each copy goes in a different page .

b) All the copies goes in the same page (the paper will have cutting holes to separete copies).

There will be a wrapper or helper class which uses iText to generate the PDF in order to be able to do something like var pdf = HelperClass.CreateDocument(DocuemntInfo info); . The multiple-copies problem will be solved inside this wrapper/helper.

What does iText provides to accomplish this? Do I need to write each element in the document several times in different positions/pages? Or does iText provide some way to write one copy to the document and then copy it to other position/page?


Note: It's a .Net project, but I tagged the question with both java and c# because this qustion is about how to use iText properly the answer will help both laguage developers.

If each copy goes on a different page , you can create a new document and copy in the page multiple times. Using iText in Java you can do it like this:

// Create output PDF
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
PdfContentByte cb = writer.getDirectContent();

// Load existing PDF
PdfReader reader = new PdfReader(templateInputStream);
PdfImportedPage page = writer.getImportedPage(reader, 1); 

// Copy first page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);
// Add your first piece of text here
document.add(new Paragraph("Customer")); 

// Copy second page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);
// Add your second piece of text here
document.add(new Paragraph("Accounting")); 

// etc...

document.close();

If you want to put all the copies on the same page , the code is similar but instead of using zeroes in addTemplate(page, 0, 0) you'll need to set values for the correct position; the numbers to use depend on the size and shape of your invoice.

See also iText - add content to existing PDF file — the above code is based on the code I wrote in that answer.

Here's how I see this working.

PdfReader reader = new PdfReader( templatePDFPath );
Document doc = new Document();
PdfWriter writer = PdfWriter.createInstance( doc, new FileOutputStream("blah.pdf" ) );

PdfImportedPage inputPage = writer.getImportedPage( reader, 1 );

PdfDirectContent curPageContent = writer.getDirectContent();

String extraStuff[] = getExtraStuff();

for (String stuff : extraStuff) {
  curPageContent.saveState();
  curPageContent.addTemplate( inputPage /*, x, y*/ );
  curPageContent.restoreState();

  curPageContent.beginText();
  curPageContent.setTextMatrix(x, y);
  curPageContent.setFontAndSize( someFont, someSize );

  // the actual work:
  curPageContent.showText( stuff );

  curPageContent.EndText();       

  // save the contents of curPageContent out to the file and reset it for the next page.
  doc.newPage();
}

That's the bare minimum of work on the computer's part. Quite Efficient, and it'll result in a smaller PDF. Rather than having N copies of that page, with tweaks, you have one copy of that page that's reused on N pages, with little tweaks on top.

You could do the same thing, and use the "x,y" parameters in addTemplate to draw them all on the same page. Up to you.

PS: you'll need to figure out the coordinates for setTextMatrix in advance.

You could also use PDfCopy Or PDfSmartCopy to do this.

PdfReader reader = new PdfReader("Path\To\File");
Document doc = new Document();           
PdfCopy copier = new PdfCopy(doc, ms1);
//PdfSmartCopy copier = new PdfSmartCopy(doc, ms1);
doc.Open();
copier.CloseStream = false;    

PdfImportedPage inputPage = writer.GetImportedPage(reader, 1);
PdfContentByte curPageContent = writer.DirectContent;            

for (int i = 0; i < count; i++)
{           
    copier.AddPage(inputPage);          
}
doc.Close();                        
ms1.Flush();
ms1.Position = 0;

The difference between PdfCopy and PdfSmartCopy is that PdfCopy copies the entire PDF for each page, while PdfSmartCopy outputs a PDF that internally contains only one copy and all pages reference it, resulting in a smaller file and less bandwidth on a network, however it uses more memory on the server and takes longer to process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM