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

使用Thymeleaf与Flying Saucer生成PDF时CSS未生效问题求助

Thymeleaf + Flying Saucer 生成PDF无CSS样式问题排查方案

1. 修正CSS引用路径

Flying Saucer对资源路径的解析逻辑和浏览器不同,相对路径大概率无法被正确加载,建议:

  • 优先使用内部CSS(直接写在<style>标签内),这是最稳妥的方式
  • 若使用外部CSS,必须指定绝对路径:本地资源用file:///开头的路径,线上资源用完整HTTP路径,避免../css/style.css这类相对路径

示例:

<!-- 推荐写法:内部样式 -->
<style type="text/css">
    .container { width: 100%; padding: 20px; }
    .title { font-size: 24px; color: #333; }
</style>

<!-- 不推荐:相对路径外部样式 -->
<link rel="stylesheet" href="../css/pdf-style.css">

<!-- 推荐:绝对路径外部样式 -->
<link rel="stylesheet" href="file:///D:/project/src/main/resources/static/css/pdf-style.css">

2. 适配Flying Saucer的CSS语法

Flying Saucer基于旧版CSS标准,现代CSS特性兼容性差,需调整写法:

  • 避免flexbox/grid布局,改用float、table等传统布局方式
  • 禁用CSS简写,使用完整属性名(比如用margin-top代替margin简写)
  • 字体优先使用系统内置字体,若用自定义字体,需通过@font-face指定本地绝对路径

示例:

/* 适配写法 */
.header {
    float: left;
    width: 100%;
    height: 50px;
    background-color: #f5f5f5;
    padding-left: 15px;
    padding-right: 15px;
    font-family: "Arial", sans-serif;
}

/* 不推荐的现代写法 */
.header {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-family: "Noto Sans", sans-serif;
}

3. 调整Service类的资源加载逻辑

在生成PDF的代码中,需为Flying Saucer指定资源解析的基准路径,帮助它识别相对资源:

@Service
public class PdfService {
    private final TemplateEngine templateEngine;

    public PdfService(TemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }

    public byte[] generatePdf(String templateName, Map<String, Object> data) throws Exception {
        String html = templateEngine.process(templateName, new Context(Locale.getDefault(), data));
        ITextRenderer renderer = new ITextRenderer();
        
        // 设置资源基准路径,替换为你的静态资源目录绝对路径
        String baseUrl = getClass().getResource("/static/").toExternalForm();
        renderer.setDocumentFromString(html, baseUrl);
        
        // 可选:添加字体支持,解决中文乱码或自定义字体问题
        renderer.getFontResolver().addFont("/path/to/fonts/arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

        renderer.layout();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        renderer.createPDF(outputStream);
        return outputStream.toByteArray();
    }
}

4. 规范HTML模板结构

Flying Saucer对HTML结构要求严格,需确保:

  • 开头声明标准DOCTYPE:<!DOCTYPE html>
  • 结构完整,包含<html>、<head>、<body>标签,CSS必须放在<head>内
  • 避免使用HTML5新标签(如<header>、<section>),改用<div>;若必须使用,需添加CSS声明:
header, section { display: block; }

5. 验证生成的HTML内容

即使浏览器显示正常,仍需检查生成的HTML是否存在以下问题:

  • Thymeleaf的动态路径(如th:href)是否正确渲染为绝对路径
  • 是否存在未闭合标签,导致Flying Saucer解析异常
  • 内联样式是否正常生效(Flying Saucer对内联样式的支持优先级最高)

内容的提问来源于stack exchange,提问作者Rahul Raj Sonu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:17:26