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

