2011-04-28 70 views
7

我正在写一个Java程序,打印宾果卡的PDF文件。每页是一张卡。为了让我更容易,我创建了一个带有acrofields的模板PDF文件,这样程序只需要创建一个该模板的副本,用数字填充ac场,然后将其平坦化。截至目前,我可以创建1宾果卡。我想在一个PDF文件中有多个页面(因此,多张卡片)。但我不知道如何做到这一点。我读到的是一个PDFStamper关联到一个且只有一个PDFReader对象。有没有一种方法,我可以做到这一点,而不诉诸创建多个PDF文件并将它们合并为一个(我最后一次这样做,我发现真的很慢)先谢谢了!Itext - 如何使用acrofields克隆页面?

回答

13

花了我一会儿才弄明白这一点。这不是最有效的方法的代码,但这里的本质是什么呢:

  • 创建文档
  • 为每个页面(S)与acrofield:
  • 复制模板
  • 填写表格
  • 扁平化的形式
  • 添加页面

这里是我的实现你可以尝试和修改,以适应您的需求:

private void createPdf() throws Exception { 
    Document doc = new Document(); 
    PdfSmartCopy copy = new PdfSmartCopy(doc, new FileOutputStream("result.pdf")); 
    doc.open(); 

    PdfReader reader; 
    PdfStamper stamper; 
    AcroFields form; 
    ByteArrayOutputStream baos; 

    for(int i = 0; i < getTotalPages(); i++) { 
     copyPdf(i); 

     reader = new PdfReader(String.format("%d%s", i, "template.pdf")); 
     baos = new ByteArrayOutputStream(); 
     stamper = new PdfStamper(reader, baos); 
     form = stamper.getAcroFields(); 
     //methods to fill forms 

     stamper.setFormFlattening(true); 
     stamper.close(); 

     reader = new PdfReader(baos.toByteArray()); 
     copy.addPage(copy.getImportedPage(reader, 1)); 
    } 

    doc.close(); 
} 

private void copyPdf(int currentPage) throws Exception { 
    PdfReader reader = new PdfReader("timesheet.pdf"); 
    Document doc = new Document(); 
    File file = new File(String.format("%d%s", currentPage, "template.pdf")); 
    file.deleteOnExit(); 
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(file)); 
    stamper.close(); 
} 

的copyPdf()方法创建用来允许填写表格,而不会影响整个文档的临时文件。如果你找到一个更有效的方法来做到这一点,让我知道。

此外,我发现在基于Intel的Mac和Windows计算机上,Mac可以更快地完成此操作。

如果您不反对获取iText参考书,我会推荐Bruno Lowagie的“iText in Action,第二版”。这是一本很棒的书,非常有帮助。

+0

+1书建议 – oers 2011-04-28 12:08:49

+0

+1正是我所需要的!谢谢!只需注意,copyPdf中的'doc'不会被使用:) – Jairo 2011-04-28 16:51:18

+3

您根本不需要'copyPdf()'。即使你这样做了,从A到B复制一个文件(这恰好是PDF)的方式是非常低效的方式。你甚至可以为'PdfStamper'的所有不同实例使用相同的'PdfReader',但这很可能会揭示Bug。你会*在相同的文件上使用多个阅读器当然会很好。 – 2011-04-28 19:17:40

1

所以,这里的代码,而无需使用扎克的“copyPdf”的方法,如马克斯托勒和MaxArt建议:

private void createPdf() throws Exception { 
    Document doc = new Document(); 
    PdfSmartCopy copy = new PdfSmartCopy(doc, new FileOutputStream("result.pdf")); 
    doc.open(); 

    PdfReader mainReader = new PdfReader("timesheet.pdf"); 

    PdfReader reader; 
    PdfStamper stamper; 
    AcroFields form; 
    ByteArrayOutputStream baos; 

    for(int i = 0; i < getTotalPages(); i++) { 

     reader = new PdfReader(mainReader); 
     baos = new ByteArrayOutputStream(); 
     stamper = new PdfStamper(reader, baos); 
     AcroFields form = stamper.getAcroFields(); 

     //methods to fill forms 

     stamper.setFormFlattening(true); 
     stamper.close(); 

     reader = new PdfReader(baos.toByteArray()); 
     copy.addPage(copy.getImportedPage(reader, 1)); 
    } 

    doc.close(); 
}