Esquema JSON

Descripcion general

gpdf soporta la definicion de documentos completamente en JSON. Esto es ideal para:

  • Generacion de PDF impulsada por API
  • Documentos dinamicos a partir de datos externos
  • Sistemas de plantillas sin codigo Go
  • Creacion de documentos basada en configuracion

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

Enlace de datos con Go Templates

Los esquemas JSON soportan expresiones de Go template para contenido 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)

Estructura del esquema

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

Configuracion de pagina

CampoValoresPredeterminado
size"A4", "A3", "Letter", "Legal""A4"
marginsCadena de dimension: "20mm", "1in", "15pt"

Filas y columnas

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

Ejemplo 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    │  ← encabezado
│  ──────────────────────────────────────────────── │
│                                                   │
│  JSON Schema Generation           ← 24pt negrita  │
│                                                   │
│  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                         │  ← pie de pagina
└───────────────────────────────────────────────────┘

Tipos de elementos en JSON

Abreviatura de columna

Para elementos individuales, use la abreviatura directamente en la columna:

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

Array de elementos

Para multiples elementos en una columna, use el 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 de estilo

{
    "size": 16,
    "bold": true,
    "italic": true,
    "color": "#1A237E",
    "background": "#F5F5F5",
    "align": "center",
    "font": "NotoSansJP"
}
CampoTipoDescripcion
sizenumberTamano de fuente en puntos
boldbooleanPeso negrita
italicbooleanEstilo cursiva
colorstringColor de texto ("#RRGGBB", "red", "blue", etc.)
backgroundstringColor de fondo
alignstring"left", "center", "right"
fontstringNombre de familia de fuente

Objeto de tabla

{
    "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 la alineacion horizontal por columna ("left" / "center" / "right") y se aplica al encabezado y al cuerpo. Las columnas sin entrada usan la alineacion izquierda por defecto.

Since v1.0.7 border dibuja un marco exterior, cellBorder anade el mismo borde alrededor de cada celda de cabecera + cuerpo (lineas de rejilla), borderCollapse colapsa bordes de celdas adyacentes y background rellena la caja exterior de la tabla. La estructura de border / cellBorder esta descrita en Objeto de borde.

Objeto de imagen

{"span": 6, "image": {
    "src": "data:image/png;base64,...",
    "width": "60mm",
    "minWidth": "40mm",
    "border":     {"widths": ["2pt", "2pt", "2pt", "2pt"], "color": "#E53935"},
    "background": "#FFF8E1"
}}
CampoDescripcion
srcbase64 / data URI / ruta de archivo
width / heightDimension de visualizacion
minWidth / minHeight Since v1.0.6 Desborda a la siguiente pagina cuando se requeriria reducirla por debajo
fit"contain" (por defecto), "cover", "stretch", "original"
align"left", "center", "right"
border Since v1.0.7 Borde alrededor de la imagen (ver Objeto de borde)
background Since v1.0.7 Color de fondo detras de la imagen (util para PNG transparentes)

Objeto de borde

Since v1.0.7

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

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

Para anchos por lado en orden CSS (top, right, bottom, left), usa widths en lugar de width:

{"widths": ["2pt", "1pt", "2pt", "1pt"], "color": "#1A237E", "style": "dashed"}
CampoTipoDescripcion
widthstringAncho uniforme de los lados (ej. "1pt", "0.5mm")
widthsarray de 4 stringsAnchos por lado [top, right, bottom, left] (gana sobre width)
colorstringColor del borde ("#RRGGBB", nombrado o "gray(0.5)")
stylestring"solid" (por defecto), "dashed", "dotted", "none"

Objeto de lista

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

Objeto de codigo QR

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

Since v1.0.6 Con minSize, el codigo QR se mueve a la siguiente pagina en lugar de reducirse por debajo del valor dado cuando el espacio restante es insuficiente.

Objeto de codigo de barras

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

Posicionamiento absoluto

Coloque elementos en coordenadas XY exactas, fuera del flujo normal de la cuadricula:

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

El array absolute puede aparecer en el nivel superior (se aplica a todas las paginas) o dentro de definiciones de paginas individuales.

CampoTipoRequeridoDescripcion
xstringSiCoordenada X (cadena de dimension)
ystringSiCoordenada Y (cadena de dimension)
widthstringNoAncho explicito (predeterminado: espacio restante)
heightstringNoAlto explicito (predeterminado: espacio restante)
originstringNo"content" (predeterminado) o "page"
elementsarraySiArray de objetos de elementos

Cadenas de dimension

FormatoEjemplo
Milimetros"20mm"
Puntos"12pt"
Centimetros"2.5cm"
Pulgadas"1in"

Colores con nombre

Los esquemas JSON soportan colores con nombre: "red", "green", "blue", "yellow", "cyan", "magenta", "black", "white", "gray".

O use formato hexadecimal: "#FF6B6B", "#1A237E".

Combinacion con opciones de Go

Sobrescriba o extienda esquemas JSON con opciones de Go:

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

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