PDF
O renderer padrão. Gera PDF multi-página com posicionamento absoluto, fontes customizáveis e suporte a etiquetas.
Uso
final engine = SulfiteEngineImpl();
final report = await engine.parseReport(reportJson);
final context = await engine.processData(report, payload);
// Em memória
final pdfBytes = await engine.renderToPdf(context);
// Direto para arquivo
await engine.renderToPdfFile(context, 'output.pdf');Como funciona
O PDF renderer usa package:pdf com pw.MultiPage. Cada band vira um container com altura fixa e elementos posicionados via pw.Stack + pw.Positioned(left: x, top: y).
┌─ pw.MultiPage ───────────────────────────┐
│ ┌─ Header ─────────────────────────────┐ │ ← repete em toda página
│ │ pw.Stack [pw.Positioned(x,y)...] │ │
│ └──────────────────────────────────────┘ │
│ ┌─ Detail (row 1) ────────────────────┐ │ ← uma por registro
│ │ pw.Stack [pw.Positioned(x,y)...] │ │
│ └──────────────────────────────────────┘ │
│ ┌─ Detail (row 2) ────────────────────┐ │
│ │ ... │ │
│ └──────────────────────────────────────┘ │
│ ┌─ Summary ───────────────────────────┐ │ ← uma vez
│ │ pw.Stack [pw.Positioned(x,y)...] │ │
│ └──────────────────────────────────────┘ │
│ ┌─ Footer ─────────────────────────────┐ │ ← repete em toda página
│ │ pw.Stack [pw.Positioned(x,y)...] │ │
│ └──────────────────────────────────────┘ │
└──────────────────────────────────────────┘Page Settings
O formato da página é definido no pageSettings do relatório:
{
"pageSettings": {
"format": "A4",
"orientation": "portrait",
"margins": { "left": 40, "right": 40, "top": 40, "bottom": 40 }
}
}Orientação "landscape" inverte largura e altura automaticamente.
Paginação
Header e Footer repetem automaticamente em cada página. Use {page} e {totalPages} em elementos Text e Field:
{ "type": "text", "id": "pg", "x": 250, "y": 10, "content": "Página {page} de {totalPages}" }Quebra de página
Qualquer band pode forçar uma nova página com forcePageBreakBefore:
{ "type": "summary", "id": "sum", "height": 60, "forcePageBreakBefore": true, "elements": [...] }Fontes customizadas
O FontLoader permite carregar fontes TTF para o PDF:
import 'package:sulfite_core/sulfite_core.dart';
// Flutter app — lê do asset bundle
final fonts = await FontLoader.load(
loader: const AssetFontBytesLoader(),
regular: 'assets/fonts/Inter-Regular.ttf',
bold: 'assets/fonts/Inter-Bold.ttf',
italic: 'assets/fonts/Inter-Italic.ttf',
boldItalic: 'assets/fonts/Inter-BoldItalic.ttf',
);
// CLI / servidor — lê do sistema de arquivos
final fonts = await FontLoader.load(
loader: const FileFontBytesLoader(),
regular: '/usr/share/fonts/Inter-Regular.ttf',
bold: '/usr/share/fonts/Inter-Bold.ttf',
);Ver detalhes em Fontes customizadas.
Etiquetas
O PDF renderer suporta modo etiqueta via labelConfig no pageSettings. Ver Etiquetas.
Todos os 14 elementos
O renderer PDF suporta todos os 14 tipos de elementos: Text, Field, Aggregate, Image, Table, Chart, Barcode, Line, Rect, Circle, RichText e Spacer.
Gráficos no PDF
Os gráficos são renderizados nativamente com package:pdf (sem dependências externas). Detalhes por tipo:
| Tipo | Comportamento |
|---|---|
| Bar (agrupado) | Cada série usa offset para barras lado a lado |
| Bar (empilhado) | Camadas cumulativas desenhadas em ordem reversa |
| Line | Linhas com pontos conectados |
| Pie | Fatias com cores da paleta padrão; valores ≤ 0 são omitidos |
Legenda, cores, grade e borda seguem o ChartOptions do JSON. Ver Chart.