我们在现有的webapp中用iText 5.4.1取代Adobe LiveCycle Server,将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_ ...)'修改我的PdfStamper .

无论生成多少次保存,Adobe LiveCycle Server生成的投资组合都不会丢失数据 .