如何将签名形式添加到现有的 pdf(使用 iText7),以便输出文件可以作为 pdf 的输入(顺序签名)?

How to add signature form to an existing pdf (using iText7), so that the output file can be served as a input to pdf (sequential signature)?

我将 iText7 用于 pdf 签名工作流程,我遵循 i7js-signatures 提供的示例。但是我的要求是获取一个输入 pdf 文件,向其添加顺序签名,然后进一步将其传递给签名。

我试着把这个过程分成两步。

  1. 在 intermediate_output 文件中输入 pdf 并添加顺序签名面板。

    public void createForm() throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(FORM),new PdfWriter(TMP));
        //PdfDocument pdfDoc = new PdfDocument(new PdfWriter(FORM));
        pdfDoc.addNewPage();
        Document doc = new Document(pdfDoc);
        Table table = new Table(1);
        table.addCell("Signer 1: Alice");
        table.addCell(createSignatureFieldCell("sig1"));
        table.addCell("Signer 2: Bob");
        table.addCell(createSignatureFieldCell("sig2"));
        table.addCell("Signer 3: Carol");
        table.addCell(createSignatureFieldCell("sig3"));
        doc.add(table);
        doc.close();
    }
    
  2. 取 intermediate_output 文件并签名。

虽然 运行 第二步与第一步的输出,我得到 com.itextpdf.kernel.PdfException: error.reading.objstm

Exception in thread "main" com.itextpdf.kernel.PdfException: error.reading.objstm
    at com.itextpdf.kernel.pdf.PdfReader.readObjectStream(PdfReader.java:508)
    at com.itextpdf.kernel.pdf.PdfReader.readObject(PdfReader.java:1014)
    at com.itextpdf.kernel.pdf.PdfReader.readObject(PdfReader.java:533)
    at com.itextpdf.kernel.pdf.PdfIndirectReference.getRefersTo(PdfIndirectReference.java:128)
    at com.itextpdf.kernel.pdf.PdfIndirectReference.getRefersTo(PdfIndirectReference.java:132)
    at com.itextpdf.kernel.pdf.PdfArray.get(PdfArray.java:376)
    at com.itextpdf.kernel.pdf.PdfArray.get(PdfArray.java:237)

输入pdf:

中级 pdf 第 1 页:

中级 pdf 第 2 页:

请指导我以防万一,我在这里做错了。

底层 iText 7 bug/peculiarity 与 in this answer 描述的相同,其中 table 跨四页构建,但所有字段都出现在最后一页页。

正如您在评论中澄清的那样,无论如何您都需要 table 和最后一页上的字段。因此,我们需要做的就是将 table 也移动到最后一页。

这个其实很简单,只要在添加table之前添加一个合适的AreaBreak即可:

doc.add(new AreaBreak(AreaBreakType.LAST_PAGE));
doc.add(table);

(AddSignatureField 测试 testAddSignaturesInTable)


您针对此问题更新了 iText 版本。同时,table 创建代码发生了相当大的变化。因此,您可能还想设置签名单元格的宽度,例如

Cell cell = new Cell();
cell.setHeight(50);
cell.setWidth(200);
cell.setNextRenderer(new SignatureFieldCellRenderer(cell, name));
return cell;

(AddSignatureField方法createSignatureFieldCell)