我有以下代码,可以打开 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
这可能吗?我在一些论坛上读到我应该使用 PdfCopy
或 PdfSmartCopy
但我不知道如何,在其他地方说不可能连接整个 pdf 文档,所以我应该添加页面..
最佳答案
让我总结一下文档中关于您的问题的内容:
- 如果最终文档需要交互式,那么就会遇到问题。如果您阅读过 ISO-32000-1,您会发现 PDF 文档只能包含一种表单。单个字段可以对应多个小部件注释,但只能有一个值。例如:如果您有一个带有字段 name 的表单,并且您多次连接同一表单(使用
PdfCopyFields
),则所有包含对应小部件注释的页面与字段 name 将显示相同的名称。您不能在一个页面中 name 字段显示 Bruno,而在另一个页面中 name 字段显示 Joaquin 。 chapter 6 的第 6.4.3 节对此进行了解释我的书,其中示例 ConcatenateForms1导致同一字段有多个小部件,并且 ConcatenateForms2在连接表单之前重命名字段。 - 就您而言,您不存在这个问题。您可以使用
stamper.setFormFlattening(true);
行展平表单,您可以连接结果,如 chapter 6 的第 6.4.2 节所示。我的书,其中 DataSheets1使用PdfCopy
导致文件大小巨大,并且 DataSheets2使用PdfSmartCopy
生成尺寸更可接受的 PDF。
“最终结果需要保持形式”和“最终结果可以扁平化”之间的差异可以解释为什么您在不同论坛上获得混合信息。
请注意,DataSheets
示例不会将单个文件存储在磁盘上。相反,使用 ByteArrayOutputStream
将字节保存在内存中,其中 toByteArray()
用于构造 PdfReader
实例。
关于java - 使用 iText 从多个模板创建单个 PDF 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18064690/