Goテンプレート
概要
gpdfはGoの text/template パッケージと統合し、動的コンテンツ生成をサポートします。テンプレートはJSONスキーマ出力を生成し、gpdfがPDFとしてレンダリングします。
2つのアプローチが利用可能です:
- FromJSON — JSONにGoテンプレート式をインラインで埋め込む(シンプル)
- FromTemplate — パース済みGoテンプレートによるフルコントロール(柔軟)
FromJSONとテンプレート式
よりシンプルなアプローチ — Goテンプレート式をJSON内に直接埋め込みます:
schema := []byte(`{
"page": {"size": "A4", "margins": "20mm"},
"metadata": {"title": "{{.Title}}"},
"body": [
{"row": {"cols": [
{"span": 12, "text": "{{.Title}}", "style": {"size": 24, "bold": true}}
]}},
{"row": {"cols": [
{"span": 12, "text": "Author: {{.Author}}"}
]}}
]
}`)
doc, err := template.FromJSON(schema, map[string]any{
"Title": "Monthly Report",
"Author": "ACME Corp",
})
FromTemplateとパース済みテンプレート
ループや条件分岐などの複雑なロジックには FromTemplate を使用します:
import (
gotemplate "text/template"
"github.com/gpdf-dev/gpdf/template"
)
tmplStr := `{
"page": {"size": "A4", "margins": "20mm"},
"metadata": {"title": "{{.Title}}"},
"body": [
{"row": {"cols": [
{"span": 12, "text": "{{.Title}}", "style": {"size": 24, "bold": true}}
]}},
{"row": {"cols": [
{"span": 12, "spacer": "5mm"}
]}},
{{- range $i, $section := .Sections}}
{{- if $i}},{{end}}
{"row": {"cols": [
{"span": 12, "elements": [
{"type": "text", "content": "{{$section.Heading}}", "style": {"size": 16, "bold": true, "color": "#1A237E"}},
{"type": "spacer", "height": "3mm"},
{"type": "text", "content": "{{$section.Body}}"},
{"type": "spacer", "height": "8mm"}
]}
]}}
{{- end}}
]
}`
tmpl, err := gotemplate.New("report").Funcs(template.TemplateFuncMap()).Parse(tmplStr)
if err != nil {
log.Fatal(err)
}
type section struct {
Heading string
Body string
}
data := map[string]any{
"Title": "Quarterly Report - Q1 2026",
"Sections": []section{
{
Heading: "Executive Summary",
Body: "Revenue increased 25% year-over-year, driven by new enterprise offerings.",
},
{
Heading: "Product Development",
Body: "The gpdf library reached v0.8 with JSON schema and Go template support.",
},
{
Heading: "Market Analysis",
Body: "PDF generation market grows. Zero-dependency approach resonates with Go devs.",
},
{
Heading: "Next Steps",
Body: "Focus on reusable components, fuzz testing, and v1.0 release.",
},
},
}
doc, err := template.FromTemplate(tmpl, data)
if err != nil {
log.Fatal(err)
}
pdfData, err := doc.Generate()
┌─ A4 ──────────────────────────────────────────────┐
│ │
│ Quarterly Report - Q1 2026 ← 24pt bold │
│ │
│ Executive Summary ← 16pt bold blue │
│ Revenue increased 25% year-over-year, driven │
│ by new enterprise offerings. │
│ │
│ Product Development │
│ The gpdf library reached v0.8 with JSON schema │
│ and Go template support. │
│ │
│ Market Analysis │
│ PDF generation market grows. Zero-dependency │
│ approach resonates with Go devs. │
│ │
│ Next Steps │
│ Focus on reusable components, fuzz testing, │
│ and v1.0 release. │
│ │
└───────────────────────────────────────────────────┘
テンプレート関数マップ
テンプレートをパースする際は TemplateFuncMap() を使用してください — ヘルパー関数が提供されます:
tmpl, err := gotemplate.New("doc").Funcs(template.TemplateFuncMap()).Parse(tmplStr)
利用可能な関数
| 関数 | 説明 |
|---|---|
toJSON | Go値をJSON文字列に変換(データ埋め込みに便利) |
rangeによる動的セクション
データをループして繰り返しセクションを生成します:
{{- range $i, $item := .Items}}
{{- if $i}},{{end}}
{"row": {"cols": [
{"span": 6, "text": "{{$item.Name}}"},
{"span": 6, "text": "{{$item.Value}}", "style": {"align": "right"}}
]}}
{{- end}}
条件分岐
条件付きコンテンツには if を使用します:
{{- if .ShowHeader}}
{"row": {"cols": [
{"span": 12, "text": "{{.HeaderText}}", "style": {"size": 20, "bold": true}}
]}},
{{- end}}
ヒント
- テンプレートアクション周辺の空白を除去するには
{{-と-}}を使用してください rangeループ内のJSONカンマの扱いに注意してください({{if $i}},{{end}}を使用)- ビルトインヘルパー関数を取得するには
TemplateFuncMap()を使用してください - Goオプション(
WithFont,WithMarginsなど)でテンプレート設定をオーバーライドできます:
doc, err := template.FromTemplate(tmpl, data,
template.WithFont("NotoSansJP", fontData),
template.WithDefaultFont("NotoSansJP", 12),
)