使用C# iText.Kernel添加的PDF签名打印时不可见问题求助
问题
在C#中使用iText.Kernel库创建PDF签名域(将矩形属性全部设为0实现不可见签名),完成签名保存PDF后,打开PDF时可见签名显示正常,但执行打印操作时所有签名都不可见,排查不出代码问题。
创建签名域代码
PdfSignatureFormField newSignField = PdfSignatureFormField.CreateSignature(pdfDoc, new Rectangle(pdfFieldInfos.FieldX, pdfFieldInfos.FieldY, pdfFieldInfos.FieldWidth, pdfFieldInfos.FieldHeight)); newSignField.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.WHITE); newSignField.SetBorderColor(iText.Kernel.Colors.ColorConstants.BLACK); newSignField.SetFieldName(pdfFieldInfos.FieldName); form.AddField(newSignField, pdfDoc.GetPage(pdfFieldInfos.FieldPage));
签名代码
var pdfSignatureFieldInfos = pdfExistingSignatureFieldsInfos[i]; using (MemoryStream srcMemStream = new MemoryStream(filledPDF)) { using (MemoryStream memStream = new MemoryStream()) { PdfReader reader = new PdfReader(srcMemStream); reader.SetUnethicalReading(true); // 绕过加密 // 以追加模式打开PDF进行盖章编辑 PdfSigner signer = new PdfSigner(reader, memStream, new StampingProperties().UseAppendMode()); // 创建签名外观 Rectangle rect = new Rectangle(pdfSignatureFieldInfos.FieldX, pdfSignatureFieldInfos.FieldY, pdfSignatureFieldInfos.FieldWidth, pdfSignatureFieldInfos.FieldHeight); PdfSignatureAppearance appearance = signer.GetSignatureAppearance(); appearance .SetPageRect(rect) .SetPageNumber(pdfSignatureFieldInfos.FieldPage); if (pdfSignatureFieldInfos.FieldReason != null) { appearance.SetReason(pdfSignatureFieldInfos.FieldReason); } if (pdfSignatureFieldInfos.FieldLocation != null) { appearance.SetLocation(pdfSignatureFieldInfos.FieldLocation); } if (pdfSignatureFieldInfos.FieldSignatureCreator != null) { appearance.SetSignatureCreator(pdfSignatureFieldInfos.FieldSignatureCreator); } if (pdfSignatureFieldInfos.FieldContact != null) { appearance.SetContact(pdfSignatureFieldInfos.FieldContact); } // 非不可见签名时设置签名图片 if (pdfSignatureFieldInfos.FieldValue != null) { byte[] imageBinaries = Convert.FromBase64String(pdfSignatureFieldInfos.FieldValue); ImageData img = ImageDataFactory.Create(imageBinaries); appearance .SetRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC) .SetSignatureGraphic(img); } // 第一个签署者添加认证签名 if (isFirstRecipientToSign && i == 0) { signer.SetCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING); } else { signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED); } signer.SetFieldName(pdfSignatureFieldInfos.FieldName); // 创建签名 IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm); ITSAClient tsaClient = new TSAClientBouncyCastle("http://timestamp.digicert.com", "", ""); // 设置签名时间戳 signer.SignDetached(pks, chain, null, null, tsaClient, 0, subfilter); reader.Close(); filledPDF = memStream.ToArray(); } }
问题原因与解决方案
核心原因
签名域未设置打印标志,PDF表单域默认不会强制开启打印属性,导致打印时签名被阅读器/打印机忽略。
修复步骤
在创建签名域的代码中,添加一行设置域打印标志的代码:
// 标记签名域需要被打印 newSignField.SetFieldFlags(PdfAnnotation.PRINT);
修改后的创建签名域代码
PdfSignatureFormField newSignField = PdfSignatureFormField.CreateSignature(pdfDoc, new Rectangle(pdfFieldInfos.FieldX, pdfFieldInfos.FieldY, pdfFieldInfos.FieldWidth, pdfFieldInfos.FieldHeight)); newSignField.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.WHITE); newSignField.SetBorderColor(iText.Kernel.Colors.ColorConstants.BLACK); newSignField.SetFieldName(pdfFieldInfos.FieldName); // 添加打印标志,确保签名域会被打印 newSignField.SetFieldFlags(PdfAnnotation.PRINT); form.AddField(newSignField, pdfDoc.GetPage(pdfFieldInfos.FieldPage));
补充说明
- 对于不可见签名(矩形参数全0),此设置不影响其功能,仅针对可见签名生效;
- 该标志会告知PDF阅读器/打印机,此签名域需要被包含在输出内容中,彻底解决打印时签名消失的问题。
内容的提问来源于stack exchange,提问作者Mustapha BOUFARA
相关产品推荐
相关产品推荐

