使用iText从多个模板创建单个PDF文件

时间:2013-08-05 18:03:19

标签: java spring pdf pdf-generation itext

我有以下代码可以打开PDF模板,用Receipt对象中的数据填充AcroFields并输出到浏览器。它与我的收据的一个实例完美配合,但现在我用一个收据清单重复这个过程,这样我就可以生成一个连接pdf压模实例的PDF文件。

这是我现在的代码:

response.setContentType("application/pdf");

PdfReader pdfTemplate = new PdfReader ("/receipt-template.pdf");
PdfStamper stamper = new PdfStamper(pdfTemplate, response.getOutputStream());
stamper.setFormFlattening(true);
AcroFields form = stamper.getAcroFields();

// fill the fields as
form.setField("number", recipt.getNumber().toString());

// ...
stamper.close();
pdfTemplate.close();

我想做点什么:

pdf = new pdf
foreach receipt in receiptsList
    partial = fillReceiptTemplate (receipt)
    pdf.append (partial)
output pdf

有可能吗?我在一些论坛中读过我应该使用PdfCopyPdfSmartCopy,但我不知道如何在其他地方说不可能连接整个pdf文档,所以我应该添加页面而不是...

1 个答案:

答案 0 :(得分:2)

让我总结文档中有关您的问题的内容:

  1. 如果最终文档需要互动,则表示您遇到问题。如果您阅读ISO-32000-1,您会发现PDF文档只能包含一个表单。单个字段可以与多个窗口小部件注释相对应,但它只能具有一个值。例如:如果您的表单包含字段 name ,并且您多次连接同一表单(使用PdfCopyFields),那么包含与该字段对应的窗口小部件注释的所有页面 name 将显示相同的名称。您不能拥有 name 字段显示 Bruno 的一个页面和 name 字段显示 Joaquin 的另一个字段。我的书chapter 6的第6.4.3节对此进行了解释,其中示例ConcatenateForms1为同一字段生成多个小部件,ConcatenateForms2在连接表单之前重命名字段。
  2. 在你的情况下,你没有那个问题。您使用行stamper.setFormFlattening(true);展平表单,您可以将结果连接起来,如本书chapter 6的第6.4.2节所示,其中DataSheets1使用PdfCopy导致巨大的文件大小,DataSheets2使用PdfSmartCopy会生成尺寸更合适的PDF格式。
  3. “最终结果需要保持形式”与“最终结果可以展平”之间的差异可以解释为什么你在不同的论坛上获得混合信息。

    请注意,DataSheets示例不会将单个文件存储在磁盘上。而是使用ByteArrayOutputStream将字节保存在内存中,toByteArray()用于构造PdfReader实例。