Guía del producto y de la API

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.

JSON
{
  "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 contenido
  • free — colocado en layout.x y layout.y, exactamente donde lo sitúes
  • band — 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.

JSON
{
  "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
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" } }'
Formatos de datos →

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.