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
相关产品推荐
相关产品推荐

