JSON Schema

Visao Geral

gpdf suporta a definicao de documentos inteiramente em JSON. Isso e ideal para:

  • Geracao de PDF orientada por API
  • Documentos dinamicos a partir de dados externos
  • Sistemas de templates sem codigo Go
  • Criacao de documentos baseada em configuracao

Uso Basico

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    │
│                                       │
└───────────────────────────────────────┘

Vinculacao de Dados com Go Templates

JSON schemas suportam expressoes Go template para conteudo dinamico:

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)

Estrutura do Schema

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

Configuracao de Pagina

CampoValoresPadrao
size"A4", "A3", "Letter", "Legal""A4"
marginsString de dimensao: "20mm", "1in", "15pt"

Linhas e Colunas

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

Exemplo Completo

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    │  ← cabecalho
│  ──────────────────────────────────────────────── │
│                                                   │
│  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                         │  ← rodape
└───────────────────────────────────────────────────┘

Tipos de Elementos em JSON

Atalho de Coluna

Para elementos unicos, use o atalho diretamente na coluna:

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

Array de Elementos

Para multiplos elementos em uma coluna, use o array 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"}}
]}

Objeto Style

{
    "size": 16,
    "bold": true,
    "italic": true,
    "color": "#1A237E",
    "background": "#F5F5F5",
    "align": "center",
    "font": "NotoSansJP"
}
CampoTipoDescricao
sizenumberTamanho da fonte em pontos
boldbooleanPeso negrito
italicbooleanEstilo italico
colorstringCor do texto ("#RRGGBB", "red", "blue", etc.)
backgroundstringCor de fundo
alignstring"left", "center", "right"
fontstringNome da familia de fonte

Objeto Table

{
    "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 define o alinhamento horizontal por coluna ("left" / "center" / "right") e se aplica ao cabecalho e ao corpo. Colunas sem entrada usam o alinhamento a esquerda padrao.

Since v1.0.7 border desenha uma moldura externa, cellBorder adiciona a mesma borda ao redor de cada celula de cabecalho + corpo (linhas de grade), borderCollapse colapsa bordas de celulas adjacentes e background preenche a caixa externa da tabela. A estrutura de border / cellBorder esta descrita em Objeto Border.

Objeto Image

{"span": 6, "image": {
    "src": "data:image/png;base64,...",
    "width": "60mm",
    "minWidth": "40mm",
    "border":     {"widths": ["2pt", "2pt", "2pt", "2pt"], "color": "#E53935"},
    "background": "#FFF8E1"
}}
CampoDescricao
srcbase64 / data URI / caminho de arquivo
width / heightDimensao de exibicao
minWidth / minHeight Since v1.0.6 Transborda para a proxima pagina quando seria necessario reduzir abaixo deste valor
fit"contain" (padrao), "cover", "stretch", "original"
align"left", "center", "right"
border Since v1.0.7 Borda ao redor da imagem (ver Objeto Border)
background Since v1.0.7 Cor de fundo atras da imagem (util para PNG transparente)

Objeto Border

Since v1.0.7

Usado por table.border, table.cellBorder e image.border:

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

Para larguras por lado em ordem CSS (top, right, bottom, left), use widths em vez de width:

{"widths": ["2pt", "1pt", "2pt", "1pt"], "color": "#1A237E", "style": "dashed"}
CampoTipoDescricao
widthstringLargura uniforme dos lados (ex. "1pt", "0.5mm")
widthsarray de 4 stringsLarguras por lado [top, right, bottom, left] (vence sobre width)
colorstringCor da borda ("#RRGGBB", nomeado ou "gray(0.5)")
stylestring"solid" (padrao), "dashed", "dotted", "none"

Objeto List

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

Objeto QR Code

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

Since v1.0.6 Com minSize, o QR code transborda para a proxima pagina em vez de encolher abaixo do valor informado quando o espaco restante e insuficiente.

Objeto Barcode

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

Posicionamento Absoluto

Posicione elementos em coordenadas XY exatas, fora do fluxo normal do grid:

{
    "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"}
            ]
        }
    ]
}

O array absolute pode aparecer no nivel superior (aplica-se a todas as paginas) ou dentro de definicoes de paginas individuais.

CampoTipoObrigatorioDescricao
xstringSimCoordenada X (string de dimensao)
ystringSimCoordenada Y (string de dimensao)
widthstringNaoLargura explicita (padrao: espaco restante)
heightstringNaoAltura explicita (padrao: espaco restante)
originstringNao"content" (padrao) ou "page"
elementsarraySimArray de objetos de elementos

Strings de Dimensao

FormatoExemplo
Milimetros"20mm"
Pontos"12pt"
Centimetros"2.5cm"
Polegadas"1in"

Cores Nomeadas

JSON schemas suportam cores nomeadas: "red", "green", "blue", "yellow", "cyan", "magenta", "black", "white", "gray".

Ou use o formato hexadecimal: "#FF6B6B", "#1A237E".

Combinando com Opcoes Go

Sobrescreva ou estenda JSON schemas com opcoes Go:

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

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