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

iText7生成PDF表单域非拉丁文字默认不显示问题求助

iText 7 生成多语言可填充PDF文本域显示异常问题解决

问题描述

我使用itext 7.1.9库创建了带可填充文本域的PDF文档,PdfTextFormField中包含多语言文本。PDF生成完成后,在Adobe Acrobat Reader中打开时文本域内的非拉丁符号消失,仅可见拉丁字符,点击该字段后,包括非拉丁符号在内的全部文本都会正常显示。

  • 文档打开后的PDF文本域状态:文档打开后的PDF文本域状态
  • 点击文本域后的显示状态:点击文本域后的显示状态

我使用如下代码生成PDF:

public class Main {
    public static void main(String[] args) throws IOException, URISyntaxException {
        FontProviderAndFormFieldExample app = new FontProviderAndFormFieldExample();
        app.createPdf("Test1.pdf");
        app.fillExample("Test1.pdf", "Result.pdf", Paths.get(Main.class.getResource("/fonts").toURI()).toString());
    }

    public static class FontProviderAndFormFieldExample {
        public String FIELDNAME = "test";
        public Rectangle FIELDRECT = new Rectangle(50,300,300,20);
        public String FIELDVALUE = "ПриветHello";

        public void createPdf(String dest) throws IOException {
            PdfWriter writer = new PdfWriter(dest);
            PdfDocument pdfDoc = new PdfDocument(writer);
            Document doc = new Document(pdfDoc);

            Paragraph para = new Paragraph("Test document for multi-font appearance in a text formfield");
            doc.add(para);

            PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDoc,true);
            PdfTextFormField ff = PdfFormField.createText(pdfDoc,FIELDRECT,"test", FIELDVALUE);
            ff.setMultiline(true);
            ff.setScroll(true);
            acroForm.addField(ff,pdfDoc.getFirstPage());

            PdfCanvas pdfCanvas = new PdfCanvas(pdfDoc.getFirstPage());
            pdfCanvas.setLineWidth(1f).setStrokeColor(ColorConstants.BLUE).rectangle(FIELDRECT).stroke();

            doc.close();
        }

        public void fillExample(String src, String dest, String srcf) throws IOException, URISyntaxException {
            PdfReader reader = new PdfReader(src);
            PdfWriter writer = new PdfWriter(dest);
            PdfDocument pdfDoc = new PdfDocument(reader,writer);
            PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDoc,true);
            PdfFormField ff = acroForm.getField(FIELDNAME);
            String filename = Main.class.getResource("/fonts/arial unicode.ttf").toURI().toString();
            final PdfFont font = PdfFontFactory.createFont(filename, PdfEncodings.UTF8, false);
            ff.setFont(font).setValue(FIELDVALUE);

            pdfDoc.close();

        }
    }
}

我已尝试多种方案均无效:

  • 已知可以调用ff.setNeedAppearence(true)方法,但该方法会破坏应用的其他功能因此无法使用
  • 无法使用PdfEncoding.IDENTITY_H配置,因为它只会嵌入代码中指定的符号子集,后续用户无法正常填充该表单域

问题原因

当前代码的问题核心在于两点:

  1. 创建初始表单字段时没有提前绑定支持全字符集的字体,iText默认使用的字体仅支持拉丁字符,生成的默认外观流没有包含非拉丁字符的渲染规则,Adobe Reader打开时直接用默认外观渲染就会丢失非拉丁字符
  2. 填充字段时没有强制iText生成完整的自定义外观流,同时没有设置表单全局的默认字体规则,后续用户手动填写时也可能出现字符不显示的问题

解决方案

无需使用setNeedAppearence,也无需用IDENTITY_H嵌入子集,按如下规则修改代码即可解决:

  1. 提前加载支持多语言的字体,设置为全嵌入、禁止子集化,确保所有字符都被打包到PDF中
  2. 创建表单字段时就绑定该全字符字体,不要等到后续填充阶段才设置
  3. 调用setValue时开启强制生成外观参数,让iText直接渲染包含所有字符的默认显示效果
  4. 给整个AcroForm设置默认字体规则,确保后续用户手动填写时也能正常渲染所有字符

修改后的核心代码片段如下:

// 1. 提前定义全局全字符字体,embedded设为true表示嵌入PDF,subset设为false禁止子集化,确保所有字符都可用
String fontPath = Main.class.getResource("/fonts/arial unicode.ttf").toURI().toString();
PdfFont fullFont = PdfFontFactory.createFont(fontPath, PdfEncodings.UTF8, true, false);

// 2. 创建表单字段时直接绑定该字体,同时指定字号
PdfTextFormField ff = PdfFormField.createText(pdfDoc,FIELDRECT,"test", FIELDVALUE, fullFont, 12f);

// 3. 填充字段时调用带appearance参数的setValue方法,第二个参数设为true强制生成正确的外观流
ff.setFont(fullFont).setValue(FIELDVALUE, true);

// 4. 给整个表单设置默认外观,字体名称要和嵌入字体的PostScript名称一致,可通过fullFont.getName()打印获取实际名称
acroForm.setDefaultAppearance("/ArialUnicodeMS 12 Tf 0 g");

注意事项

  • 全字库嵌入会增加PDF的体积,Arial Unicode MS全嵌入大概会增加20MB左右的体积,如果对体积有要求可以换用更小的全字符开源字体,比如Noto Sans系列全字库
  • 默认外观里的字体名称必须和嵌入字体的PostScript名称完全一致,否则Adobe Reader会找不到字体回退到系统字体,依然可能出现显示异常
  • 当前使用的iText 7.1.9版本存在少量表单字体渲染的已知bug,如果修改后还是有问题可以升级到7.2.5以上的稳定版本,该版本已经修复了多语言表单字段默认外观生成的相关问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:45:03