升级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(); } }
关键说明
- 表单初始化:将
PdfAcroForm.GetAcroForm的第二个参数设为true,确保表单被正确初始化,避免默认字体未关联的问题。 - 外观再生:调用
field.RegenerateField()强制重新生成字段外观,确保嵌入字体被写入外观流,替代原有可能使用未嵌入字体的外观。 - 字体注册:通过
pdfDocument.AddFont()将字体纳入文档管理,避免iText校验时判定字体未被嵌入。
内容的提问来源于stack exchange,提问作者Reinhard
相关产品推荐
相关产品推荐

