很多时候我们需要在后台动态生成图片,pdf来供页面显示,但是使用Go语言写样式是一件很棘手的事情,但是对于html来说却是很轻松,那么又没有什么方法可以将html直接转化为pdf呢?
go语言提供了go-wkhtmltopdf
框架可以将html
转pdf
。
在转换的过程中需要先构建html,这里要使用html/template
库,首先将变量赋值到html中生成完整的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语言赋值参数:
go
package main
import (
"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 // 二维码图片URL
QrCodeDesc 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())
}
最终效果:
