You need to enable JavaScript to run this app. Spring Boot 2.3.3下Thymeleaf结合Flying Saucer生成PDF内容偏右截断问题
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.3.3下Thymeleaf结合Flying Saucer生成PDF内容偏右截断问题

核心问题根因
  • Flying Saucer内置的CSS渲染引擎仅兼容CSS 2.1标准,完全无法适配Bootstrap v4的核心布局逻辑:Bootstrap v4的.container类依赖响应式媒体查询、flex布局、视口单位(vw)动态计算边距和宽度,引擎不识别媒体查询时,会错误将容器的margin-left: auto计算为超大值,直接把整块内容推到页面右侧超出边界,这是你遇到错位的最直接原因
  • 你之前配置的@page规则完全无效:Flying Saucer对@page的奇偶页伪类(:right)、视口单位(vw)、嵌套边距的解析存在已知兼容bug,那些带200vw padding、额外margin的配置不仅没修正问题,还会进一步干扰页面宽度计算
  • 模板里使用的flex类(inline-flex)、响应式字号类(display-2/display-4)、基于断点的max-width配置,在没有浏览器动态视口的PDF渲染环境下,会被默认计算为远大于A4页面的宽度值,直接触发横向溢出截断
可落地的修正步骤

1. 替换不适配的Bootstrap依赖逻辑

删除HTML里直接引入的全量Bootstrap webjar链接,不要依赖框架类做PDF排版,在styles.css里写死固定逻辑的基础排版规则:

/* 全局样式重置,放在文件最顶部 */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}
body {
    width: 100%;
    font-family: Lato, sans-serif;
}
/* 替换原Bootstrap的container类,写死宽度不做响应式计算 */
.container {
    width: 100%;
    max-width: 100%;
    padding: 0 2cm; /* 固定左右内边距,禁用auto margin */
}
/* 逐个替换用到的Bootstrap类为固定规则,不依赖框架计算 */
.text-center {
    text-align: center;
}
.float-right {
    float: right;
}
.jumbotron {
    width: 100%;
    padding: 2rem;
    margin-top: 2rem;
    background-color: #e9ecef;
    border-radius: 0.3rem;
}

2. 重写@page规则为引擎可识别的格式

删掉所有带伪类、视口单位的无效@page配置,替换为基础固定规则:

/* 放在styles.css最顶部,不要嵌套复杂选择器 */
@page {
    size: A4; /* 明确指定页面尺寸,不让引擎自动猜测 */
    margin: 2cm;
    /* 页头配置保留基础规则即可 */
    @top-right {
        content: "My PDF";
        font-family: Lato, sans-serif;
    }
}

注意:Flying Saucer不支持:left/:right奇偶页选择器的自定义边距,如果需要配置奇偶页不同边距,需要在Java渲染代码中单独设置,写在CSS里不会生效。

3. 强制修正渲染引擎的宽度计算偏差

在Java侧的PDF渲染代码中,固定渲染上下文的宽度,避免引擎自动计算时出现偏差:

// 初始化渲染器
ITextRenderer renderer = new ITextRenderer();
// 关键配置:强制设置内容区宽度为A4页面减去左右边距后的实际可用宽度
renderer.getSharedContext().setBaseWidth(682); // A4总宽794px,减去两侧各56px边距后的实际值
// 后续接你原有的文档加载、排版、输出逻辑
renderer.setDocumentFromString(htmlContent);
renderer.layout();
renderer.createPDF(outputStream);

4. 替换模板中无法兼容的类名

  • 把原模板里带flex逻辑的inline-flex类删掉,引擎不识别flex布局,会错误计算元素宽度导致溢出
  • 把原模板里带响应式断点逻辑的display-2/display-4类删掉,这类类的字号是基于浏览器宽度断点设置的,引擎完全不识别,直接把字号值写在元素的内联样式里即可
    修正后的核心HTML片段示例:
<body>
    <div class="container">
        <h3 class="text-center" style="font-size: 2.5rem; font-weight: 300;">MY FIRST THYMELEAF TO PDF PROJECT. HAVING ISSUE WITH PDF FORMATTING THOUGH.............</h3>
        <div class="text-center" style="margin-top: 1rem;">
            <span style="font-size: 2.5rem; letter-spacing: 0;">Thymeleaf Template Engine</span>
            <span style="font-size: 2.0rem; opacity: 1; color: #707070; padding-left: 20px;">Flying Saucer PDF</span>
        </div>
        <div class="jumbotron">
            <h2 class="float-right" style="font-size: 4.5rem; font-weight: 300;">Some Jumbo Text</h2>
        </div>
    </div>
</body>
通用踩坑提醒
  • Flying Saucer的CSS引擎仅支持CSS 2.1标准,所有CSS3特性(flex、grid、vw/vh单位、媒体查询、高级伪类选择器)都不要在PDF模板里使用,不仅不生效,还会触发布局计算错误
  • 不要为了图省事直接把浏览器端的前端项目代码(带Bootstrap、Tailwind的页面)直接搬去生成PDF,动态视口下的响应式逻辑和静态PDF的排版逻辑完全不匹配
  • 所有静态资源(字体、图片、CSS文件)要确保是引擎可访问的本地路径,不要走webjar的相对路径,避免样式加载不全引发的错位

内容的提问来源于stack exchange,提问作者Joseph Freeman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.14 14:36:10