gofpdf仅支持极简html标签,不解析css;chromedp通过chrome真实渲染,完整支持css/js;go-wkhtmltopdf已停更且兼容性差;pdf体积大是chromium默认行为,需手动优化。

用 gofpdf 渲染简单 HTML 会丢样式和换行
它不解析 CSS,只支持极简的 HTML 标签(<b></b>、<i></i>、<u></u>、<br>),遇到 <div> 或内联 <code>style 直接忽略。适合生成报表标题或带粗体的纯文本段落,不适合渲染页面快照。
实操建议:
- 仅用于结构极简、无 CSS 依赖的场景,比如日志导出、票据摘要
- 若需保留排版,必须手动把 HTML 拆成
Cell()、MultiCell()调用,自己算行高和宽度 - 中文需提前注册字体(
AddFont()+SetFont()),否则显示方块
chromedp 是目前最靠谱的“HTML → PDF”方案
它通过 DevTools 协议调用本地 Chrome/Chromium,真实渲染页面再导出 PDF,能完整支持 CSS、Flex、媒体查询、字体图标甚至 JS 动态内容。
常见错误现象:
-
context deadline exceeded:没加足够超时,或 Chrome 启动失败(缺--no-sandbox) - PDF 空白页:HTML 中含
display: none或未触发重绘(可加runtime.Evaluate强制window.scrollTo(0,0)) - 中文字体缺失:Chrome 默认不加载系统中文字体,需在 HTML 中显式
@font-face或用--font-render-hinting=none
关键参数差异:
-
page.PrintToPDF的PrintToPDFParams{PaperWidth: 210, PaperHeight: 297}单位是毫米(A4 尺寸) - 若 HTML 含相对单位(
rem、vh),确保viewportmeta 已设置,否则渲染尺寸异常 - 本地调试时加
chromedp.ExecAllocatorOption(chromedp.Flag("headless", false))可看实际渲染过程
别直接用 go-wkhtmltopdf —— 它已停止维护且不兼容新版 wkhtmltopdf
这个包依赖 C 库 wkhtmltopdf,但自 2021 年后没更新,无法适配 wkhtmltopdf 0.12.6+ 的新参数(如 --enable-local-file-access)。编译时容易报 undefined reference to 'wkhtmltopdf_init'。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
如果你已有旧项目在用,注意:
- 锁定
wkhtmltopdf版本为0.12.5(Ubuntu 20.04 默认源版本) - Windows 下必须把
wkhtmltopdf.exe放进PATH,不能只传绝对路径 - 不支持 HTTP Basic Auth 页面,会卡在认证弹窗(
chromedp可用network.SetCookies绕过)
PDF 文件体积大?不是代码问题,是渲染策略问题
chromedp 导出的 PDF 默认含完整字体子集(尤其中文字体),一个页面可能达 10MB+。这不是 Go 写法导致的,而是 Chromium 的默认行为。
减小体积的实操方式:
- HTML 中只 @import 必需字体,避免引入整套思源黑体
- 用
page.PrintToPDF的UsePrintDialog: true参数(仅调试),然后手动勾选 “Background graphics” 关闭背景图 - 导出后用
qpdf --optimize压缩(额外命令,非 Go 内置) - 若内容全是文字,考虑先转为 PNG 再用
gofpdf嵌入——反而更小、更可控
真正难处理的是动态 SVG 或 Canvas 导出:Chromium 渲染后转 PDF 会栅格化,失真不可避免。这时候得回到 HTML 层做降级,比如用 svg-to-pdfkit 替代原生渲染。










