Spring Boot集成Thymeleaf模板生成PDF时自定义字体无法生效
Spring Boot + Thymeleaf 生成PDF自定义字体失效解决方案
1. 先确认打包配置无异常
多数场景是构建工具打包时过滤了二进制字体文件,导致类路径下找不到字体资源。Maven配置示例:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <excludes> <exclude>**/*.ttf</exclude> <exclude>**/*.otf</exclude> </excludes> </resource> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>**/*.ttf</include> <include>**/*.otf</include> </includes> </resource> </resources> </build>
Gradle项目需配置processResources任务,区分处理文本文件和二进制字体文件即可。
2. 模板CSS写法修正
不要使用普通Web相对路径/根路径,需配合Thymeleaf的资源路径解析规则,示例:
<head> <style> @font-face { font-family: 'Museo Sans'; src: url([[@{classpath:/templates/fonts/MuseoSans-Regular.ttf}]]) format('truetype'); font-weight: normal; font-style: normal; } /* 后续使用字体时名称必须完全匹配,大小写、空格都不能出错 */ body { font-family: 'Museo Sans', sans-serif; } </style> </head>
注意:尽量使用TTF格式字体,Flying Saucer/IText等主流PDF生成组件对OTF格式兼容性较差。
3. PDF生成器配置(以常用的Flying Saucer ITextRenderer为例)
仅靠HTML里的@font-face不足以让生成组件识别字体,需要在代码中注册字体、设置资源解析路径:
// 先获取Thymeleaf渲染后的HTML内容 String htmlContent = templateEngine.process("file_template", context); ITextRenderer renderer = new ITextRenderer(); // 1. 手动注册字体,参数控制编码、是否嵌入PDF renderer.getFontResolver().addFont("classpath:/templates/fonts/MuseoSans-Regular.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // 2. 设置资源解析基础路径,确保CSS中引用的其他资源也能被正确识别 renderer.setDocumentFromString(htmlContent, Objects.requireNonNull(getClass().getResource("/templates/")).toExternalForm()); renderer.layout(); // 后续输出PDF的逻辑 try (OutputStream os = new FileOutputStream("output.pdf")) { renderer.createPDF(os); }
其他排查点
- 确认字体文件无损坏,可在本地先安装验证是否能正常使用
- 检查
font-family的名称在@font-face定义和实际使用处完全一致,包括空格、大小写 - 确认字体版权允许嵌入PDF,部分商用字体会限制嵌入功能
内容的提问来源于stack exchange,提问作者user3648235
相关产品推荐
相关产品推荐

