如何在 gpdf 表格中添加斑马条纹行?
传入 template.TableStripe 即可,gpdf 会自动给隔行涂上你指定的背景色,不用写循环、也不用逐格设置样式。
把问题换个说法
我有一个表格 — 发票、流水、日志 — 行数超过 5 行后眼睛容易跳行。Bootstrap 里的 .table-striped 就是隔行加灰底,我想在 gpdf 里也实现这个,但不想写行循环。
一句话答案
c.Table(header, rows, template.TableStripe(pdf.RGBHex(0xF5F5F5)))
就这一行。gpdf 负责交替着色。表头不在斑马条纹范围内,只对主体行生效:第 1 行保持白色,第 2 行加底色,第 3 行白色,第 4 行加底色,以此类推。
可运行的代码
package main
import (
"log"
"os"
"github.com/gpdf-dev/gpdf"
"github.com/gpdf-dev/gpdf/document"
"github.com/gpdf-dev/gpdf/pdf"
"github.com/gpdf-dev/gpdf/template"
)
func main() {
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithMargins(document.UniformEdges(document.Mm(20))),
)
brand := pdf.RGBHex(0x1A237E) // 表头背景色
stripe := pdf.RGBHex(0xF5F5F5) // 隔行底色
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Text("Q1 销售汇总", template.FontSize(20), template.Bold())
c.Spacer(document.Mm(4))
c.Table(
[]string{"产品", "区域", "数量", "销售额"},
[][]string{
{"Laptop Pro 15", "北美", "120", "¥1,058,400"},
{"Wireless Mouse", "欧洲", "640", "¥130,560"},
{"USB-C Hub", "亚太", "410", "¥139,400"},
{"Monitor 27\"", "北美", "180", "¥489,600"},
{"Keyboard", "欧洲", "320", "¥174,080"},
{"Webcam HD", "亚太", "260", "¥159,120"},
},
template.ColumnWidths(40, 20, 15, 25),
template.TableHeaderStyle(
template.TextColor(pdf.White),
template.BgColor(brand),
),
template.TableStripe(stripe),
)
})
})
data, err := doc.Generate()
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("sales.pdf", data, 0o644); err != nil {
log.Fatal(err)
}
}
go run main.go 即可。主体 6 行中有 3 行带底色,表头深蓝白字。这就是周一邮件里发出去的报表样式。
交替着色的原理
内部上,gpdf 用从 0 开始的下标 i 遍历主体行,只对 i%2 == 1 的行涂条纹色。表头是单独的切片,不参与计数。
| 主体行下标 (从 0 开始) | 视觉位置 | 是否带条纹? |
|---|---|---|
| 0 | 第 1 行 | 否 |
| 1 | 第 2 行 | 是 |
| 2 | 第 3 行 | 否 |
| 3 | 第 4 行 | 是 |
| ... | ... | ... |
这套奇偶规则跟 Bootstrap 一致。第一行干净,条纹是视觉"换气",白行—浅色行—白行,眼睛自然跳跃。
没有反转奇偶的开关(让奇数行带色)。如果非要反过来,可以在主体最前插一空行 — 但其实没人想要这种效果。
颜色怎么选
条纹的关键在于 不抢眼。一旦颜色和正文抢注意力,条纹就失去意义。
pdf.RGBHex(0xF5F5F5) // 柔和暖灰,Bootstrap 默认色附近
pdf.RGBHex(0xFAFAFA) // 更淡,小字号下几乎看不出
pdf.RGBHex(0xEEF2FF) // 品牌色的极浅版本(表头是品牌色时最合适)
pdf.Gray(0.96) // 灰度版本,PDF/A 输出时省几个字节
避免高饱和度。60% 饱和度的蓝条纹会被读成"这一行被选中/重要",视线反而被钉住,与斑马条纹"帮助跨行扫读"的目的相反。
少数深色主题(幻灯片样式的报表偶尔有)可以在 0x1A1A1A 页面上用 pdf.RGBHex(0x202020)。低对比度的原则不变。
与单元格边框组合
短表格用条纹就够了。财务类高密度表格,推荐配合 WithTableCellBorder 在每个单元格之间画细线:
hairline := template.Border(
template.BorderWidth(document.Pt(0.5)),
template.BorderColor(pdf.Gray(0.85)),
)
c.Table(header, rows,
template.ColumnWidths(40, 20, 15, 25),
template.TableHeaderStyle(
template.TextColor(pdf.White),
template.BgColor(brand),
),
template.TableStripe(pdf.RGBHex(0xF5F5F5)),
template.WithTableCellBorder(hairline),
)
细线 + 浅条纹 = 财务部打印预览的经典样式。边框颜色一定要比条纹更浅,这样条纹仍然是主信号、边框只是辅助。
只想要外边框、不要内部网格的话,把 WithTableCellBorder 换成 WithTableBorder。
容易浪费十分钟的坑
- 颜色取值范围搞错。
pdf.RGB(245, 245, 245)会变成纯黑色块。构造函数要求 0.0–1.0,而不是 0–255。习惯 CSS 写法的话用pdf.RGBHex(0xF5F5F5)。 - 想给表头加条纹。
TableStripe不影响表头。要给表头加底色应该用TableHeaderStyle(template.BgColor(...)),这是另一个选项。混淆这两个、然后纳闷"表头怎么没颜色",是最经典的初次踩坑。 - 想要双色交替。gpdf 只接受一个条纹色,没有 white → gray → blue 三色循环。这不是功能限制,而是有意为之 — 三色斑马只会让读者更累。
- 3 行的小表格也加条纹。斑马条纹至少需要 4–5 行才有效。2–3 行加上去,只会让人以为"某一格被选中"。短表格直接不要条纹。
相关菜谱
- 如何为表格设置自定义列宽? —
ColumnWidths详解。 - 如何在 gpdf 中加载自定义 TrueType 字体? — 用品牌字体渲染条纹表。
- 用 Go 在 50 行内生成发票 PDF — 包含表头样式、条纹、合计行的实战示例。
试试 gpdf
gpdf 是一个用纯 Go 写的 PDF 生成库,MIT 许可、零外部依赖、原生 TrueType 处理。
go get github.com/gpdf-dev/gpdf