开发者

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.

E.g.: 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜