如何将签名形式添加到现有的 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 文件,向其添加顺序签名,然后进一步将其传递给签名。
我试着把这个过程分成两步。
在 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();
}
取 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
)
我将 iText7 用于 pdf 签名工作流程,我遵循 i7js-signatures 提供的示例。但是我的要求是获取一个输入 pdf 文件,向其添加顺序签名,然后进一步将其传递给签名。
我试着把这个过程分成两步。
在 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(); }
取 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
)