PDFBox在Windows渲染特殊字符正常但Linux下字符被替换问题求助
PDFBox Acroform 非英文字符Linux环境乱码解决方案
问题根因
本地Windows运行正常、Linux乱码的核心原因有2个:
- 当前使用的Arial_Narrow.ttf未嵌入生成的PDF文件中,Windows系统预装了Arial系列字体,PDF阅读器可自动 fallback 渲染;而Linux环境默认无该字体,无法识别字符。
- 未给文本字段强制指定Unicode编码,低版本PDFBox在Linux环境会默认继承系统编码,导致非WinAnsi字符解析错误。
修复步骤
1. 替换/校验字体文件
确保你使用的Arial_Narrow.ttf是完整版,包含你需要的所有特殊字符(如İ、Ł、ą、ź等拉丁扩展字符),如果没有合适的资源可替换为开源的Noto Sans Narrow字体,该字体对多语言字符支持完整。
2. 修改工具类代码
你需要修改3处代码逻辑:
- 加载字体时开启嵌入子集,把用到的字符打包到PDF中,不依赖系统环境字体
- 给文本字段强制指定Unicode编码(Identity-H)
- 可选:将PDFBox版本升级到2.0.32及以上稳定版,修复低版本已知的Acroform填充编码bug
修改后的核心代码如下:
首先引入依赖类:
import org.apache.pdfbox.cos.COSName;
修改字体加载和文本字段处理逻辑:
// 加载字体,第三个参数true表示仅嵌入用到的字符子集到PDF PDType0Font font = PDType0Font.load(pdDoc, PDFMailMergeUtil.class.getResourceAsStream("/Arial_Narrow.ttf"), true); PDResources res = pdAcroForm.getDefaultResources(); String fontName = res.add(font).getName(); String defaultAppearanceString = "/" + fontName + " 10 Tf 0 g"; // 文本字段处理部分 if (pdfield instanceof PDTextField) { PDTextField textField = (PDTextField) pdfield; textField.setDefaultAppearance(defaultAppearanceString); // 强制使用Unicode水平编码,兼容所有非英文字符 textField.setEncoding(COSName.IDENTITY_H); textField.setValue(formFieldValue); textField.setReadOnly(true); }
3. 校验Linux服务端字符集
确保Java进程启动时添加参数-Dfile.encoding=UTF-8,避免JVM默认使用非UTF-8编码解析字符串。
修改后重新打包部署即可解决Linux环境乱码问题。
内容的提问来源于stack exchange,提问作者sameer59
相关产品推荐
相关产品推荐

