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路径:

  1. 当前目录
  2. PATH和PATHEXT环境变量目录
  3. 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

1 回复

更多关于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)

注意事项

  1. wkhtmltopdf对CSS的支持有限,特别是Flexbox和Grid布局可能会有问题
  2. 复杂的JavaScript可能无法正确执行
  3. 对于中文等非拉丁字符,确保HTML中指定了正确的字符集
  4. 在生产环境中,考虑添加错误处理和重试机制

性能优化

对于大量PDF生成,可以:

  1. 复用PDF生成器实例
  2. 使用并发生成,但注意wkhtmltopdf本身不是线程安全的
  3. 缓存常用模板

go-wkhtmltopdf是一个功能强大且相对简单的库,适合需要从HTML生成PDF的Go应用程序。

回到顶部