IText合并文件与acrofields

我目前有一个PdfReader和一个PdfStamper,我正在用acrofields填写。 我现在必须复制另一个pdf到我已经填写的表格的末尾,当我这样做的时候,我将复制的新表格丢失了。 这是代码。

public static void addSectionThirteenPdf(PdfStamper stamper, Rectangle pageSize, int pageIndex){ PdfReader reader = new PdfReader(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/documents/Section13.pdf")); AcroFields fields = reader.getAcroFields(); fields.renameField("SecurityGuidancePage3", "SecurityGuidancePage" + pageIndex); stamper.insertPage(pageIndex, pageSize); stamper.replacePage(reader, 1, pageIndex); } 

我创build原始文档的方式就是这样。

  OutputStream output = FacesContext.getCurrentInstance().getExternalContext().getResponseOutputStream(); PdfReader pdfTemplate = new PdfReader(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/documents/dd254.pdf")); PdfStamper stamper = new PdfStamper(pdfTemplate, output); stamper.setFormFlattening(true); AcroFields fields = stamper.getAcroFields(); 

有没有办法使用第一段代码合并两个acrofields在一起?

根据你的要求,不同的情况是可能的,但无论如何:你做错了。 您应该使用PdfCopyPdfSmartCopy合并文档。

下面的video教程介绍了不同的场景。

你可以在iText沙箱中find大部分的例子。

合并不同的forms(有不同的领域)

如果你想合并不同的表单而不PdfCopy它们,你应该像在MergeForms例子中那样使用PdfCopy

 public void createPdf(String filename, PdfReader[] readers) throws IOException, DocumentException { Document document = new Document(); PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename)); copy.setMergeFields(); document.open(); for (PdfReader reader : readers) { copy.addDocument(reader); } document.close(); for (PdfReader reader : readers) { reader.close(); } } 

在这种情况下, readers是包含不同forms(具有不同字段名称)的PdfReader实例的数组,因此我们使用PdfCopy并且确保我们不会忘记使用setMergeFields()方法,否则字段将不会复制。

合并相同的forms(具有相同的字段)

在这种情况下,我们需要重命名这些字段,因为我们可能在不同的页面上需要不同的值。 在PDF中,一个字段只能有一个值。 如果合并相同的表单,则可以对同一个字段进行多个可视化,但每个可视化都将显示相同的值 (因为实际上只有一个字段)。

我们来看看MergeForms2的例子:

 public void manipulatePdf(String src, String dest) throws IOException, DocumentException { Document document = new Document(); PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest)); copy.setMergeFields(); document.open(); List<PdfReader> readers = new ArrayList<PdfReader>(); for (int i = 0; i < 3; ) { PdfReader reader = new PdfReader(renameFields(src, ++i)); readers.add(reader); copy.addDocument(reader); } document.close(); for (PdfReader reader : readers) { reader.close(); } } public byte[] renameFields(String src, int i) throws IOException, DocumentException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(src); PdfStamper stamper = new PdfStamper(reader, baos); AcroFields form = stamper.getAcroFields(); Set<String> keys = new HashSet<String>(form.getFields().keySet()); for (String key : keys) { form.renameField(key, String.format("%s_%d", key, i)); } stamper.close(); reader.close(); return baos.toByteArray(); } 

正如你所看到的, renameFields()方法在内存中创build一个新文档。 该文档使用PdfSmartCopy与其他文档合并。 如果你在这里使用PdfCopy ,你的文档将会变得臃肿(我们很快就会发现)。

合并扁平forms

在FillFlattenMerge1中 ,我们使用PdfStamper填写表单。 结果是保存在内存中的PDF文件,并使用PdfCopy合并。 虽然这个例子是好的,如果你要合并不同的forms,这实际上是一个例子, 如何不这样做 (如video教程中所述 )。

FillFlattenMerge2显示如何合并正确填写和展平的相同表单:

 public void manipulatePdf(String src, String dest) throws DocumentException, IOException { Document document = new Document(); PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest)); document.open(); ByteArrayOutputStream baos; PdfReader reader; PdfStamper stamper; AcroFields fields; StringTokenizer tokenizer; BufferedReader br = new BufferedReader(new FileReader(DATA)); String line = br.readLine(); while ((line = br.readLine()) != null) { // create a PDF in memory baos = new ByteArrayOutputStream(); reader = new PdfReader(SRC); stamper = new PdfStamper(reader, baos); fields = stamper.getAcroFields(); tokenizer = new StringTokenizer(line, ";"); fields.setField("name", tokenizer.nextToken()); fields.setField("abbr", tokenizer.nextToken()); fields.setField("capital", tokenizer.nextToken()); fields.setField("city", tokenizer.nextToken()); fields.setField("population", tokenizer.nextToken()); fields.setField("surface", tokenizer.nextToken()); fields.setField("timezone1", tokenizer.nextToken()); fields.setField("timezone2", tokenizer.nextToken()); fields.setField("dst", tokenizer.nextToken()); stamper.setFormFlattening(true); stamper.close(); reader.close(); // add the PDF to PdfCopy reader = new PdfReader(baos.toByteArray()); copy.addDocument(reader); reader.close(); } br.close(); document.close(); } 

这是三种情况。 你的问题对于任何人来说都是不清楚的,除非你决定哪种scheme最适合你的需求。 我build议你在编码之前花时间学习。 观看video,尝试一下例子,如果你还有疑问,你可以发布一个更明智的问题。