Esquema JSON de modelos
Estrutura de uma definição
Uma definição de modelo é um objeto com duas partes: page, que define a folha, e elements, a lista ordenada desenhada nela.
{
"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" }
}
]
}
Tamanhos de página: A4 · A3 · Letter. A orientação é portrait ou landscape, e as margens são em pixels CSS a 96 por polegada.
Quais campos cada elemento aceita
Todo elemento contém id, type, placementMode. O restante depende do tipo, e a tabela abaixo é gerada a partir das mesmas regras usadas pelo validador, portanto não fica desatualizada em relação ao produto.
| type | Campos aceitos |
|---|---|
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 |
Um campo que não está na linha do seu tipo falha na validação em vez de ser ignorado. Descartá-lo silenciosamente seria pior: o documento sairia incompleto, embora a solicitação parecesse bem-sucedida.
placementMode
Como um elemento encontra sua posição na folha. O modo também determina se layout.x e layout.y serão lidos.
flow— empilhados um após o outro na página; x e y são ignorados e o elemento cresce com seu conteúdofree— posicionado em layout.x e layout.y, exatamente onde você o colocarband— repetido em todas as páginas na faixa indicada pelo elemento, como cabeçalho ou rodapé
O elemento dataset
Um dataset imprime uma coleção que não é uma tabela: uma lista de visitas, fotografias ou assinaturas, desenhada com o layout definido pelo modelo em vez de colunas.
{
"id": "maintenance-visits",
"type": "dataset",
"placementMode": "flow",
"binding": "visits",
"layout": { "width": 100, "widthUnit": "percent", "height": 160 },
"style": { "fontSize": 11 },
"dataRules": { "required": true }
}
binding indica o array nos seus dados, exatamente como em uma tabela. O que o elemento desenha para cada item vem do layout e do estilo; assim, a mesma coleção pode ser tabela em um modelo e dataset em outro.
Um dataset não tem campo content. Ele recebe dados apenas por binding; o texto que antes ficava em content nunca chegava à saída, por isso o campo foi removido em vez de permanecer como um local onde escrever não teria efeito.
Verificar seus dados antes de renderizar
O endpoint de validação responde à mesma pergunta que uma renderização, sem gastar cota: estes dados atendem ao que o modelo exige?
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" } }'
Os problemas mais comuns
- Um campo que não pertence ao tipo do elemento falha na validação em vez de ser ignorado. Isso é intencional: descartar um campo silenciosamente gera um documento incompleto, e ninguém procura o que não está lá.
- No posicionamento flow, layout.x e layout.y não são lidos. Defini-los e se perguntar por que nada se moveu é a dúvida de esquema mais comum.
- Um dataset não tem campo content; recebe dados apenas por binding. Texto em content nunca chega à saída.
- Margens e tamanhos são em pixels CSS a 96 por polegada, não milímetros. Um 20 pensado em milímetros sai cerca de três vezes menor.
- Renderizar para verificar se os dados servem custa uma página. O endpoint de validação responde à mesma pergunta sem custo.