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

使用OpenHTMLToPDF生成PDF时特定字符显示为#的问题排查求助

解决OpenHTMLToPDF中DejaVuSans字体无法显示特殊字符的问题

我帮你分析下这个问题——PDF里出现#替代字符,本质是OpenHTMLToPDF找不到对应字符的字体字形(glyph)。虽然DejaVuSans确实支持土耳其语的ı, ş, İ这些字符,但你的配置大概率有这几处问题:

1. 字体加载时机错误(最核心的问题)

你当前的代码是先构建渲染器,再添加字体:

pdfRendererBuilder.buildPdfRenderer().getFontResolver().addFont(...)

但OpenHTMLToPDF的渲染器一旦build完成,字体上下文就已经初始化,后续添加的字体根本不会生效。正确的做法是在构建渲染器之前,通过PdfRendererBuilder直接配置字体:

try (InputStream is = pdfTtfFile.getInputStream()) {
    // 先通过builder注册字体,再build渲染器
    pdfRendererBuilder.useFont(() -> is, "deja-sans");
} catch (IOException e) {
    logger.warn("error while loading DejaVuSans_1.ttf font", e);
}

// 最后构建渲染器
PdfRenderer renderer = pdfRendererBuilder.buildPdfRenderer();

useFont是官方推荐的便捷方法,能确保字体在渲染器初始化时就被正确加载。

2. 确认字体文件的完整性

检查你用的DejaVuSans_1.ttf是不是完整的DejaVu Sans常规字体:

  • 有些字体文件是子集化的(只包含常用字符),如果你的TTF是裁剪过的,可能刚好缺失土耳其语的特殊字符
  • 建议替换成完整的DejaVu Sans字体文件(常规版本大小约1.4MB),避免字符缺失

3. 验证字体名称与CSS的匹配

虽然你设置了别名deja-sans,但有时候别名匹配可能出现问题。可以尝试直接使用字体的内部名称:

  • DejaVu Sans的内部名称是"DejaVu Sans"(注意空格和大小写),修改代码:
pdfRendererBuilder.useFont(() -> is, "DejaVu Sans");

然后CSS同步修改:

body { font-family: 'DejaVu Sans', sans-serif; }

这样能彻底避免别名匹配的潜在问题。

4. 检查HTML的字符编码

确保你的HTML文件是以UTF-8编码保存的,并且在头部声明编码:

<meta charset="UTF-8">

如果HTML本身编码错误,OpenHTMLToPDF解析到的就是乱码,自然找不到对应的字形。

按上面的步骤调整后,应该就能正确显示Fıstıkçı Şahap İlkay Günel这些内容了。

内容的提问来源于stack exchange,提问作者İlkay Gunel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:37:51