English | 日本語 | 中文 | 한국어 | Español | Português
纯 Go 实现的零依赖 PDF 生成库,采用分层架构和声明式构建器 API。
- 零依赖 — 仅使用 Go 标准库
- 分层架构 — 底层 PDF 原语、文档模型和高层模板 API
- 12 列网格系统 — Bootstrap 风格的响应式布局
- TrueType 字体支持 — 自定义字体嵌入与子集化
- CJK 就绪 — 从第一天起完整支持中日韩文本
- 表格 — 表头、列宽、条纹行、垂直对齐、外边框和单元格边框
- 边框和背景 — 适用于表格、图片和 Box 容器(solid / dashed / dotted)
- 页眉和页脚 — 带页码,所有页面统一显示
- 列表 — 无序列表和有序列表
- 二维码 — 纯 Go 二维码生成(支持纠错等级)
- 条形码 — Code 128 条形码生成
- 文本装饰 — 下划线、删除线、字间距、首行缩进
- 页码 — 自动页码和总页数
- Go 模板集成 — 从 Go 模板生成 PDF
- 可复用组件 — 内置发票、报告和信函预设模板
- JSON 模式 — 完全用 JSON 定义文档
- 多种单位 — pt、mm、cm、in、em、%
- 色彩空间 — RGB、灰度、CMYK
- 图片 — JPEG 和 PNG 嵌入(支持缩放选项)
- 绝对定位 — 在页面上以精确 XY 坐标放置元素
- 现有 PDF 叠加 — 打开现有 PDF 并在上面添加文字、图片、印章
- 表单扁平化 — 将 AcroForm 字段扁平化为静态页面内容,保留非控件注释
- PDF 合并 — 将多个 PDF 合并为一个,支持页面范围选择
- 文档元数据 — 标题、作者、主题、创建者
- 加密 — AES-256 加密(ISO 32000-2, Rev 6),支持所有者/用户密码和权限控制
- PDF/A — PDF/A-1b 和 PDF/A-2b 合规,包含 ICC 配置文件和 XMP 元数据
- 数字签名 — CMS/PKCS#7 签名,支持 RSA/ECDSA 密钥和 RFC 3161 时间戳
与 go-pdf/fpdf、signintech/gopdf、maroto v2 对比。 5次运行取中位数,每次100次迭代。Apple M1,Go 1.25。
执行时间(越低越好):
| 基准测试 | gpdf | fpdf | gopdf | maroto v2 |
|---|---|---|---|---|
| 单页 | 13 µs | 132 µs | 423 µs | 237 µs |
| 表格 (4x10) | 108 µs | 241 µs | 835 µs | 8.6 ms |
| 100页 | 683 µs | 11.7 ms | 8.6 ms | 19.8 ms |
| 复杂文档 | 133 µs | 254 µs | 997 µs | 10.4 ms |
内存使用(越低越好):
| 基准测试 | gpdf | fpdf | gopdf | maroto v2 |
|---|---|---|---|---|
| 单页 | 16 KB | 1.2 MB | 1.8 MB | 61 KB |
| 表格 (4x10) | 209 KB | 1.3 MB | 1.9 MB | 1.6 MB |
| 100页 | 909 KB | 121 MB | 83 MB | 4.0 MB |
| 复杂文档 | 246 KB | 1.3 MB | 2.0 MB | 2.0 MB |
- 单页 — 构建→布局→渲染的单次管道,无中间数据结构。全程使用具体结构体类型(无
interface{}装箱),以最少的堆分配构建文档树。 - 表格 — 单元格内容通过可复用的
strings.Builder缓冲区直接写入 PDF 内容流命令。无逐单元格的对象包装或重复字体查找,字体在每个文档中仅解析一次。 - 100页 — 布局以 O(n) 线性扩展。溢出分页通过切片引用传递剩余节点(无深拷贝)。字体仅解析一次并在所有页面间共享。
- 复杂文档 — 无需重新测量的单次布局整合了以上所有优势。字体子集化仅嵌入实际使用的字形,且默认启用 Flate 压缩,使内存和输出大小保持较小。
运行基准测试:
cd _benchmark && go test -bench=. -benchmem -count=5┌─────────────────────────────────────┐
│ gpdf (entry point) │
├─────────────────────────────────────┤
│ template — Builder API, Grid │ Layer 3
├─────────────────────────────────────┤
│ document — Nodes, Style, Layout │ Layer 2
├─────────────────────────────────────┤
│ pdf — Writer, Fonts, Streams │ Layer 1
└─────────────────────────────────────┘
- Go 1.22 或更高版本
go get github.com/gpdf-dev/gpdfpackage main
import (
"os"
"github.com/gpdf-dev/gpdf"
"github.com/gpdf-dev/gpdf/document"
"github.com/gpdf-dev/gpdf/template"
)
func main() {
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithMargins(document.UniformEdges(document.Mm(20))),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Hello, World!", template.FontSize(24), template.Bold())
})
})
data, _ := doc.Generate()
os.WriteFile("hello.pdf", data, 0644)
}字号、字重、样式、颜色、背景色和对齐方式:
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("大号粗体标题", template.FontSize(24), template.Bold())
c.Text("斜体文本", template.Italic())
c.Text("粗体 + 斜体", template.Bold(), template.Italic())
c.Text("红色文本", template.TextColor(pdf.Red))
c.Text("自定义颜色", template.TextColor(pdf.RGBHex(0x336699)))
c.Text("带背景色", template.BgColor(pdf.Yellow))
c.Text("居中对齐", template.AlignCenter())
c.Text("右对齐", template.AlignRight())
})
})渲染 CJK 文本需要嵌入 TrueType 字体。每种语言使用对应的 Noto Sans 字体:
fontData, _ := os.ReadFile("NotoSansSC-Regular.ttf")
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithFont("NotoSansSC", fontData),
gpdf.WithDefaultFont("NotoSansSC", 12),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("你好世界", template.FontSize(18))
})
})对于多语言文档,注册多个字体并使用 FontFamily() 切换:
jpFont, _ := os.ReadFile("NotoSansJP-Regular.ttf")
scFont, _ := os.ReadFile("NotoSansSC-Regular.ttf")
krFont, _ := os.ReadFile("NotoSansKR-Regular.ttf")
doc := gpdf.NewDocument(
gpdf.WithFont("NotoSansJP", jpFont),
gpdf.WithFont("NotoSansSC", scFont),
gpdf.WithFont("NotoSansKR", krFont),
gpdf.WithDefaultFont("NotoSansSC", 12),
)
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(4, func(c *template.ColBuilder) {
c.Text("日本語", template.FontFamily("NotoSansJP"))
})
r.Col(4, func(c *template.ColBuilder) {
c.Text("中文", template.FontFamily("NotoSansSC"))
})
r.Col(4, func(c *template.ColBuilder) {
c.Text("한국어", template.FontFamily("NotoSansKR"))
})
})推荐字体(均为免费,OFL 许可):
| 字体 | 语言 |
|---|---|
| Noto Sans JP | 日文 |
| Noto Sans SC | 简体中文 |
| Noto Sans KR | 韩文 |
使用 Bootstrap 风格的 12 列网格构建布局:
// 两等分列
page.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("左半部分")
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("右半部分")
})
})
// 侧边栏 + 主内容
page.AutoRow(func(r *template.RowBuilder) {
r.Col(3, func(c *template.ColBuilder) {
c.Text("侧边栏")
})
r.Col(9, func(c *template.ColBuilder) {
c.Text("主内容")
})
})使用 Row() 指定高度,或使用 AutoRow() 自适应内容高度:
// 固定高度:30mm
page.Row(document.Mm(30), func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("此行高度为 30mm")
})
})基本表格:
c.Table(
[]string{"名称", "数量", "价格"},
[][]string{
{"组件", "10", "¥50.00"},
{"配件", "3", "¥120.00"},
},
)带样式的表格(表头颜色、列宽、条纹行):
c.Table(
[]string{"产品", "类别", "数量", "单价", "合计"},
[][]string{
{"笔记本 Pro 15", "电子产品", "2", "¥12,990", "¥25,980"},
{"无线鼠标", "配件", "10", "¥299", "¥2,990"},
},
template.ColumnWidths(30, 20, 10, 20, 20),
template.TableHeaderStyle(
template.TextColor(pdf.White),
template.BgColor(pdf.RGBHex(0x1A237E)),
),
template.TableStripe(pdf.RGBHex(0xF5F5F5)),
)表格边框 — 外框、单元格网格、或两者:
outer := template.Border(
template.BorderWidth(document.Pt(1)),
template.BorderColor(pdf.RGBHex(0x1A237E)),
)
grid := template.Border(
template.BorderWidth(document.Pt(0.5)),
template.BorderColor(pdf.Gray(0.5)),
)
// 仅外框
c.Table(header, rows, template.WithTableBorder(outer))
// 仅单元格网格(Excel 风格网格线)
c.Table(header, rows, template.WithTableCellBorder(grid))
// 外框 + 单元格网格 + 背景
c.Table(header, rows,
template.WithTableBorder(outer),
template.WithTableCellBorder(grid),
template.WithTableBackground(pdf.RGBHex(0xFAFAFA)),
)
// 虚线单元格网格
dashed := template.Border(
template.BorderWidth(document.Pt(0.75)),
template.BorderColor(pdf.RGBHex(0x0D47A1)),
template.BorderLine(document.BorderDashed),
)
c.Table(header, rows, template.WithTableCellBorder(dashed))嵌入 JPEG 和 PNG 图片(支持缩放选项):
c.Image(imgData) // 默认尺寸
c.Image(imgData, template.FitWidth(document.Mm(80))) // 按宽度缩放
c.Image(imgData, template.FitHeight(document.Mm(30))) // 按高度缩放带边框和实色背景的图片(适用于透明 PNG):
c.Image(pngData,
template.FitWidth(document.Mm(60)),
template.WithImageBorder(template.Border(
template.BorderWidth(document.Pt(2)),
template.BorderColor(pdf.RGBHex(0xE53935)),
)),
template.WithImageBackground(pdf.RGBHex(0xFFF8E1)),
)将任意列内容包装在带边框、填充和内边距的样式化矩形容器中:
c.Box(func(c *template.ColBuilder) {
c.Text("盒子里")
c.Text("两行正文")
},
template.WithBoxBorder(template.Border(
template.BorderWidth(document.Pt(1)),
template.BorderColor(pdf.RGBHex(0x1A237E)),
)),
template.WithBoxBackground(pdf.RGBHex(0xE8EAF6)),
template.WithBoxPadding(document.UniformEdges(document.Mm(4))),
)c.Line() // 默认(灰色,1pt)
c.Line(template.LineColor(pdf.Red)) // 带颜色
c.Line(template.LineThickness(document.Pt(3))) // 粗线
c.Spacer(document.Mm(5)) // 5mm 垂直间距无序列表和有序列表:
// 无序列表
c.List([]string{"第一项", "第二项", "第三项"})
// 有序列表
c.OrderedList([]string{"步骤一", "步骤二", "步骤三"})可配置大小和纠错等级的二维码生成:
// 基本二维码
c.QRCode("https://gpdf.dev")
// 自定义大小和纠错等级
c.QRCode("https://gpdf.dev",
template.QRSize(document.Mm(30)),
template.QRErrorCorrection(qrcode.LevelH))Code 128 条形码生成:
// 基本条形码
c.Barcode("INV-2026-0001")
// 自定义宽度
c.Barcode("INV-2026-0001", template.BarcodeWidth(document.Mm(80)))自动页码和总页数:
doc.Footer(func(p *template.PageBuilder) {
p.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("由 gpdf 生成", template.FontSize(8))
})
r.Col(6, func(c *template.ColBuilder) {
c.PageNumber(template.AlignRight(), template.FontSize(8))
})
})
})
doc.Header(func(p *template.PageBuilder) {
p.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.TotalPages(template.AlignRight(), template.FontSize(9))
})
})
})下划线、删除线、字间距和首行缩进:
c.Text("下划线文本", template.Underline())
c.Text("删除线文本", template.Strikethrough())
c.Text("宽字间距", template.LetterSpacing(3))
c.Text("首行缩进段落...", template.TextIndent(document.Pt(24)))定义在每一页重复显示的页眉和页脚:
doc.Header(func(p *template.PageBuilder) {
p.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("ACME 公司", template.Bold(), template.FontSize(10))
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("机密文件", template.AlignRight(), template.FontSize(10),
template.TextColor(pdf.Gray(0.5)))
})
})
})
doc.Footer(func(p *template.PageBuilder) {
p.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("由 gpdf 生成", template.AlignCenter(),
template.FontSize(8), template.TextColor(pdf.Gray(0.5)))
})
})
})for i := 1; i <= 5; i++ {
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("页面内容")
})
})
}一个函数调用即可生成常见文档类型:
发票:
doc := template.Invoice(template.InvoiceData{
Number: "#INV-2026-001",
Date: "2026年3月1日",
DueDate: "2026年3月31日",
From: template.InvoiceParty{Name: "ACME公司", Address: []string{"北京市朝阳区123号"}},
To: template.InvoiceParty{Name: "客户有限公司", Address: []string{"上海市浦东新区456号"}},
Items: []template.InvoiceItem{
{Description: "Web开发", Quantity: "40小时", UnitPrice: 150, Amount: 6000},
{Description: "UI/UX设计", Quantity: "20小时", UnitPrice: 120, Amount: 2400},
},
TaxRate: 10,
Notes: "感谢您的惠顾!",
})
data, _ := doc.Generate()报告:
doc := template.Report(template.ReportData{
Title: "季度报告",
Subtitle: "2026年 Q1",
Author: "ACME公司",
Sections: []template.ReportSection{
{
Title: "执行摘要",
Content: "与2025年Q4相比,收入增长了15%。",
Metrics: []template.ReportMetric{
{Label: "收入", Value: "¥12.5M", ColorHex: 0x2E7D32},
{Label: "增长", Value: "+15%", ColorHex: 0x2E7D32},
},
},
{
Title: "收入明细",
Table: &template.ReportTable{
Header: []string{"部门", "2026 Q1", "变化"},
Rows: [][]string{{"云服务", "¥5.2M", "+26.8%"}, {"企业服务", "¥3.8M", "+8.6%"}},
},
},
},
})信函:
doc := template.Letter(template.LetterData{
From: template.LetterParty{Name: "ACME公司", Address: []string{"北京市朝阳区123号"}},
To: template.LetterParty{Name: "张先生", Address: []string{"上海市浦东新区456号"}},
Date: "2026年3月1日",
Subject: "合作提案",
Greeting: "尊敬的张先生:",
Body: []string{"我们希望向您提出战略合作伙伴关系的建议..."},
Closing: "此致敬礼",
Signature: "李明",
})AES-256 加密,支持所有者/用户密码和权限控制:
// 仅所有者密码(无需密码即可打开 PDF,但编辑受限)
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithEncryption(
encrypt.WithOwnerPassword("owner-secret"),
),
)
// 双密码和权限控制
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithEncryption(
encrypt.WithOwnerPassword("owner-pass"),
encrypt.WithUserPassword("user-pass"),
encrypt.WithPermissions(encrypt.PermPrint|encrypt.PermCopy),
),
)生成 PDF/A-1b 或 PDF/A-2b 合规文档:
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithPDFA(
pdfa.WithLevel(pdfa.LevelA2b),
pdfa.WithMetadata(pdfa.MetadataInfo{
Title: "归档报告",
Author: "gpdf",
}),
),
)使用 RSA 或 ECDSA 密钥的 CMS/PKCS#7 签名:
data, _ := doc.Generate()
signed, err := gpdf.SignDocument(data, signature.Signer{
Certificate: cert,
PrivateKey: key,
Chain: intermediates,
},
signature.WithReason("已批准"),
signature.WithLocation("北京"),
signature.WithTimestamp("http://tsa.example.com"),
)打开现有 PDF,使用同一构建器 API 叠加内容:
// 打开现有 PDF
doc, err := gpdf.Open(existingPDFBytes)
// 在第 1 页添加 "DRAFT" 水印
doc.Overlay(0, func(p *template.PageBuilder) {
p.Absolute(document.Mm(50), document.Mm(140), func(c *template.ColBuilder) {
c.Text("DRAFT", template.FontSize(72),
template.TextColor(pdf.Gray(0.85)))
})
})
// 为每页添加页码
count, _ := doc.PageCount()
doc.EachPage(func(i int, p *template.PageBuilder) {
p.Absolute(document.Mm(170), document.Mm(285), func(c *template.ColBuilder) {
c.Text(fmt.Sprintf("%d / %d", i+1, count), template.FontSize(10))
}, template.AbsoluteWidth(document.Mm(20)))
})
result, _ := doc.Save()将交互式 AcroForm 字段扁平化为静态页面内容。链接、批注等非控件注释会被保留:
// 打开包含表单字段的 PDF
doc, err := gpdf.Open(filledFormPDF)
// 将所有表单字段扁平化为静态内容
if err := doc.FlattenForms(); err != nil {
log.Fatal(err)
}
result, _ := doc.Save()将多个 PDF 合并为一个文档,支持页面范围选择:
// 合并多个 PDF
merged, _ := gpdf.Merge(
[]gpdf.Source{
{Data: coverPage},
{Data: report},
{Data: appendix, Pages: gpdf.PageRange{From: 1, To: 3}}, // 仅前 3 页
},
gpdf.WithMergeMetadata("My Document", "Author", ""),
)完全用 JSON 定义文档:
schema := []byte(`{
"page": {"size": "A4", "margins": "20mm"},
"metadata": {"title": "报告", "author": "gpdf"},
"body": [
{"row": {"cols": [
{"span": 12, "text": "来自 JSON 的问候", "style": {"size": 24, "bold": true}}
]}},
{"row": {"cols": [
{"span": 12, "table": {
"header": ["名称", "值"],
"rows": [["Alpha", "100"], ["Beta", "200"]],
"headerStyle": {"bold": true, "color": "white", "background": "#1A237E"}
}}
]}}
]
}`)
doc, err := template.FromJSON(schema, nil)
data, _ := doc.Generate()表格和图片接受与构建器 API 相同的 border / background 键:
style 接受 solid(默认)/ dashed / dotted / none。使用 widths 按 CSS 顺序 [top, right, bottom, left] 指定各边宽度;使用 width 设置统一宽度。
使用 Go 模板和 JSON 模式生成动态内容:
schema := []byte(`{
"page": {"size": "A4", "margins": "20mm"},
"metadata": {"title": "{{.Title}}"},
"body": [
{"row": {"cols": [
{"span": 12, "text": "{{.Title}}", "style": {"size": 24, "bold": true}}
]}}
]
}`)
data := map[string]any{"Title": "动态报告"}
doc, err := template.FromJSON(schema, data)使用预解析的 Go 模板实现更多控制:
tmpl, _ := gotemplate.New("doc").Funcs(template.TemplateFuncMap()).Parse(schemaStr)
doc, err := template.FromTemplate(tmpl, data)doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithMetadata(document.DocumentMetadata{
Title: "年度报告 2026",
Author: "gpdf Library",
Subject: "文档元数据示例",
Creator: "My Application",
}),
)// 可用页面尺寸
document.A4 // 210mm x 297mm
document.A3 // 297mm x 420mm
document.Letter // 8.5in x 11in
document.Legal // 8.5in x 14in
// 统一边距
template.WithMargins(document.UniformEdges(document.Mm(20)))
// 非对称边距
template.WithMargins(document.Edges{
Top: document.Mm(10),
Right: document.Mm(40),
Bottom: document.Mm(10),
Left: document.Mm(40),
})// Generate 返回 []byte
data, err := doc.Generate()
// Render 写入任意 io.Writer
var buf bytes.Buffer
err := doc.Render(&buf)
// 直接写入文件
f, _ := os.Create("output.pdf")
defer f.Close()
doc.Render(f)| 函数 | 说明 |
|---|---|
WithPageSize(size) |
设置页面大小(A4、A3、Letter、Legal) |
WithMargins(edges) |
设置页面边距 |
WithFont(family, data) |
注册 TrueType 字体 |
WithDefaultFont(family, size) |
设置默认字体 |
WithMetadata(meta) |
设置文档元数据 |
WithEncryption(opts...) |
启用 AES-256 加密 |
WithPDFA(opts...) |
启用 PDF/A 合规 |
| 方法 | 说明 |
|---|---|
c.Text(text, opts...) |
添加带样式选项的文本 |
c.Table(header, rows, opts...) |
添加表格 |
c.Image(data, opts...) |
添加图片(JPEG/PNG) |
c.QRCode(data, opts...) |
添加二维码 |
c.Barcode(data, opts...) |
添加条形码(Code 128) |
c.List(items, opts...) |
添加无序列表 |
c.OrderedList(items, opts...) |
添加有序列表 |
c.PageNumber(opts...) |
添加当前页码 |
c.TotalPages(opts...) |
添加总页数 |
c.Line(opts...) |
添加水平线 |
c.Spacer(height) |
添加垂直间距 |
c.Box(fn, opts...) |
在带样式的 Box 中包装内容(边框 / 填充 / 内边距) |
| 方法 | 说明 |
|---|---|
page.AutoRow(fn) |
添加自动高度行 |
page.Row(height, fn) |
添加固定高度行 |
page.Absolute(x, y, fn, opts...) |
在精确 XY 坐标放置内容 |
| 选项 | 说明 |
|---|---|
gpdf.AbsoluteWidth(value) |
设置显式宽度(默认:剩余空间) |
gpdf.AbsoluteHeight(value) |
设置显式高度(默认:剩余空间) |
gpdf.AbsoluteOriginPage() |
以页面角为原点,而非内容区域 |
| 函数 / 方法 | 说明 |
|---|---|
gpdf.Open(data, opts...) |
打开现有 PDF 用于叠加 |
doc.PageCount() |
获取页数 |
doc.Overlay(page, fn) |
在指定页上叠加内容 |
doc.EachPage(fn) |
对每页应用叠加 |
doc.FlattenForms() |
将 AcroForm 字段扁平化为静态页面内容 |
doc.Save() |
保存修改后的 PDF |
gpdf.Merge(sources, opts...) |
将多个 PDF 合并为一个 |
WithMergeMetadata(title, author, producer) |
设置合并后的元数据 |
| 选项 | 说明 |
|---|---|
template.FontSize(size) |
设置字号(单位:磅) |
template.Bold() |
粗体 |
template.Italic() |
斜体 |
template.FontFamily(name) |
使用已注册的字体 |
template.TextColor(color) |
设置文本颜色 |
template.BgColor(color) |
设置背景颜色 |
template.Underline() |
下划线装饰 |
template.Strikethrough() |
删除线装饰 |
template.LetterSpacing(pts) |
设置字间距(磅) |
template.TextIndent(value) |
设置首行缩进 |
template.AlignLeft() |
左对齐(默认) |
template.AlignCenter() |
居中对齐 |
template.AlignRight() |
右对齐 |
| 选项 | 说明 |
|---|---|
template.ColumnWidths(w...) |
设置列宽百分比 |
template.TableHeaderStyle(opts...) |
设置表头行样式 |
template.TableStripe(color) |
设置交替行颜色 |
template.TableCellVAlign(align) |
设置单元格垂直对齐(Top/Middle/Bottom) |
template.WithTableBorder(spec) |
在表格周围绘制外边框 |
template.WithTableCellBorder(spec) |
在每个表头和正文单元格周围绘制相同的边框(网格线) |
template.WithTableBorderCollapse(b) |
启用相邻单元格边框合并 |
template.WithTableBackground(color) |
填充表格的外部 Box |
| 选项 | 说明 |
|---|---|
template.FitWidth(value) |
按宽度缩放(保持宽高比) |
template.FitHeight(value) |
按高度缩放(保持宽高比) |
template.MinDisplayWidth(v) |
低于此宽度时溢出到下一页 |
template.MinDisplayHeight(v) |
低于此高度时溢出到下一页 |
template.WithImageBorder(spec) |
在图片周围绘制边框 |
template.WithImageBackground(color) |
填充图片的 Box(适用于透明 PNG) |
| 选项 | 说明 |
|---|---|
template.WithBoxBorder(spec) |
在 Box 周围绘制边框 |
template.WithBoxBackground(color) |
填充 Box |
template.WithBoxPadding(edges) |
内边距 |
template.WithBoxMargin(edges) |
外边距 |
template.WithBoxWidth(value) |
显式宽度 |
template.WithBoxHeight(value) |
显式高度 |
构建一次 BorderSpec 并通过 WithTableBorder / WithTableCellBorder /
WithImageBorder / WithBoxBorder / WithTextBorder 应用:
spec := template.Border(
template.BorderWidth(document.Pt(1)), // 四边统一
template.BorderColor(pdf.RGBHex(0x1A237E)),
template.BorderLine(document.BorderSolid), // BorderSolid | BorderDashed | BorderDotted
)| 选项 | 说明 |
|---|---|
template.Border(opts...) |
构建 BorderSpec(默认 1pt 黑色实线) |
template.BorderWidth(v) |
四边统一宽度 |
template.BorderWidths(t, r, b, l) |
按 CSS 顺序设置各边宽度 |
template.BorderColor(c) |
边线颜色 |
template.BorderLine(style) |
线型:BorderSolid / BorderDashed / BorderDotted / BorderNone |
| 选项 | 说明 |
|---|---|
template.QRSize(value) |
设置二维码大小 |
template.QRMinSize(value) |
最小显示尺寸 — 低于此值时溢出到下一页 |
template.QRErrorCorrection(level) |
设置纠错等级(L/M/Q/H) |
template.QRScale(n) |
设置模块缩放因子 |
| 选项 | 说明 |
|---|---|
template.BarcodeWidth(value) |
设置条形码宽度 |
template.BarcodeHeight(value) |
设置条形码高度 |
template.BarcodeFormat(fmt) |
设置条形码格式(Code 128) |
| 选项 | 说明 |
|---|---|
encrypt.WithOwnerPassword(pw) |
设置所有者密码 |
encrypt.WithUserPassword(pw) |
设置用户密码 |
encrypt.WithPermissions(perm) |
设置文档权限 (PermPrint, PermCopy, PermModify 等) |
| 选项 | 说明 |
|---|---|
pdfa.WithLevel(level) |
设置合规级别 (LevelA1b, LevelA2b) |
pdfa.WithMetadata(info) |
设置 XMP 元数据 (Title, Author, Subject 等) |
| 函数 / 选项 | 说明 |
|---|---|
gpdf.SignDocument(data, signer, opts...) |
使用数字签名签署 PDF |
signature.WithReason(reason) |
设置签名原因 |
signature.WithLocation(location) |
设置签名位置 |
signature.WithTimestamp(tsaURL) |
启用 RFC 3161 时间戳 |
signature.WithSignTime(t) |
设置签名时间 |
| 函数 | 说明 |
|---|---|
template.FromJSON(schema, data) |
从 JSON 模式生成文档 |
template.FromTemplate(tmpl, data) |
从 Go 模板生成文档 |
template.TemplateFuncMap() |
获取模板辅助函数(包含 toJSON) |
| 函数 | 说明 |
|---|---|
template.Invoice(data) |
生成专业发票 PDF |
template.Report(data) |
生成结构化报告 PDF |
template.Letter(data) |
生成商务信函 PDF |
| 选项 | 说明 |
|---|---|
template.LineColor(color) |
设置线条颜色 |
template.LineThickness(value) |
设置线条粗细 |
document.Pt(72) // 点(1/72 英寸)
document.Mm(10) // 毫米
document.Cm(2.5) // 厘米
document.In(1) // 英寸
document.Em(1.5) // 相对于字体大小
document.Pct(50) // 百分比pdf.RGB(0.2, 0.4, 0.8) // RGB(0.0–1.0)
pdf.RGBHex(0xFF5733) // 十六进制 RGB
pdf.Gray(0.5) // 灰度
pdf.CMYK(0, 0.5, 1, 0) // CMYK
// 预定义颜色
pdf.Black, pdf.White, pdf.Red, pdf.Green, pdf.Blue
pdf.Yellow, pdf.Cyan, pdf.MagentaMIT
{"span": 12, "table": { "header": ["名称", "数量", "单价"], "rows": [["A","1","¥100"], ["B","2","¥200"]], "border": {"width": "1pt", "color": "#1A237E"}, // 外框 "cellBorder": {"width": "0.5pt", "color": "gray(0.5)", "style": "dashed"}, // 网格线 "background": "#FAFAFA" }} {"span": 12, "image": { "src": "...", "width": "60mm", "border": {"widths": ["2pt","2pt","2pt","2pt"], "color": "#E53935"}, "background": "#FFF8E1" }}