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

升级iText至7.2.5后填充PDF/A表单时Courier字体未嵌入报错求助

解决iText 7.2.5填充PDF/A AcroForm时的字体未嵌入异常

问题核心

从iText 7.1.5升级到7.2.5后,填充PDF/A文档的AcroForm时触发All the fonts must be embedded. This one isn't: Courier异常。这是因为iText 7.1.7版本开始强化了PDF/A的字体嵌入合规性校验,对字体在文档(包括表单字段外观)中的实际嵌入状态检查更严格,旧版本中未被检测到的隐性问题(如字段外观未正确使用嵌入字体)在新版本中会触发错误。

解决方案

方案1:确保字体正确嵌入并关联到表单

显式将字体注册到文档,同时设置表单默认字体为嵌入字体,强制字段外观使用该字体:

using (var pdfDocument = new PdfADocument(pdfReader, writer))
{
    // 完整参数创建嵌入字体,指定编码保证兼容性
    PdfFont fontCourier = PdfFontFactory.CreateFont(
        fontBytes, 
        PdfEncodings.WINANSI, 
        PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED
    );
    
    // 将字体添加到文档的字体集合,确保被跟踪管理
    pdfDocument.AddFont(fontCourier);
    
    // 获取或创建AcroForm,初始化表单环境
    var acroForm = PdfAcroForm.GetAcroForm(pdfDocument, true);
    // 设置表单默认字体,避免字段使用未嵌入的系统默认字体
    acroForm.SetDefaultFont(fontCourier);
    
    var field = acroForm.GetField(formField.Name);
    if (field != null)
    {
        // 设置字段值并指定嵌入字体
        field.SetValue(fieldValue, fontCourier, fontSize);
        // 强制重新生成字段外观,确保字体嵌入到外观流中
        field.RegenerateField();
    }
}

方案2:复用文档中已有的嵌入Courier字体

如果文档本身已嵌入Courier字体,需确保正确获取并关联到字段,避免重复创建导致的校验问题:

using (var pdfDocument = new PdfADocument(pdfReader, writer))
{
    PdfFont existingCourier = null;
    // 遍历文档字体,筛选已嵌入的Courier字体
    foreach (var font in pdfDocument.GetFonts())
    {
        var fontName = font.GetFontProgram().GetFontNames().GetFontName();
        if (fontName.Contains("Courier") && font.IsEmbedded())
        {
            existingCourier = font;
            break;
        }
    }
    
    // 未找到则创建新的嵌入字体
    if (existingCourier == null)
    {
        existingCourier = PdfFontFactory.CreateFont(
            fontBytes, 
            PdfEncodings.WINANSI, 
            PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED
        );
        pdfDocument.AddFont(existingCourier);
    }
    
    var acroForm = PdfAcroForm.GetAcroForm(pdfDocument, true);
    acroForm.SetDefaultFont(existingCourier);
    
    var field = acroForm.GetField(formField.Name);
    if (field != null)
    {
        field.SetValue(fieldValue, existingCourier, fontSize);
        field.RegenerateField();
    }
}

关键说明

  1. 表单初始化:将PdfAcroForm.GetAcroForm的第二个参数设为true,确保表单被正确初始化,避免默认字体未关联的问题。
  2. 外观再生:调用field.RegenerateField()强制重新生成字段外观,确保嵌入字体被写入外观流,替代原有可能使用未嵌入字体的外观。
  3. 字体注册:通过pdfDocument.AddFont()将字体纳入文档管理,避免iText校验时判定字体未被嵌入。

内容的提问来源于stack exchange,提问作者Reinhard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 13:35:17