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

PDFBox在Windows渲染特殊字符正常但Linux下字符被替换问题求助

PDFBox Acroform 非英文字符Linux环境乱码解决方案

问题根因

本地Windows运行正常、Linux乱码的核心原因有2个:

  1. 当前使用的Arial_Narrow.ttf未嵌入生成的PDF文件中,Windows系统预装了Arial系列字体,PDF阅读器可自动 fallback 渲染;而Linux环境默认无该字体,无法识别字符。
  2. 未给文本字段强制指定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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:18:04