我们正在现有 web 应用程序中将 Adobe LiveCycle Server 替换为 iText 5.4.1,以将 XML 数据与 LiveCycle Designer 生成的 PDF 模板合并,从数百个模板生成可编辑的 PDF 文件。
此代码将数据与模板结合,返回一个 PDF 字节数组:
// Import data into the PDF form
if (pdfTemplateFileName != null && inputXmlDataFile != null) {
// set up the objects
template = new PdfReader(pdfTemplateFileName);
filledPDF = new ByteArrayOutputStream();
stamper = new PdfStamper(template, filledPDF);
AcroFields form = stamper.getAcroFields();
// fill in the form with the data
XfaForm xfa = form.getXfa();
xfa.fillXfaForm(inputXmlDataFile);
//closing the stamper is necessary to flush to filledPDF
stamper.close();
returnPDF = filledPDF.toByteArray();
}
此代码将 PDF 字节数组组合成一个投资组合:
List<byte[]> assemblingPdfList = assemblingPdfMap.get("newStyleForms");
// create PDF portfolio of editable documents
com.itextpdf.text.Document document = new com.itextpdf.text.Document();
ByteArrayOutputStream mergedPDFOutput = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, mergedPDFOutput);
document.open();
Paragraph coverSheet = new Paragraph("Multiple files are bound together in this PDF Package");
coverSheet.setAlignment(com.itextpdf.text.Element.ALIGN_CENTER);
document.add(coverSheet);
// define the collection
PdfCollection collection = new PdfCollection(PdfCollection.DETAILS);
PdfCollectionSchema schema = new PdfCollectionSchema();
PdfCollectionField filename = new PdfCollectionField("Name", PdfCollectionField.FILENAME);
filename.setOrder(0);
schema.addField("FILENAME", filename);
PdfCollectionField description = new PdfCollectionField("Description", PdfCollectionField.TEXT);
description.setOrder(1);
schema.addField("DESCRIPTION", description);
PdfCollectionField modified = new PdfCollectionField("Modified", PdfCollectionField.MODDATE);
modified.setOrder(2);
schema.addField("MODIFIED", modified);
PdfCollectionField size = new PdfCollectionField("Size", PdfCollectionField.SIZE);
size.setOrder(3);
schema.addField("SIZE", size);
collection.setSchema(schema);
writer.setCollection(collection);
// loop through the PDF documents and add each to the portfolio
PdfFileSpecification fs;
PdfCollectionItem item;
int iNum = 0;
for (byte[] pdf : assemblingPdfList) {
fs = PdfFileSpecification.fileEmbedded(writer, null,
String.format("StylesResult_%s.pdf", iNum++), pdf);
fs.addDescription("Styles Result File", false);
item = new PdfCollectionItem(schema);
item.addItem("DESCRIPTION", "Styles Result File");
item.addItem("MODIFIED", new PdfDate() );
fs.addCollectionItem(item);
writer.addFileAttachment(fs);
}
// close document
document.close();
mergedPDFOutput.flush();
mergedPDFOutput.close();
return mergedPDFOutput.toByteArray();
起初,iText 不会填充表单字段。我们使用 LiveCycle Designer 将大多数字段的数据绑定从 Normal 更改为 Global,这使得 iText 能够正确填充大部分字段。例外是重复的(想想“表”)数据行。将绑定设置为“全局”会导致第一个数据值在每个数据记录的列中重复。将重复字段的绑定设置回“正常”似乎有效。
iText 合并的可编辑 PDF 组合在 Internet Explorer 10 中启动。如果我们单击“打开文件”以在 Adobe Acrobat XI Pro 中打开单个 PDF,则所有数据都在那里。但是,如果我们在 Acrobat Pro 中单击“文件”/“另存为”以保存到新的 PDF 文件,然后打开新文件,部分或全部表单数据已经消失(在一种情况下,“第一代”保存大部分数据完好无损,但重复的子表单数据被擦除。再次保存,创建“第二代”保存,擦除所有数据。)
我失败的解决方案尝试包括:(a)在“追加”模式下初始化 PdfStamper;(b) 使用 'stamper.setEncryption(false, "", "", PdfWriter.ALLOW_{everything}...)' 修改我的 PdfStamper。
无论保存多少代,Adobe LiveCycle Server 生成的投资组合都不会丢失数据。