Esquema JSON de plantillas
Estructura de una definición
Una definición de plantilla es un objeto con dos partes: page, que define la hoja, y elements, la lista ordenada que se dibuja sobre ella.
{
"page": {
"size": "A4",
"orientation": "portrait",
"margin": { "top": 48, "right": 48, "bottom": 48, "left": 48 }
},
"elements": [
{
"id": "invoice-title",
"type": "heading",
"placementMode": "flow",
"content": { "text": "Invoice" },
"layout": { "width": 100, "widthUnit": "percent", "height": 40 },
"style": { "fontSize": 24, "textStyle": "bold" }
}
]
}
Tamaños de página: A4 · A3 · Letter. La orientación es portrait o landscape y los márgenes se expresan en píxeles CSS a 96 por pulgada.
Qué campo admite cada elemento
Todos los elementos incluyen id, type, placementMode. El resto depende del tipo; la tabla siguiente se genera a partir de las mismas reglas que utiliza el validador, por lo que no puede quedarse desactualizada respecto al producto.
| type | Campos admitidos |
|---|---|
chart |
band · binding · chart · content · dataRules · layout · style |
container |
band · container · dataRules · layout |
dataset |
band · binding · dataRules · layout · style |
footer |
band · binding · content · dataRules · layout · style |
header |
band · binding · content · dataRules · layout · style |
heading |
band · binding · content · dataRules · layout · style |
image |
band · binding · content · dataRules · layout · style |
pagebreak |
band · dataRules |
pagenumber |
band · content · dataRules · layout · style |
table |
band · binding · columns · content · dataRules · layout · style · summaryRows |
text |
band · binding · content · dataRules · layout · style |
Un campo que no aparece en la fila de su tipo falla en la validación en lugar de ignorarse. Descartarlo silenciosamente sería peor: el documento saldría incompleto aunque la solicitud pareciera correcta.
placementMode
Cómo encuentra un elemento su posición en la hoja. El modo también determina si se leen layout.x y layout.y.
flow— apilados uno tras otro hacia abajo en la página; se ignoran x e y, y el elemento crece con su contenidofree— colocado en layout.x y layout.y, exactamente donde lo sitúesband— repetido en cada página en la franja indicada por el elemento, como un encabezado o pie de página
El elemento dataset
Un dataset imprime una colección que no es una tabla: una lista de visitas, fotografías o firmas, dibujada con el diseño indicado en la plantilla en lugar de en columnas.
{
"id": "maintenance-visits",
"type": "dataset",
"placementMode": "flow",
"binding": "visits",
"layout": { "width": 100, "widthUnit": "percent", "height": 160 },
"style": { "fontSize": 11 },
"dataRules": { "required": true }
}
binding indica el array de tus datos, igual que en una tabla. Lo que dibuja el elemento para cada registro depende del diseño y el estilo, por lo que una misma colección puede ser una tabla en una plantilla y un dataset en otra.
Un dataset no tiene campo content. Solo se alimenta mediante binding; el texto que antes se escribía en content nunca llegaba a la salida, por lo que se eliminó el campo en lugar de conservar un lugar donde escribir no producía ningún efecto.
Comprobar tus datos antes de renderizar
El endpoint de validación responde a la misma pregunta que una renderización, sin consumir cuota: ¿cumplen estos datos los requisitos de la plantilla?
curl -X POST https://api.pdfgine.com/api/v1/templates/invoice/validate-data \
-H "X-PDFgine-Key: $PDFGINE_KEY" \
-H "Content-Type: application/json" \
-d '{ "data": { "referenceNo": "DOC-2026-0042", "currency": "USD" } }'
Los errores más habituales
- Un campo que no pertenece al tipo de su elemento falla en la validación en lugar de ignorarse. Es intencionado: descartarlo silenciosamente produciría un documento incompleto y nadie buscaría lo que no aparece.
- En posicionamiento flow no se leen layout.x ni layout.y. Configurarlos y preguntarse por qué no se mueve nada es la duda de esquema más frecuente.
- Un dataset no tiene campo content; solo se alimenta mediante binding. El texto incluido en content nunca llega a la salida.
- Los márgenes y tamaños se expresan en píxeles CSS a 96 por pulgada, no en milímetros. Un 20 pensado como milímetros saldrá unas tres veces más pequeño.
- Renderizar para comprobar si los datos encajan consume una página. El endpoint de validación responde a la misma pregunta sin coste.