如何使用PDFBox在单次签名会话中添加多可视化签名并完成外部签名?
解决PDFBox单次签名会话添加多可见签名的问题
问题根源
- 空间不足异常:未设置
PreferredSignatureSize时,PDFBox默认预留的签名空间不足以容纳多个签名的完整数据,直接触发IOException。 - 仅最后一个签名可见:复用同一
SignatureOptions实例或未为每个签名分配独立的外观图层/位置,后续签名的外观会覆盖之前的签名内容。
修复方案
1. 为每个签名创建独立的签名配置
禁止复用SignatureOptions,每个签名都生成新实例,并根据签名数量设置足够大的PreferredSignatureSize(建议单签名预留40000字节以上,多签名按数量累加):
for (SignatureDefinition def : signatureDefinitions) { // 每个签名都新建SignatureOptions SignatureOptions signatureOptions = new SignatureOptions(); // 按签名数量预留足够空间,示例为3个签名预留120000字节 signatureOptions.setPreferredSignatureSize(40000 * signatureDefinitions.size()); // 配置当前签名的页面与位置 signatureOptions.setPage(def.getPageIndex()); PDRectangle signRect = new PDRectangle(def.getLeft(), def.getBottom(), def.getWidth(), def.getHeight()); signatureOptions.setVisualSignature(buildUniqueVisualSignature(document, signRect, def.getSignerName())); // 执行签名 signer.sign(signatureOptions); // 及时关闭当前配置,释放资源 signatureOptions.close(); }
2. 生成独立的签名外观
每个签名的可视化外观必须创建独立的PDFormXObject,避免复用导致的覆盖:
private PDFormXObject buildUniqueVisualSignature(PDDocument doc, PDRectangle rect, String signerName) throws IOException { PDFormXObject visualForm = new PDFormXObject(doc); visualForm.setBBox(rect); visualForm.setResources(new PDResources()); try (PDPageContentStream contentStream = new PDPageContentStream(doc, visualForm)) { // 绘制签名边框 contentStream.addRect(rect.getLowerLeftX(), rect.getLowerLeftY(), rect.getWidth(), rect.getHeight()); contentStream.setStrokingColor(Color.LIGHT_GRAY); contentStream.stroke(); // 添加签名人信息文本 contentStream.beginText(); contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12); contentStream.setNonStrokingColor(Color.BLACK); contentStream.newLineAtOffset(rect.getLowerLeftX() + 10, rect.getLowerLeftY() + 15); contentStream.showText("签署人:" + signerName); contentStream.endText(); } return visualForm; }
3. 确保签名位置不重叠
遍历signatureDefinitions时,需保证每个签名的页面坐标不重叠,可通过配置文件或业务逻辑为每个签名分配唯一的页面区域(如不同页面、同一页面的不同象限)。
4. 维持单次会话的增量签名流程
全程保持PDDocument处于打开状态,所有签名完成后再统一关闭文档,确保PDFBox以增量更新模式追加每个签名,而非覆盖原有内容。
内容的提问来源于stack exchange,提问作者H20
相关产品推荐
相关产品推荐

