如何使用iText创建多个副本文档

时间:2011-03-19 22:18:03

标签: c# java itextsharp itext

我正在使用iText生成一份PDF文档,其中包含几个几乎相同信息的副本。

例如:发票。向客户提供一份副本,另一份提交,第三份提交给会计师进行簿记。

所有副本必须完全相同,除了一小段文字表明谁是副本(客户会计文件,...)。

有两种可能的情况(我不知道两种方案的解决方案是否相同):

a)每个副本都在不同的页面

b)所有副本都在相同的页面(该文件将有切割孔以分离副本)。

将有一个包装器或帮助器类使用iText生成PDF,以便能够执行var pdf = HelperClass.CreateDocument(DocuemntInfo info);之类的操作。多包拷贝问题将在这个包装器/帮助器中解决。

iText为实现这一目标提供了什么?我是否需要在不同的位置/页面中多次写入文档中的每个元素?或者iText是否提供了一种方法来将一个副本写入文档,然后将其复制到其他位置/页面?


注意:这是一个.Net项目,但是我用java和c#标记了这个问题,因为这个qustion是关于如何正确使用iText的,答案将有助于两个开发人员。

3 个答案:

答案 0 :(得分:4)

如果每个副本都在不同的页面上,您可以创建一个新文档并多次在页面中复制。在Java中使用iText可以这样做:

// 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();

如果您想将所有副本放在同一页上,代码类似,但不是在addTemplate(page, 0, 0)中使用零,而是需要为正确的位置设置值;要使用的数字取决于发票的大小和形状。

另请参阅iText - add content to existing PDF file - 上面的代码基于我在该答案中编写的代码。

答案 1 :(得分:2)

以下是我看到这一点的工作方式。

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();
}

这是计算机上最少的工作。相当高效,它将导致更小的PDF。不是通过调整获得该页面的N个副本,而是拥有该页面的一个副本,该页面在N个页面上重复使用,并且在顶部进行了一些调整。

你可以做同样的事情,并使用addTemplate中的“x,y”参数将它们全部绘制在同一页面上。由你决定。

PS:您需要提前确定setTextMatrix的坐标。

答案 2 :(得分:1)

您也可以使用PDfCopy或PDfSmartCopy来执行此操作。

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;

PdfCopy和PdfSmartCopy之间的区别在于PdfCopy复制每页的整个PDF,而PdfSmartCopy输出的PDF内部只包含一个副本,所有页面都引用它,从而导致文件更小,网络带宽更少它在服务器上占用更多内存,处理时间更长。