Tutorial: Exportação multi-formato
O Sulfite gera o mesmo relatório em 4 formatos a partir de uma única definição JSON. Neste tutorial você vai entender como cada formato renderiza os elementos e como tirar o melhor proveito de cada um.
Formatos disponíveis
| Formato | Extensão | Uso ideal |
|---|---|---|
.pdf | Impressão, documentos formais | |
| HTML | .html | Visualização web, gráficos interativos |
| CSV | .csv | Importação em planilhas, ETL |
| Excel | .xlsx | Análise de dados, filtros nativos |
Gerar todos os formatos
dart
import 'dart:convert';
import 'dart:io';
import 'package:sulfite_core/sulfite_core.dart';
void main() async {
final engine = SulfiteEngineImpl();
final report = await engine.parseReport(
File('report.json').readAsStringSync(),
);
final data = jsonDecode(File('data.json').readAsStringSync());
final ctx = await engine.processData(report, data);
// PDF — layout pixelPerfeito
final pdf = await engine.renderToPdf(ctx);
File('relatorio.pdf').writeAsBytesSync(pdf);
// HTML — visualização web com Chart.js
final html = await engine.renderToHtml(ctx);
File('relatorio.html').writeAsStringSync(html);
// CSV — dados tabulares puros (RFC 4180)
final csv = await engine.renderToCsv(ctx);
File('relatorio.csv').writeAsStringSync(csv);
// Excel — planilha .xlsx
final xlsx = await engine.renderToExcel(ctx);
File('relatorio.xlsx').writeAsBytesSync(xlsx);
}O que cada formato renderiza
Elementos visuais vs. tabulares
| Elemento | HTML | CSV | Excel | |
|---|---|---|---|---|
| Text | ✅ Posicionado | ✅ Posicionado (CSS) | — | — |
| Field | ✅ Formatado | ✅ Formatado | ✅ Coluna | ✅ Coluna |
| Aggregate | ✅ Calculado | ✅ Calculado | ✅ Linha total | ✅ Linha total |
| Chart | ✅ Nativo | ✅ Chart.js interativo | Dados brutos | Dados brutos |
| Table | ✅ Grade | ✅ <table> HTML | ✅ Linhas CSV | ✅ Linhas Excel |
| Image | ✅ Embarcada | ✅ Base64/URL | — | — |
| Barcode | ✅ Renderizado | ✅ SVG | Texto do código | Texto do código |
| RichText | ✅ Spans nativos | ✅ <span> estilizados | Texto puro | Texto puro |
| Shapes | ✅ Desenhadas | ✅ SVG/CSS | — | — |
Detalhes por formato
PDF
- Layout posicional exato (coordenadas x, y)
- Multi-página automática com header/footer repetidos
- Fontes customizadas via
FontLoader - Gráficos renderizados nativamente via
package:pdf
HTML
- Layout posicional via CSS absolute/relative
- Gráficos renderizados com Chart.js 4 (CDN) — interativos com hover e tooltips
- Multi-página representada como seções
<div> - Responsivo quando desejado
CSV
- Segue RFC 4180 (compatível com Excel, Google Sheets)
- Apenas dados tabulares das bands
detail - Campos do esquema viram colunas
- Formato puro, sem estilo visual
Excel
- Arquivo
.xlsxválido - Dados das bands
detailcom formatação básica - Compatível com Excel, LibreOffice, Google Sheets
- Suporta múltiplas linhas de agregação
Comparando saídas
Uma boa prática é validar que todos os formatos produzem dados consistentes:
dart
// Verificar que nenhum formato está vazio
assert(pdf.isNotEmpty);
assert(html.isNotEmpty);
assert(csv.isNotEmpty);
assert(xlsx.isNotEmpty);
// CSV e Excel devem ter o mesmo número de linhas de dados
final csvLines = csv.split('\n').where((l) => l.trim().isNotEmpty).length;
// csvLines inclui header + registrosDicas
- Use PDF para relatórios que serão impressos ou enviados por email
- Use HTML quando quiser gráficos interativos ou embedding em sistemas web
- Use CSV para importação em outros sistemas ou pipelines de dados
- Use Excel quando o destinatário precisa de filtros e fórmulas nativas
- Todos os formatos respeitam os mesmos dados e parâmetros — a diferença é apenas visual
Exemplo prático: comparação de 3 relatórios
O projeto inclui testes automatizados que geram todos os exemplos em todos os formatos e comparam a consistência:
examples/
├── 06-grouped-sales/ → GroupBands + Expressões
├── 07-dashboard/ → Charts + RichText + Table
└── 08-hr-report/ → Parameters + ValidaçãoCada exemplo é testado em:
- Parse correto do JSON
- Geração PDF, HTML, CSV e Excel (todos não-vazio)
- Contagem de linhas CSV vs Excel (consistência)
- HTML contém
<table>ou<th>esperados