Definição do relatório#
Todo relatório Sulfite é um JSON com esta estrutura:
{
"reportId": "string",
"reportName": "string",
"version": "string",
"pageSettings": { ... },
"dataSources": [ ... ],
"bands": [ ... ]
}
Campos#
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
reportId |
string |
Sim | Identificador único do relatório |
reportName |
string |
Sim | Nome legível |
version |
string |
Não | Versão do relatório (ex: "1.0") |
pageSettings |
object |
Sim | Formato da página, margens, orientação |
dataSources |
array |
Sim | Fontes de dados esperadas |
bands |
array |
Sim | Faixas horizontais que compõem o layout |
parameters |
array |
Não | Parâmetros interativos preenchidos antes da impressão (ver Filtros) |
scripts |
array |
Não | Scripts executados em hooks do ciclo de vida (afterQuery, beforeRender) |
metadata |
object |
Não | Dados extras livres |
processingMode |
string |
Não | "strict" (padrão) ou "resilient" |
pageSettings#
{
"format": "A4",
"width": 595.28,
"height": 841.89,
"unit": "pt",
"orientation": "portrait",
"margins": {
"left": 40,
"right": 40,
"top": 40,
"bottom": 40
}
}
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
format |
string |
"A4" |
Nome do formato (
A3
,
A4
,
A5
,
Carta
,
Legal
)
|
width |
double |
595.28 |
Largura em pontos |
height |
double |
841.89 |
Altura em pontos |
unit |
string |
"pt" |
Unidade de medida |
orientation |
string |
"portrait" |
"portrait" ou "landscape" |
margins |
object |
— | Margens (left, right, top, bottom) |
labelConfig |
object |
null |
Configuração para modo etiqueta (ver Etiquetas) |
Formatos comuns#
| Formato | Largura (pt) | Altura (pt) |
|---|---|---|
| A3 | 841.89 | 1190.55 |
| A4 | 595.28 | 841.89 |
| A5 | 419.53 | 595.28 |
| Carta | 612.00 | 792.00 |
| Legal | 612.00 | 1008.00 |
Modo de processamento#
-
strict(padrão): erros de binding, data source não encontrado ou tipo inválido interrompem o processamento. -
resilient: registra erros emProcessedData.errorse continua com valores de fallback.
{
"processingMode": "resilient"
}
Scripts#
O campo scripts declara handlers de ciclo de vida executados pelo AdvancedScriptEngine. Cada script é identificado por um
id e disparado em um dos dois hooks disponíveis:
| Hook | Quando executa |
|---|---|
afterQuery |
Logo após o
DataProcessor
carregar os dados, antes de renderizar. Use para filtrar, enriquecer ou transformar registros.
|
beforeRender |
Após o processamento, antes de montar o PDF/HTML. Use para ajustar visibilidade de bands e elementos com base em regras de negócio. |
{
"scripts": [
{
"id": "mask_custo",
"hook": "afterQuery",
"description": "Remove coluna de custo se usuário não tiver permissão"
},
{
"id": "hide_empty_section",
"hook": "beforeRender",
"description": "Oculta band de detalhes quando não há registros"
}
]
}
Os handlers são registrados em Dart via AdvancedScriptEngine.register() e associados ao relatório pelo
id:
final engine = AdvancedScriptEngine(
externalContext: {'permissions': userPermissions},
);
engine.register('mask_custo', (ctx) {
final podeVerCusto = ctx.context('permissions').contains('financeiro');
if (!podeVerCusto) {
ctx.setElementVisible('col_custo', false);
}
});
engine.register('hide_empty_section', (ctx) {
final rows = ctx.datasource('vendas');
ctx.setBandVisible('band_detalhe', rows.isNotEmpty);
});
final pdfBytes = await engine.generate(
report,
dataPayload: payload,
format: 'pdf',
);
ScriptContext — API disponível#
| Método | Descrição |
|---|---|
datasource(id) | Retorna os registros atuais de um data source |
setDatasource(id, rows) | Substitui todos os registros de um data source |
addRow(id, row) | Adiciona um registro |
removeRow(id, predicate) | Remove registros que satisfaçam a condição |
setBandVisible(id, visible) | Mostra ou oculta uma band |
setElementVisible(id, visible) | Mostra ou oculta um elemento |
setElementProperty(id, prop, value) | Altera propriedade de um elemento |
param(id) | Lê o valor de um parâmetro |
setParam(id, value) | Define o valor de um parâmetro |
context(key) | Acessa o externalContext injetado no engine |
query(sql, params) | Executa SQL via SqlBridge (opcional) |
cancel() | Aborta a geração do relatório |
log(msg) | Log de diagnóstico |
Para condicionais simples sem estado, use os campos inline dos elementos:
printWhen em qualquer elemento ou band: expressão booleana que controla visibilidade.
valueExpression em FieldElement: expressão calculada no contexto do row atual.
Prefira scripts quando a lógica precisar de acesso a parâmetros externos, múltiplos data sources ou estado acumulado.
Exemplo completo#
Um relatório de vendas com header, 50 linhas de detalhe, agregados no summary e rodapé com paginação:
{
"reportId": "sales_report",
"reportName": "Relatório de Vendas",
"version": "2.0",
"pageSettings": {
"format": "A4",
"orientation": "portrait",
"margins": { "left": 30, "right": 30, "top": 30, "bottom": 30 }
},
"dataSources": [
{
"id": "sales",
"type": "list",
"schema": {
"order_id": "string",
"customer": "string",
"amount": "number",
"date": "string"
}
}
],
"bands": [
{
"type": "header", "id": "hdr", "height": 60,
"elements": [
{ "type": "text", "id": "t1", "x": 30, "y": 20, "content": "Relatório de Vendas", "fontSize": 24, "bold": true }
]
},
{
"type": "detail", "id": "det", "dataSourceId": "sales", "height": 25,
"elements": [
{ "type": "field", "id": "f1", "x": 30, "y": 5, "width": 80, "binding": "order_id" },
{ "type": "field", "id": "f2", "x": 120, "y": 5, "width": 200, "binding": "customer" },
{ "type": "field", "id": "f3", "x": 330, "y": 5, "width": 100, "binding": "amount", "format": "currency:BRL" },
{ "type": "field", "id": "f4", "x": 440, "y": 5, "width": 100, "binding": "date", "format": "date:dd/MM/yyyy" }
]
},
{
"type": "summary", "id": "sum", "height": 40,
"elements": [
{ "type": "aggregate", "id": "total", "x": 330, "y": 10, "width": 100, "verb": "SUM", "dataSourceId": "sales", "targetKey": "amount", "format": "currency:BRL", "bold": true }
]
},
{
"type": "footer", "id": "ftr", "height": 30,
"elements": [
{ "type": "text", "id": "pg", "x": 250, "y": 10, "content": "Página {page} de {totalPages}", "fontSize": 9, "color": "999999" }
]
}
]
}