JSONスキーマ

概要

gpdfはドキュメント全体をJSONで定義することをサポートしています。以下のケースに最適です:

  • API駆動のPDF生成
  • 外部データからの動的ドキュメント
  • Goコードを使わないテンプレートシステム
  • 設定ベースのドキュメント作成

基本的な使い方

schema := []byte(`{
    "page": {"size": "A4", "margins": "20mm"},
    "body": [
        {"row": {"cols": [
            {"span": 12, "text": "Hello from JSON!", "style": {"size": 24, "bold": true}}
        ]}}
    ]
}`)

doc, err := template.FromJSON(schema, nil)
if err != nil {
    log.Fatal(err)
}
data, err := doc.Generate()
┌─ A4 ──────────────────────────────────┐
│                                       │
│   Hello from JSON!   ← 24pt, Bold    │
│                                       │
└───────────────────────────────────────┘

Goテンプレートによるデータバインディング

JSONスキーマは動的コンテンツのためにGoテンプレート式をサポートしています:

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}}"}
        ]}}
    ]
}`)

data := map[string]any{
    "Title":  "Quarterly Report",
    "Author": "ACME Corporation",
}

doc, err := template.FromJSON(schema, data)

スキーマ構造

{
    "page": {
        "size": "A4",
        "margins": "20mm"
    },
    "metadata": {
        "title": "Document Title",
        "author": "Author Name",
        "subject": "Subject",
        "creator": "Creator"
    },
    "header": [ /* rows */ ],
    "footer": [ /* rows */ ],
    "body": [ /* rows */ ]
}

ページ設定

フィールドデフォルト
size"A4", "A3", "Letter", "Legal""A4"
margins寸法文字列: "20mm", "1in", "15pt"

行とカラム

{"row": {"cols": [
    {"span": 6, "text": "Left column"},
    {"span": 6, "text": "Right column"}
]}}

完全な例

schema := []byte(`{
    "page": {"size": "A4", "margins": "20mm"},
    "metadata": {"title": "JSON Schema Example", "author": "gpdf"},
    "header": [
        {"row": {"cols": [
            {"span": 6, "text": "gpdf JSON Schema", "style": {"size": 16, "bold": true, "color": "#1A237E"}},
            {"span": 6, "text": "Document Header", "style": {"align": "right", "italic": true}}
        ]}},
        {"row": {"cols": [
            {"span": 12, "line": {"color": "#1A237E", "thickness": "1pt"}}
        ]}}
    ],
    "footer": [
        {"row": {"cols": [
            {"span": 12, "elements": [
                {"type": "line"},
                {"type": "pageNumber", "style": {"align": "center"}}
            ]}
        ]}}
    ],
    "body": [
        {"row": {"cols": [
            {"span": 12, "text": "JSON Schema Generation", "style": {"size": 24, "bold": true}}
        ]}},
        {"row": {"cols": [
            {"span": 12, "spacer": "5mm"}
        ]}},
        {"row": {"cols": [
            {"span": 12, "text": "This PDF was generated from a JSON schema. No Go builder code needed!"}
        ]}},
        {"row": {"cols": [
            {"span": 12, "spacer": "10mm"}
        ]}},
        {"row": {"cols": [
            {"span": 6, "elements": [
                {"type": "text", "content": "Features", "style": {"size": 16, "bold": true}},
                {"type": "list", "list": {"items": [
                    "Declarative document definition",
                    "All element types supported",
                    "Style options",
                    "Header and footer support"
                ]}}
            ]},
            {"span": 6, "elements": [
                {"type": "text", "content": "Supported Elements", "style": {"size": 16, "bold": true}},
                {"type": "list", "list": {"type": "ordered", "items": [
                    "Text with styles",
                    "Tables with headers",
                    "Lists (ordered/unordered)",
                    "Lines and spacers",
                    "QR codes and barcodes",
                    "Images (base64)"
                ]}}
            ]}
        ]}},
        {"row": {"cols": [
            {"span": 12, "spacer": "10mm"}
        ]}},
        {"row": {"cols": [
            {"span": 12, "table": {
                "header": ["Feature", "Format", "Status"],
                "rows": [
                    ["Text styling", "JSON style object", "Supported"],
                    ["Tables", "header + rows arrays", "Supported"],
                    ["Lists", "ordered/unordered", "Supported"],
                    ["Images", "base64 encoded", "Supported"],
                    ["QR codes", "data string", "Supported"],
                    ["Barcodes", "Code128", "Supported"]
                ],
                "columnWidths": [35, 35, 30],
                "headerStyle": {"bold": true, "color": "white", "background": "#1A237E"},
                "stripeColor": "#F5F5F5"
            }}
        ]}},
        {"row": {"cols": [
            {"span": 12, "spacer": "10mm"}
        ]}},
        {"row": {"cols": [
            {"span": 6, "qrcode": {"data": "https://gpdf.dev", "size": "25mm"}},
            {"span": 6, "barcode": {"data": "GPDF-JSON-001", "format": "code128"}}
        ]}}
    ]
}`)

doc, err := template.FromJSON(schema, nil)
┌─ A4 ──────────────────────────────────────────────┐
│  gpdf JSON Schema              Document Header    │  ← header
│  ──────────────────────────────────────────────── │
│                                                   │
│  JSON Schema Generation           ← 24pt bold     │
│                                                   │
│  This PDF was generated from a JSON schema.       │
│                                                   │
│  Features              Supported Elements         │
│  • Declarative...      1. Text with styles        │
│  • All element...      2. Tables with headers     │
│  • Style options       3. Lists                   │
│  • Header/footer       4. Lines and spacers       │
│                        5. QR codes and barcodes    │
│                        6. Images (base64)          │
│                                                   │
│  ┌──────────┬──────────────────┬──────────┐       │
│  │ Feature  │ Format           │ Status   │       │
│  ├──────────┼──────────────────┼──────────┤       │
│  │ Text     │ JSON style obj   │Supported │       │
│  │ Tables   │ header + rows    │Supported │       │
│  │ ...      │ ...              │ ...      │       │
│  └──────────┴──────────────────┴──────────┘       │
│                                                   │
│  ┌────┐        ║║│║║│║║║│║║│                      │
│  │ QR │        GPDF-JSON-001                      │
│  └────┘                                           │
│                                                   │
│  ──────────────────────────────────────────────── │
│                    Page 1                         │  ← footer
└───────────────────────────────────────────────────┘

JSONの要素タイプ

カラムの省略記法

単一要素の場合、カラムに直接省略記法を使用できます:

{"span": 12, "text": "Hello", "style": {"bold": true}}
{"span": 12, "spacer": "10mm"}
{"span": 12, "line": {"color": "#FF0000"}}

elements配列

1つのカラムに複数の要素を配置する場合は elements 配列を使用します:

{"span": 12, "elements": [
    {"type": "text", "content": "Title", "style": {"size": 18, "bold": true}},
    {"type": "spacer", "height": "5mm"},
    {"type": "text", "content": "Body text"},
    {"type": "line"},
    {"type": "pageNumber", "style": {"align": "center"}}
]}

スタイルオブジェクト

{
    "size": 16,
    "bold": true,
    "italic": true,
    "color": "#1A237E",
    "background": "#F5F5F5",
    "align": "center",
    "font": "NotoSansJP"
}
フィールド説明
sizenumberフォントサイズ(ポイント単位)
boldboolean太字
italicbooleanイタリック体
colorstringテキスト色("#RRGGBB", "red", "blue" など)
backgroundstring背景色
alignstring"left", "center", "right"
fontstringフォントファミリー名

テーブルオブジェクト

{
    "header": ["Col A", "Col B", "Col C"],
    "rows": [
        ["A1", "B1", "C1"],
        ["A2", "B2", "C2"]
    ],
    "columnWidths": [40, 30, 30],
    "columnAlign": ["left", "right", "right"],
    "headerStyle": {"bold": true, "color": "white", "background": "#1A237E"},
    "stripeColor": "#F5F5F5",
    "border":     {"width": "1pt",   "color": "#1A237E"},
    "cellBorder": {"width": "0.5pt", "color": "gray(0.5)", "style": "dashed"},
    "borderCollapse": true,
    "background": "#FAFAFA"
}

Since v1.0.10 columnAlign は列ごとの水平方向アラインメント("left" / "center" / "right")を指定し、ヘッダー・本文の両方に適用されます。指定がない列はデフォルトの左寄せにフォールバックします。

Since v1.0.7 border は外枠を、cellBorder はヘッダー・本文すべてのセルに同じボーダー(グリッド線)を描画します。borderCollapse は隣接セルのボーダーを統合し、background はテーブルの外枠ボックスを塗りつぶします。border / cellBorder の構造は ボーダーオブジェクト を参照してください。

画像オブジェクト

{"span": 6, "image": {
    "src": "data:image/png;base64,...",
    "width": "60mm",
    "minWidth": "40mm",
    "border":     {"widths": ["2pt", "2pt", "2pt", "2pt"], "color": "#E53935"},
    "background": "#FFF8E1"
}}
フィールド説明
srcbase64 / data URI / ファイルパス
width / height表示寸法
minWidth / minHeight Since v1.0.6 この値未満に縮小される場合は次ページへオーバーフロー
fit"contain"(デフォルト), "cover", "stretch", "original"
align"left", "center", "right"
border Since v1.0.7 画像周囲のボーダー(ボーダーオブジェクト 参照)
background Since v1.0.7 画像背後の塗りつぶし色(透過 PNG に有効)

ボーダーオブジェクト

Since v1.0.7

table.bordertable.cellBorderimage.border で使用します:

{
    "width": "1pt",
    "color": "#1A237E",
    "style": "solid"
}

CSS 順(top, right, bottom, left)で辺ごとに幅を指定する場合は width の代わりに widths を使います:

{"widths": ["2pt", "1pt", "2pt", "1pt"], "color": "#1A237E", "style": "dashed"}
フィールド説明
widthstring4 辺均一の幅(例 "1pt", "0.5mm"
widths4 要素の string 配列辺ごとの幅 [top, right, bottom, left]width より優先)
colorstringボーダー色("#RRGGBB"・名前付き・"gray(0.5)"
stylestring"solid"(デフォルト), "dashed", "dotted", "none"

リストオブジェクト

{"type": "list", "list": {"items": ["Item 1", "Item 2", "Item 3"]}}
{"type": "list", "list": {"type": "ordered", "items": ["First", "Second", "Third"]}}

QRコードオブジェクト

{"span": 6, "qrcode": {"data": "https://gpdf.dev", "size": "25mm", "minSize": "20mm"}}

Since v1.0.6 minSize を指定すると、残り空間が小さい場合に QR コードを縮小せず次のページへ送ります。

バーコードオブジェクト

{"span": 6, "barcode": {"data": "INV-001", "format": "code128"}}

絶対位置指定

通常のグリッドフローの外側で、要素を正確なXY座標に配置します:

{
    "absolute": [
        {
            "x": "120mm",
            "y": "20mm",
            "elements": [
                {"type": "text", "content": "CONFIDENTIAL", "style": {"size": 20, "bold": true, "color": "red"}}
            ]
        },
        {
            "x": "10mm",
            "y": "250mm",
            "width": "25mm",
            "height": "25mm",
            "elements": [
                {"type": "qrcode", "qrcode": {"data": "https://gpdf.dev", "size": "20mm"}}
            ]
        },
        {
            "x": "0mm",
            "y": "0mm",
            "origin": "page",
            "elements": [
                {"type": "text", "content": "Page origin"}
            ]
        }
    ]
}

absolute 配列はトップレベル(すべてのページに適用)または個別のページ定義内に配置できます。

フィールド必須説明
xstringはいX座標(寸法文字列)
ystringはいY座標(寸法文字列)
widthstringいいえ明示的な幅(デフォルト: 残りスペース)
heightstringいいえ明示的な高さ(デフォルト: 残りスペース)
originstringいいえ"content"(デフォルト)または "page"
elementsarrayはい要素オブジェクトの配列

寸法文字列

フォーマット
ミリメートル"20mm"
ポイント"12pt"
センチメートル"2.5cm"
インチ"1in"

名前付きカラー

JSONスキーマは名前付きカラーをサポートしています: "red", "green", "blue", "yellow", "cyan", "magenta", "black", "white", "gray"

または16進数フォーマット: "#FF6B6B", "#1A237E"

Goオプションとの組み合わせ

Goオプションでスキーマをオーバーライドまたは拡張できます:

fontData, _ := os.ReadFile("fonts/NotoSansJP-Regular.ttf")

doc, err := template.FromJSON(schema, data,
    template.WithFont("NotoSansJP", fontData),
    template.WithDefaultFont("NotoSansJP", 12),
)