Go语言实现HTML转PDF
很多时候我们需要在后台动态生成图片,pdf来供页面显示,但是使用Go语言写样式是一件很棘手的事情,但是对于html来说却是很轻松,那么又没有什么方法可以将html直接转化为pdf呢?
go-wkhtmltopdf
go-wkhtmltopdf
go语言提供了go-wkhtmltopdf
框架可以将html
转pdf
。
在转换的过程中需要先构建html,这里要使用html/template
库,首先将变量赋值到html中生成完整的html包括内容。
如下html页面:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>{{.ProjectName}}</title><style>body {font-family: "Microsoft YaHei", sans-serif;margin: 30px;position: relative;}h2 {text-align: center;margin-bottom: 30px;}.info-container {margin-bottom: 40px;position: relative;}.info-item {margin: 10px 0;font-size: 16px;}.label {display: inline-block;width: 120px;font-weight: bold;}.tag {display: inline-block;background-color: #007bff;color: white;padding: 3px 10px;border-radius: 4px;font-size: 14px;}.vehicle-group {margin: 20px 0 30px 0;padding-left: 10px;border-left: 3px solid #eee;}.vehicle-title {font-weight: bold;margin-bottom: 10px;font-size: 15px;}.vehicle-list {display: flex;flex-wrap: wrap;gap: 10px;}.vehicle-item {background-color: #f1f3f5;padding: 6px 12px;border-radius: 4px;}.qr-code-container {position: absolute;top: 5px;right: 70px;text-align: center;}.qr-code {width: 200px;height: 200px;}.qr-code-desc {margin-top: 8px;font-size: 14px;color: #666;}</style>
</head>
<body><h2>{{.ProjectName}}</h2><div class="info-container"><div class="info-item"><span class="label">清运单号:</span>{{.OrderNumber}}</div><div class="info-item"><span class="label">有效期限:</span>{{.ValidPeriod}}</div><div class="info-item"><span class="label">项目位置:</span>{{.ProjectLocation}}</div><div class="info-item"><span class="label">报备人姓名:</span>{{.ReporterName}}</div><div class="info-item"><span class="label">报备人手机号:</span>{{.ReporterPhone}}</div><div class="info-item"><span class="label">垃圾类型:</span><span class="tag">{{.GarbageType}}</span></div><div class="info-item"><span class="label">垃圾报备:</span>{{.GarbageReport}}</div><div class="info-item"><span class="label">处置场所:</span>{{.DisposalSite}}</div><!-- 二维码区域 --><div class="qr-code-container"><img src="{{.QrCodeUrl}}" alt="项目二维码" class="qr-code"><div class="qr-code-desc">{{.QrCodeDesc}}</div></div>
</div><!-- 使用循环展示运输企业和车辆信息 -->
{{range .TransportEnterprises}}
<div class="vehicle-group"><div class="vehicle-title">运输企业:{{.Name}}</div><div class="vehicle-title">运输车辆:</div><div class="vehicle-list">{{range .Vehicles}}<div class="vehicle-item">{{.}}</div>{{end}}</div>
</div>
{{end}}
</body>
</html>
go语言赋值参数:
package mainimport ("fmt""github.com/chack1919/go-wkhtmltopdf""html/template""os""strings""time"
)// 定义运输企业结构体
type TransportEnterprise struct {Name string // 企业名称Vehicles []string // 车辆列表
}// 定义模板所需的数据结构
type TemplateData struct {ProjectName string // 项目名称OrderNumber string // 清运单号ValidPeriod string // 有效期限ProjectLocation string // 项目位置ReporterName string // 报备人姓名ReporterPhone string // 报备人手机号GarbageType string // 垃圾类型GarbageReport string // 垃圾报备DisposalSite string // 处置场所TransportEnterprises []TransportEnterprise // 运输企业列表(结构体数组)QrCodeUrl string // 二维码图片URLQrCodeDesc string // 二维码描述
}func main() {// 3. 准备测试数据testData := TemplateData{ProjectName: "三亚市海棠区创业人才保障项目",OrderNumber: "NO.20250630SYS0002",ValidPeriod: fmt.Sprintf("%s 至 %s", time.Now().Format("2006-01-02"), time.Now().AddDate(0, 1, 0).Format("2006-01-02")),ProjectLocation: "海口市龙华区白龙南路99号",ReporterName: "王莹莹",ReporterPhone: "15008976944",GarbageType: "拆除垃圾",GarbageReport: "240 吨",DisposalSite: "海棠湾消纳场",TransportEnterprises: []TransportEnterprise{{Name: "海南省路和实业有限公司",Vehicles: []string{"琼AA1838","琼AA1839","琼AA1840",},},{Name: "海南顺通运输有限公司",Vehicles: []string{"琼BB2956","琼BB2957",},},},QrCodeUrl: "https://picsum.photos/120/120",QrCodeDesc: "扫码查看详情",}temp, err := template.ParseFiles("test.html")if err != nil {panic(err)}file, err := os.Create("output.html")if err != nil {panic(err)}defer func() {err = file.Close()if err != nil {return}}()err = temp.Execute(file, testData)if err != nil {panic(err)}generator, err := wkhtmltopdf.NewPDFGenerator()if err != nil {panic(err)}readFile, err := os.ReadFile("./output.html")if err != nil {panic(err)}generator.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(string(readFile))))err = generator.Create()if err != nil {fmt.Println("Error creating PDF:", err)}create, err := os.Create("test.pdf")if err != nil {panic(err)}_, err = create.Write(generator.Bytes())
}
最终效果: