golang将HTML模板转换为PDF文件的插件库go-wkhtmltopdf的使用
golang将HTML模板转换为PDF文件的插件库go-wkhtmltopdf的使用
go-wkhtmltopdf是一个Golang命令行包装器,用于将HTML/CSS模板转换为PDF文档。它提供了对wkhtmltopdf命令行工具的全部功能的封装。
警告
wkhtmltopdf已不再维护并在GitHub上归档。这个Go包目前仍在维护,但对于新项目建议寻找替代方案。
功能特点
- 提供类型安全的选项设置
- 支持从URL或io.Reader添加页面
- 内置输出缓冲区,也可直接写入文件
- 支持JSON序列化和反序列化
- 易于在服务器应用中使用
安装
go get -u github.com/SebastiaanKlippert/go-wkhtmltopdf
go-wkhtmltopdf会按以下顺序查找wkhtmltopdf路径:
- 当前目录
- PATH和PATHEXT环境变量目录
- WKHTMLTOPDF_PATH环境变量目录
如果需要自定义路径,可以使用SetPath()
方法。
基本使用示例
package main
import (
"fmt"
"log"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
func main() {
// 创建PDF生成器
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
// 设置全局选项
pdfg.Dpi.Set(300) // 设置DPI
pdfg.Orientation.Set(wkhtmltopdf.OrientationLandscape) // 横向
pdfg.Grayscale.Set(true) // 灰度模式
// 从URL创建新页面
page := wkhtmltopdf.NewPage("https://example.com")
// 设置页面选项
page.FooterRight.Set("[page]") // 页脚右侧显示页码
page.FooterFontSize.Set(10) // 页脚字体大小
page.Zoom.Set(0.95) // 缩放比例
// 添加到文档
pdfg.AddPage(page)
// 创建PDF文档到内部缓冲区
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 将缓冲区内容写入磁盘文件
err = pdfg.WriteFile("./output.pdf")
if err != nil {
log.Fatal(err)
}
fmt.Println("PDF生成完成")
}
从HTML字符串生成PDF
html := "<html><body><h1>Hello PDF</h1></body></html>"
pdfg.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(html)))
JSON序列化与反序列化
可以在客户端准备PDF配置,然后在服务器生成PDF:
// 客户端代码
pdfg := wkhtmltopdf.NewPDFPreparer()
htmlfile, err := ioutil.ReadFile("template.html")
if err != nil {
log.Fatal(err)
}
pdfg.AddPage(wkhtmltopdf.NewPageReader(bytes.NewReader(htmlfile)))
pdfg.Dpi.Set(600)
// 将配置保存为JSON
jb, err := pdfg.ToJSON()
if err != nil {
log.Fatal(err)
}
// 服务器代码
pdfgFromJSON, err := wkhtmltopdf.NewPDFGeneratorFromJSON(bytes.NewReader(jb))
if err != nil {
log.Fatal(err)
}
// 生成PDF
err = pdfgFromJSON.Create()
if err != nil {
log.Fatal(err)
}
性能
性能主要取决于wkhtmltopdf本身或外部HTML源的加载时间。Go包装器的开销可以忽略不计(约0.04ms处理命令选项)。
注意事项
- 确保系统已安装wkhtmltopdf
- 对于大型文件,考虑直接写入磁盘而非内存缓冲区
- 可以使用
SetOutput()
方法指定任何io.Writer
作为输出目标
这个库提供了一种简单高效的方式在Go应用中生成PDF文档,特别适合需要从HTML模板生成复杂布局的情况。
更多关于golang将HTML模板转换为PDF文件的插件库go-wkhtmltopdf的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang将HTML模板转换为PDF文件的插件库go-wkhtmltopdf的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-wkhtmltopdf将HTML模板转换为PDF
go-wkhtmltopdf是一个Go语言封装wkhtmltopdf工具的库,可以方便地将HTML内容转换为PDF文件。wkhtmltopdf是一个开源命令行工具,使用WebKit渲染引擎将HTML转换为PDF。
安装准备
首先需要安装wkhtmltopdf工具:
- Linux:
sudo apt-get install wkhtmltopdf
- Mac:
brew install wkhtmltopdf
- Windows: 从官网下载安装
然后安装go-wkhtmltopdf库:
go get github.com/SebastiaanKlippert/go-wkhtmltopdf
基本使用示例
package main
import (
"bytes"
"log"
"os"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
func main() {
// 初始化PDF生成器
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
// 设置全局选项
pdfg.Dpi.Set(300)
pdfg.Orientation.Set(wkhtmltopdf.OrientationPortrait)
pdfg.Grayscale.Set(false)
// 创建HTML页面
page := wkhtmltopdf.NewPage("https://example.com")
// 或者从字符串创建
// page := wkhtmltopdf.NewPageReader(bytes.NewReader([]byte("<html><body><h1>Hello World</h1></body></html>")))
// 设置页面选项
page.FooterRight.Set("[page]")
page.FooterFontSize.Set(10)
page.Zoom.Set(0.95)
// 添加页面到生成器
pdfg.AddPage(page)
// 创建PDF
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 写入文件
err = pdfg.WriteFile("./output.pdf")
if err != nil {
log.Fatal(err)
}
}
结合HTML模板生成PDF
更常见的场景是使用Go的HTML模板生成内容后转换为PDF:
package main
import (
"bytes"
"html/template"
"log"
"os"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
type Invoice struct {
Number string
Customer string
Items []Item
}
type Item struct {
Name string
Quantity int
Price float64
}
func main() {
// 准备模板数据
inv := Invoice{
Number: "INV-2023-001",
Customer: "Acme Corp",
Items: []Item{
{"Product A", 2, 99.99},
{"Product B", 1, 149.99},
{"Service C", 3, 49.99},
},
}
// 解析HTML模板
tmpl, err := template.ParseFiles("invoice.html")
if err != nil {
log.Fatal(err)
}
// 执行模板到缓冲区
var buf bytes.Buffer
err = tmpl.Execute(&buf, inv)
if err != nil {
log.Fatal(err)
}
// 初始化PDF生成器
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
// 设置全局选项
pdfg.Dpi.Set(300)
pdfg.PageSize.Set(wkhtmltopdf.PageSizeA4)
pdfg.Orientation.Set(wkhtmltopdf.OrientationPortrait)
pdfg.MarginTop.Set(15)
pdfg.MarginBottom.Set(15)
// 从缓冲区创建页面
page := wkhtmltopdf.NewPageReader(&buf)
// 添加页面到生成器
pdfg.AddPage(page)
// 生成PDF
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 写入文件
err = pdfg.WriteFile("invoice.pdf")
if err != nil {
log.Fatal(err)
}
log.Println("PDF generated successfully")
}
高级选项
go-wkhtmltopdf支持wkhtmltopdf的大多数选项:
// 设置页眉页脚
pdfg.HeaderHTML.Set("header.html")
pdfg.FooterHTML.Set("footer.html")
// 设置封面页
cover := wkhtmltopdf.NewPage("cover.html")
pdfg.Cover = cover
// 设置TOC(目录)
pdfg.TOC.Include = true
pdfg.TOC.TocHeaderText.Set("Table of Contents")
// 设置JavaScript延迟
page.JavascriptDelay.Set(1000) // 1秒延迟
// 禁用智能分页
page.DisableSmartShrinking.Set(true)
注意事项
- wkhtmltopdf对CSS的支持有限,特别是Flexbox和Grid布局可能会有问题
- 复杂的JavaScript可能无法正确执行
- 对于中文等非拉丁字符,确保HTML中指定了正确的字符集
- 在生产环境中,考虑添加错误处理和重试机制
性能优化
对于大量PDF生成,可以:
- 复用PDF生成器实例
- 使用并发生成,但注意wkhtmltopdf本身不是线程安全的
- 缓存常用模板
go-wkhtmltopdf是一个功能强大且相对简单的库,适合需要从HTML生成PDF的Go应用程序。