Go 每日一库:Go 生成 PDF 不再是噩梦!Folio 零依赖搞定,还支持中文
在 Go 里生成 PDF,长期以来是个痛。
你想生成一份发票?大概率得调用外部服务,或者绑一个 Chromium 实例跑 Puppeteer。如果要支持中文?抱歉,可能还得拉一套字体子集化流程。
Folio 改变了游戏规则。这个刚刚在 2026 年 3 月发布的 Go 库,把 PDF 生成做到了极致:一行 Go 代码,零外部依赖,直接输出 PDF。
go get github.com/carlos7ags/folio
三行代码生成 PDF:
doc := document.NewDocument(document.PageSizeA4)doc.Add(layout.NewHeading("Hello, Folio!", layout.H1))doc.Add(layout.NewParagraph("Generated with Folio — the modern PDF library for Go.", font.Helvetica, 12))doc.Save("hello.pdf")
这不是玩具。Folio 支持的特性包括:
-
HTML 转 PDF — 粘贴任意 HTML 模板,零 Chrome 依赖 -
布局引擎 — 表格、列表、浮动、弹性盒 -
交互式表单 — 文本框、复选框、下拉框 -
数字签名 — PAdES B-B/B-T/B-LT 合规 -
条码生成 — QR 码、Code128、EAN-13 -
PDF/A 归档 — 支持 PDF/A-2B、PDF/A-3B -
PDF 读取 — 解析、合并、截取、涂黑(Redaction)
HTML 转 PDF:最实用的功能
大多数 PDF 生成场景,你手里已经有 HTML 模板——发票、报告、证书。传统方案需要起一个无头浏览器,成本高、慢、难部署。
Folio 的 HTML 转 PDF 不需要 Chrome:
doc := document.NewDocument(document.PageSizeLetter)elems, _ := html.Convert(` <h1>Invoice #1042</h1> <p>Bill to: <strong>Acme Corp</strong></p> <table border="1"> <tr><th>Item</th><th>Amount</th></tr> <tr><td>Consulting</td><td>$1,200</td></tr> </table>`, nil)for _, e := range elems { doc.Add(e)}doc.Save("invoice.pdf")
支持 40+HTML 元素、内联 CSS、flexbox 布局、SVG、hex/rgb 颜色。Folio Playground 甚至提供在线预览,粘贴 HTML 即可看到 PDF 效果。
中文支持:字体嵌入
对于中国开发者来说,PDF 中文支持是关键需求。Folio 通过字体嵌入解决这个问题:
import"github.com/carlos7ags/folio/font"// 注册中文字体(支持TTF/OTF)chineseFont, _ := font.Register("path/to/NotoSansSC-Regular.ttf")// 在HTML模板中使用elems, _ := html.Convert(` <h1>发票 #1042</h1> <p>公司:<strong>某某科技</strong></p>`, nil)for _, e := range elems { doc.Add(e)}
Folio 支持所有 Unicode 字符,包括 CJK(中日韩)文字。只需注册对应字体文件,即可正常渲染中文,完全避免了传统方案需要的字体子集化复杂流程。
布局引擎:不只是文本
Folio 的布局引擎采用无状态设计——元素在布局阶段不会发生任何修改。这带来的好处是:页面拆分可预测,跨页表格自动处理表头重复。
doc.Add(layout.NewHeading("Q3 Revenue Report", layout.H1))tbl := layout.NewTable().SetAutoColumnWidths()h := tbl.AddHeaderRow()h.AddCell("Product", font.HelveticaBold, 10)h.AddCell("Units", font.HelveticaBold, 10)h.AddCell("Revenue", font.HelveticaBold, 10)r := tbl.AddRow()r.AddCell("Widget A", font.Helvetica, 10)r.AddCell("1,200", font.Helvetica, 10)r.AddCell("$48,000", font.Helvetica, 10)doc.Add(tbl)
支持的布局元素包括:段落、标题、表格、列表、浮动图片、Flex 容器、多栏排版、页码控制。
企业级能力:表单、签名、归档
交互式表单
form := forms.NewAcroForm()form.Add(forms.NewTextField("name", [4]float64{72, 700, 300, 720}, 0))form.Add(forms.NewCheckbox("agree", [4]float64{72, 670, 92, 690}, 0, false))form.Add(forms.NewDropdown("role", [4]float64{72, 640, 250, 660}, 0, []string{"Developer", "Designer", "Manager"}))doc.SetAcroForm(form)
数字签名
signer, _ := sign.NewLocalSigner(privateKey, []*x509.Certificate{cert})signed, _ := sign.SignPDF(pdfBytes, sign.Options{ Signer: signer, Level: sign.LevelBB, Reason: "Approved", Location: "New York",})
支持 PAdES B-B(Basic)、B-T(带时间戳)、B-LT(长验证周期)三种级别,也支持外接 HSM/KMS 签名。
PDF/A 归档
doc.SetPdfA(document.PdfA2B) // PDF/A-2B compliancedoc.SetTagged(true) // PDF/UA 无障碍
PDF 读取与处理
除了生成,Folio 还能读取和处理现有 PDF:
// 读取并提取文本r, _ := reader.Load("document.pdf")page, _ := r.Page(0)text, _ := page.ExtractText()// 合并PDFr1, _ := reader.Load("doc1.pdf")r2, _ := reader.Load("doc2.pdf")m, _ := reader.Merge(r1, r2)// 涂黑敏感信息(彻底删除,非覆盖)re := regexp.MustCompile(`\d{3}-\d{2}-\d{4}`)m, _ := reader.RedactPattern(r, re, &reader.RedactOptions{ OverlayText: "REDACTED", StripMetadata: true,})
极简依赖:只有一个
这是 Folio 最 Go 的设计:只有一个外部依赖golang.org/x/image,用于矢量图形渲染。相比之下,现有 Go PDF 库的依赖树往往长达十几个。
如果你只需要生成简单 PDF,image依赖甚至可以推迟到实际使用时再安装。
C ABI:346 个导出函数
Folio 还提供 C 共享库libfolio.so/.dylib/.dll,导出 346 个函数,可以从 Python、Ruby、C#、Java 等语言调用。
CGO_ENABLED=1 go build -buildmode=c-shared -o libfolio.so ./export/
适用场景
Folio 适合这些场景:
-
发票/报告生成 — HTML 模板直接转 PDF -
证书/函件批量 — 模板填充 + 数字签名 -
数据导出 — 将结构化数据渲染为 PDF -
PDF 处理 — 合并、拆分、涂黑 -
归档系统 — PDF/A 合规输出
不适合:需要渲染复杂 CSS3/JS 的完整网页、需要像素级浏览器渲染的场景。
总结
Folio 补齐了 Go 生态的一块短板。想想之前生成 PDF 要依赖 wkhtmltopdf、Chromium、或者 Java 库,Folio 让这件事变得轻量和 Go 起来。
项目地址:github.com/carlos7ags/folio,Apache 2.0 许可。
本文使用 Folio Playground 在线验证了 HTML→PDF 转换效果。
推荐阅读

夜雨聆风