wkhtmltopdf 是目前 HTML 转 PDF 中对 CSS 布局(尤其是 float、flex、图片内联对齐)支持最稳的命令行工具,底层基于 WebKit 渲染,但需配合 --no-stop-slow-scripts、显式设置页面尺寸、禁用页边距、img 标签带宽高属性、避免 background-image、降级 Flex/Grid、嵌入中文字体等关键配置才能可靠保留图片对齐。
用 wkhtmltopdf 保留图片对齐最靠谱
直接说结论:wkhtmltopdf 是目前 html 转 pdf 中对 css 布局(尤其是 float、flex、图片内联对齐)支持最稳的命令行工具,比浏览器原生 print to pdf 或 js 库(如 jspdf + html2canvas)更可靠。
它底层调用 WebKit 渲染引擎,能真实复现浏览器中看到的排版。但默认参数下图片常错位、换行异常——问题不在 HTML 写法,而在渲染时机和页面尺寸控制。
-
必须加
--no-stop-slow-scripts:否则含懒加载或动态插入图片的页面,PDF 里图片直接消失 -
显式设置
--page-width和--page-height(比如210mm×297mm),避免自动缩放破坏 CSS 像素精度 -
禁用智能页边距:
--margin-top 0 --margin-bottom 0 --margin-left 0 --margin-right 0,否则外层容器 padding/margin 会被二次挤压 - 图片用
<img>标签,别用background-image——wkhtmltopdf对 CSS 背景图的支持极弱,尤其带background-size: contain时大概率不渲染
img 标签必须带 width 和 height 属性
CSS 设置宽高在 PDF 渲染中容易失效,特别是用 max-width: 100% + height: auto 的响应式写法。浏览器里看着正常,PDF 里图片会塌缩成一条线,或撑破容器。
解决办法不是靠 CSS,而是给 <img> 加内联 width 和 height(单位用 px 或 mm),并配合 style="object-fit: contain;" 控制内容填充方式。
- 错误写法:
<img src="a.jpg" style="max-width:100%; height:auto;"> - 正确写法:
<img src="a.jpg" width="300" height="200" style="object-fit: contain;"> - 如果图片原始尺寸不确定,后端生成 HTML 时需先读取图片元信息,写死
width/height,不能依赖前端 JS 计算 - 用
object-fit比background-size安全得多,但仅限contain和cover;scale-down在 wkhtmltopdf 0.12.6+ 才支持,旧版本会退化为拉伸
CSS Flex/Grid 布局要降级处理
wkhtmltopdf 对现代布局支持有限:Flex 项目在跨页时可能整体被切到下一页,Grid 线条位置偏移常见,justify-content: center 经常失效。
立即学习“前端免费学习笔记(深入)”;
不是不能用,而是得加“保险”:
- 所有 flex 容器必须设
min-height(比如min-height: 1em),否则空 flex 项在 PDF 中高度为 0 - 避免
flex-wrap: wrap+ 多图混排 —— 换行逻辑和浏览器不一致,图片可能堆叠或错列;改用display: inline-block+vertical-align: top更稳 - Grid 布局建议只用于静态单页,且显式定义
grid-template-columns为固定值(如100px 100px),别用fr或auto-fit - 文字环绕图片(
float: left)可用,但必须给浮动元素加clear: both的后续块级元素,否则后续段落会跑进图片下方空白区
中文断行和字体缺失导致图片错位
图片对齐异常,有时根本不是图片的问题,而是中文字体没嵌入,导致段落高度突变,连带影响图片基线定位。
wkhtmltopdf 默认只认系统字体,Linux 服务器上通常没有思源黑体、微软雅黑,中文会 fallback 到等宽字体,行高暴涨,把原本紧贴文字的 <img align="absmiddle"> 拉离预期位置。
- 必须用
--font-family指定已安装的中文字体,例如:--font-family "Noto Sans CJK SC" - HTML 中
<style>里不要只写font-family: "Microsoft YaHei",得提供 fallback 链:font-family: "Noto Sans CJK SC", sans-serif; - 字体文件路径要用绝对路径,且确保 wkhtmltopdf 进程有读取权限;TTF/OTF 均可,但别用 .ttc 合集(部分版本不识别)
- 加
--enable-local-file-access,否则 @font-face 引用本地字体文件会失败,报错QFont::setPixelSize: Pixel size
图片对齐是多个环节咬合的结果:渲染引擎选型、标签属性、CSS 兼容性、字体链、甚至服务器字体目录权限——漏掉任一环,PDF 里就差那么一像素。











