Guia do produto e da API

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.

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

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údo
  • free — posicionado em layout.x e layout.y, exatamente onde você o colocar
  • band — 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.

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 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
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 dados →

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.