当前位置: 首页 > 面试题库 >

iText将文档与Acrofields合并

孔阎宝
2023-03-14
问题内容

我目前有一个PdfReader和一个PdfStamper,我正在用它们填充acrofields。现在,我必须将另一张pdf复制到我一直填写的表格的末尾,当我这样做时,我会在新表格上丢失acrofield。这是代码。

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);
}

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

     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();

有没有一种方法可以使用第一段代码合并并将两个acrofield合并在一起?


问题答案:

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

下面的视频教程介绍了不同的情况。

您可以在iText沙箱中找到大多数示例。

合并不同的表单(具有不同的字段)

如果要合并 不同的
表单而不使其变平,则应PdfCopy按照MergeForms示例中的操作使用:

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是一个PdfReader包含 不同
形式(具有不同字段名称)的实例数组,因此我们使用PdfCopy并确保不会忘记使用该setMergeFields()方法,否则将不会复制字段。

合并相同的表单(具有相同的字段)

在这种情况下,我们需要重命名字段,因为我们可能希望在不同页面上使用不同的值。在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()方法在内存中创建一个新文档。该文档将使用与其他文档合并PdfSmartCopy。如果您在PdfCopy这里使用,您的文档将会be肿(我们很快就会发现)。

合并拼合形式

在FillFlattenMerge1中,我们使用填写表格PdfStamper。结果是一个PDF文件,该文件保留在内存中,并使用合并PdfCopy。如果您要合并其他表单,虽然此示例很好,但这实际上是有关
如何不进行 合并的示例(如视频教程中所述)。

该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();
}

这是三种情况。对于任何人来说,您的问题都不清楚,但是您可以决定哪种方案最适合您的需求。我建议您在编码之前花点时间学习。观看视频,尝试示例,如果仍然有疑问,可以提出更聪明的问题。



 类似资料:
  • 我有一个PDF文档,有一些填写字段(文本和复选框)。如何引用这些对象,以便我可以操作它的值,然后将更新的PDF推送到用户那里,他们可以将它保存到他们想要的位置。我没有找到关于如何做到这一点的任何好的文档。 现在我正在使用下面的代码,但是当我打开它时,我的PDF阅读器告诉我它已经损坏或损坏了。

  • 我正在尝试将多个pdf页面合并为一个pdf页面。有很多iText的例子展示了如何将pdf页面合并到一个文件中,但是我需要所有的页面都放在一个页面中(一路上缩小它们的宽度和高度) 编辑:尝试从这里这个代码,但它只是合并成一个文件的pdf页面,我需要他们收缩成一个单一的页面

  • 我需要使用set()和{mer: true}将文档推送到我的Firebase FiRecovery数据库。我不能使用update(),因为我不能保证文档事先存在。 如果我使用角度 我尝试在Python中做同样的事情: 但我得到了一个错误: ValueError("无效的合并路径:{}". form(merge_path))ValueError:无效的合并路径: FieldPath('合并') 删除

  • 问题内容: 使用iText合并不同宽度的文档时出现问题。 下面是我用来合并的代码。 pdf的首页宽度为14英寸,高度为13英寸。文档上的所有其他页面将始终小于该页面。 我想将所有文档全部合并到一个文档中。 我不知道如何设置单个合并文档的宽度和高度。 我认为应该这样做,但是如果将其更改为,文档无效将不起作用。 请进一步指导我。 问题答案: 使用类合并文档违反了 官方 文档中的所有建议,尽管有一些 非

  • 假设在$facet阶段之后,我得到了一个包含两个数组的结果:roomInfo和hotelInfo。 看起来是这样的: 预期结果 我想要这样的输出: 基本上,在匹配roomInfo的ID后,将roomInfo中的预订属性添加到hotelInfo的roomDetails字段中。 如何实现这些用例? 谢谢

  • 我被android firstore文档和子集合弄糊涂了。 此示例将生成以下数据结构: 代码如下: 子集合和文档节点交替显示:a、c与b、d。 但是如何在没有d节点的情况下实现类似的数据结构(如下所示): 自。add方法仅适用于document而不适用于collection,我们不能只删除d(document),因为c(collection)没有add方法。 我应该如何修改我的代码?