使用PDFBox 2.0.30填充俄文PDF文本框遇U+0413编码错误求助
问题解决:PDFBox填充西里尔字符时的编码错误
错误原因
你遇到的U+0413 is not available in this font's encoding: WinAnsiEncoding错误,本质是原有PDF里的文本框仍绑定着仅支持拉丁字符的WinAnsi编码字体。即便你为AcroForm设置了支持西里尔字符的新字体,目标字段并未自动替换旧的字体关联,导致无法编码俄文字符。而新增字段是完全基于你配置的新资源创建的,因此能正常工作。
解决方案
修改代码,确保目标文本字段明确使用包含新字体的资源,并覆盖其默认外观设置,具体代码如下:
public void fillDocument() throws IOException { PDDocument doc = PDDocument.load(new File("InputPdf.pdf")); // 加载支持西里尔字符的Type0字体,嵌入字体提升兼容性 PDFont formFont = PDType0Font.load(doc, Myclass.class.getResourceAsStream( "/org/apache/pdfbox/resources/ttf/LiberationSans-Regular.ttf"), true); PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); // 初始化或复用AcroForm的资源容器 PDResources resources = acroForm.getDefaultResources(); if (resources == null) { resources = new PDResources(); acroForm.setDefaultResources(resources); } // 将新字体添加到资源中并获取字体名 final String fontName = resources.add(formFont).getName(); // 设置合理的字体大小(避免0值导致的异常) String defaultAppearanceString = "/" + fontName + " 12 Tf 0 g"; // 配置AcroForm全局默认资源和外观 acroForm.setDefaultAppearance(defaultAppearanceString); PDTextField textField = (PDTextField) acroForm.getField("lastName"); // 关键步骤:强制字段使用AcroForm的新资源,替换旧字体关联 textField.setResources(acroForm.getDefaultResources()); // 覆盖字段自身的默认外观配置 textField.setDefaultAppearance(defaultAppearanceString); // 关闭自动外观生成开关,强制PDFBox使用我们配置的字体生成外观 acroForm.setNeedAppearances(false); textField.setValue("Горохова"); doc.save("output.pdf"); doc.close(); // 必须关闭文档释放资源 }
额外排查点
- 字段名大小写:确认
getField("lastName")中的字段名与PDF中文本框的实际名称完全一致(PDF字段名区分大小写),问题描述中提到的是lastname,注意核对。 - 清空旧外观:如果仍有异常,可在设置值前删除字段原有外观,强制PDFBox重新生成:
textField.getWidgets().forEach(widget -> widget.setAppearanceDictionary(null)); - 字体兼容性:确保加载的字体确实支持西里尔字符,LiberationSans-Regular是符合要求的。
内容的提问来源于stack exchange,提问作者Liz Lamperouge
相关产品推荐
相关产品推荐

