You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:17:07