基本的な使い方
ドキュメントの作成
すべてのPDFは template.New() で Document を作成することから始まります:
import (
"github.com/gpdf-dev/gpdf/document"
"github.com/gpdf-dev/gpdf/template"
)
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(20))),
)
ドキュメントオプション
| オプション | 説明 |
|---|---|
WithPageSize(size) | ページサイズ — document.A4, A3, Letter, Legal |
WithMargins(edges) | ページマージン(document.UniformEdges() またはカスタム document.Edges{} を使用) |
WithFont(family, data) | TrueTypeフォントを登録(フォントファイルのバイトを渡す) |
WithDefaultFont(family, size) | デフォルトのフォントファミリーとサイズを設定 |
WithMetadata(meta) | タイトル、著者、件名、作成者を設定 |
ページとコンテンツの追加
コンテンツは階層構造で整理されます: Document → Page → Row → Column → Elements
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())
})
})
┌─ Page ────────────────────────────────┐
│ ┌─ Row ─────────────────────────────┐ │
│ │ ┌─ Col(12) ─────────────────────┐ │ │
│ │ │ Hello, World! │ │ │
│ │ └───────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└───────────────────────────────────────┘
テキストスタイリング
c.Text() にファンクショナルオプションとしてスタイルを適用します:
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
// Font sizes
c.Text("Font Size 8pt", template.FontSize(8))
c.Text("Font Size 12pt (default)", template.FontSize(12))
c.Text("Font Size 24pt", template.FontSize(24))
c.Text("Font Size 36pt", template.FontSize(36))
// Weight and style
c.Text("Normal text")
c.Text("Bold text", template.Bold())
c.Text("Italic text", template.Italic())
c.Text("Bold + Italic text", template.Bold(), template.Italic())
// Colors
c.Text("Red text", template.TextColor(pdf.Red))
c.Text("Custom color", template.TextColor(pdf.RGB(1.0, 0.5, 0.0)))
c.Text("Hex color", template.TextColor(pdf.RGBHex(0x336699)))
// Background
c.Text("Yellow background", template.BgColor(pdf.Yellow))
c.Text("White on dark",
template.TextColor(pdf.White),
template.BgColor(pdf.RGBHex(0x333333)),
)
// Alignment
c.Text("Left aligned (default)", template.AlignLeft())
c.Text("Center aligned", template.AlignCenter())
c.Text("Right aligned", template.AlignRight())
})
})
┌─────────────────────────────────────────────┐
│ Font Size 8pt │ ← 小さいテキスト
│ Font Size 12pt (default) │
│ Font Size 24pt │ ← 大きいテキスト
│ Font Size 36pt │ ← とても大きいテキスト
│ │
│ Normal text │
│ Bold text │ ← 太字
│ Italic text │ ← イタリック
│ Bold + Italic text │ ← 両方
│ │
│ Red text │ ← カラー
│ Custom color │ ← RGB(1.0, 0.5, 0.0)
│ Hex color │ ← #336699
│ │
│ Yellow background │ ← ハイライト
│ White on dark │ ← 反転
│ │
│ Left aligned (default) │
│ Center aligned │
│ Right aligned │
└─────────────────────────────────────────────┘
2カラムレイアウト
12カラムグリッドを使って複数カラムのレイアウトを作成します:
page.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("Left column")
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("Right column")
})
})
┌──────────────────────┬──────────────────────┐
│ Left column │ Right column │
└──────────────────────┴──────────────────────┘
テーブル
ヘッダーとデータ行でテーブルを作成します:
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Table(
[]string{"Name", "Age", "City"},
[][]string{
{"Alice", "30", "Tokyo"},
{"Bob", "25", "New York"},
{"Charlie", "35", "London"},
{"Diana", "28", "Paris"},
},
)
})
})
┌─────────────────────────────────────────┐
│ Name │ Age │ City │ ← ヘッダー
├────────────┼───────┼────────────────────┤
│ Alice │ 30 │ Tokyo │
│ Bob │ 25 │ New York │
│ Charlie │ 35 │ London │
│ Diana │ 28 │ Paris │
└────────────┴───────┴────────────────────┘
スタイル付きテーブル
カスタムカラム幅、ヘッダースタイル、ストライプカラーを追加できます:
darkBlue := pdf.RGBHex(0x1A237E)
lightGray := pdf.RGBHex(0xF5F5F5)
c.Table(
[]string{"Product", "Category", "Qty", "Unit Price", "Total"},
[][]string{
{"Laptop Pro 15", "Electronics", "2", "$1,299.00", "$2,598.00"},
{"Wireless Mouse", "Accessories", "10", "$29.99", "$299.90"},
{"USB-C Hub", "Accessories", "5", "$49.99", "$249.95"},
},
template.ColumnWidths(30, 20, 10, 20, 20),
template.TableHeaderStyle(
template.TextColor(pdf.White),
template.BgColor(darkBlue),
),
template.TableStripe(lightGray),
)
┌─────────────────────────────────────────────────────────┐
│ Product │ Category │ Qty │ Unit Price │ Total │ ← ダークブルーに白文字
├───────────────┼─────────────┼─────┼────────────┼────────┤
│ Laptop Pro │ Electronics │ 2 │ $1,299.00 │$2,598 │ ← 白背景
│ Wireless.. │ Accessories │ 10 │ $29.99 │ $299 │ ← ライトグレーストライプ
│ USB-C Hub │ Accessories │ 5 │ $49.99 │ $249 │ ← 白背景
└───────────────┴─────────────┴─────┴────────────┴────────┘
罫線とスペーサー
// 水平罫線
c.Line()
c.Line(template.LineColor(pdf.Red), template.LineThickness(document.Pt(2)))
// 垂直スペース
c.Spacer(document.Mm(10))
出力
// Option 1: PDF を byte スライスとして取得
data, err := doc.Generate()
if err != nil {
log.Fatal(err)
}
os.WriteFile("output.pdf", data, 0644)
// Option 2: 任意の io.Writer に書き込み (http.ResponseWriter, file, buffer...)
err := doc.Render(w)
完全な例: 請求書
doc := template.New(
template.WithPageSize(document.A4),
template.WithMargins(document.UniformEdges(document.Mm(20))),
template.WithMetadata(document.DocumentMetadata{
Title: "Invoice #INV-2026-001",
Author: "ACME Corporation",
}),
)
page := doc.AddPage()
// Company header
page.AutoRow(func(r *template.RowBuilder) {
r.Col(6, func(c *template.ColBuilder) {
c.Text("ACME Corporation", template.FontSize(24), template.Bold(),
template.TextColor(pdf.RGBHex(0x1A237E)))
c.Text("123 Business Street")
c.Text("San Francisco, CA 94105")
})
r.Col(6, func(c *template.ColBuilder) {
c.Text("INVOICE", template.FontSize(28), template.Bold(),
template.AlignRight(), template.TextColor(pdf.RGBHex(0x1A237E)))
c.Text("#INV-2026-001", template.AlignRight(), template.FontSize(12))
c.Text("Date: March 1, 2026", template.AlignRight())
})
})
// Separator
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Spacer(document.Mm(5))
c.Line(template.LineColor(pdf.RGBHex(0x1A237E)), template.LineThickness(document.Pt(2)))
c.Spacer(document.Mm(5))
})
})
// Items table
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Table(
[]string{"Description", "Qty", "Unit Price", "Amount"},
[][]string{
{"Web Development - Frontend", "40 hrs", "$150.00", "$6,000.00"},
{"Web Development - Backend", "60 hrs", "$150.00", "$9,000.00"},
{"UI/UX Design", "20 hrs", "$120.00", "$2,400.00"},
},
template.ColumnWidths(40, 15, 20, 25),
template.TableHeaderStyle(
template.TextColor(pdf.White),
template.BgColor(pdf.RGBHex(0x1A237E)),
),
template.TableStripe(pdf.RGBHex(0xF5F5F5)),
)
})
})
// Total
page.AutoRow(func(r *template.RowBuilder) {
r.Col(8, func(c *template.ColBuilder) {})
r.Col(4, func(c *template.ColBuilder) {
c.Text("Total: $17,400.00", template.AlignRight(),
template.Bold(), template.FontSize(14))
})
})
data, _ := doc.Generate()
┌─ A4 ──────────────────────────────────────────────┐
│ │
│ ACME Corporation INVOICE │
│ 123 Business Street #INV-2026-001 │
│ San Francisco, CA 94105 Date: March 1, 2026 │
│ ─────────────────────────────────────────────── │
│ │
│ ┌─────────────┬────────┬───────────┬──────────┐ │
│ │ Description │ Qty │Unit Price │ Amount │ │
│ ├─────────────┼────────┼───────────┼──────────┤ │
│ │ Frontend │ 40 hrs │ $150.00 │$6,000.00 │ │
│ │ Backend │ 60 hrs │ $150.00 │$9,000.00 │ │
│ │ UI/UX │ 20 hrs │ $120.00 │$2,400.00 │ │
│ └─────────────┴────────┴───────────┴──────────┘ │
│ │
│ Total: $17,400.00 │
│ │
└───────────────────────────────────────────────────┘