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

SpringBoot中使用openHtmlToPdf加载泰米尔语自定义字体失败求助

解决openHtmlToPdf生成PDF时泰米尔语显示####的问题

问题出在这几个地方:

  • 代码里注册的字体名称和CSS里声明的对不上
  • Spring Boot里直接用File读取resources下的文件,打包后会找不到
  • 页面元素没指定使用自定义字体,默认字体不支持泰米尔语字符
  • 未配置正确的字符编码

一步步修复

1. 统一字体名称

NotoSansTamil.ttf的实际字体内部名称是**"Noto Sans Tamil"**,代码和CSS里必须完全匹配这个名称(可以右键字体文件查看属性里的「字体名称」确认)。

2. 正确读取Spring Boot中的字体文件

Spring Boot打包后,resources下的文件会被放入classpath,不能直接用File读取,改用ClassPathResource获取:

private fun convertToPdf(htmlContent: String): ByteArrayResource {
    val jsoupDocument = Jsoup.parse(htmlContent)
    jsoupDocument.outputSettings().syntax(Document.OutputSettings.Syntax.html)
    // 强制设置UTF-8编码,避免字符乱码
    jsoupDocument.outputSettings().charset(Charset.forName("UTF-8"))
    val xmlDocument = W3CDom().fromJsoup(jsoupDocument)

    // 使用ClassPathResource读取classpath下的字体文件
    val fontResource = ClassPathResource("fonts/NotoSansTamil.ttf")

    val byteArrayOutputStream = ByteArrayOutputStream()
    val baseUrl = javaClass.protectionDomain.codeSource.location.toString()

    PdfRendererBuilder()
        .withW3cDocument(xmlDocument, baseUrl)
        // 注册字体时使用正确的内部名称
        .useFont(fontResource.inputStream, "Noto Sans Tamil")
        .toStream(byteArrayOutputStream)
        .run()
    return ByteArrayResource(byteArrayOutputStream.toByteArray())
}

3. 修正FreeMarker模板

  • 启用UTF-8编码的meta标签
  • 统一CSS中的字体名称
  • 为需要显示泰米尔语的元素指定font-family:
<html>
<head>
    <meta charset="UTF-8">
    <title>FreeMarker</title>
    <style>
        @font-face {
            font-family: 'Noto Sans Tamil';
            font-style: normal;
            font-weight: 400;
            src: url('./fonts/NotoSansTamil.ttf');
        }
        /* 全局设置字体,或针对特定元素单独设置 */
        body, h1, p {
            font-family: 'Noto Sans Tamil', sans-serif;
        }
    </style>
</head>
<body>
    <h1> Welcome to FreeMarker ${name} </h1>
    <!-- 测试泰米尔语内容 -->
    <p>வணக்கம் FreeMarker</p>
</body>
</html>

4. 额外检查点

  • 确认src/main/resources/fonts/目录下确实存在NotoSansTamil.ttf文件,打包后能在jar包的BOOT-INF/classes/fonts/路径下找到
  • 如果问题依旧,检查字体文件是否损坏,或更换其他版本的Noto Sans Tamil字体
  • 确保FreeMarker渲染生成的HTML内容本身为UTF-8编码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:12:47