Streaming
O processDataStream aceita um Stream<Map<String, dynamic>> em vez de uma lista completa. Os registros são consumidos incrementalmente, sem carregar tudo em memória de uma vez.
Uso
dart
final engine = SulfiteEngineImpl();
final report = await engine.parseReport(reportJson);
// Stream de registros (ex: de um banco de dados, API paginada, arquivo grande)
Stream<Map<String, dynamic>> getRecords() async* {
for (var i = 0; i < 10000; i++) {
yield {
'order_id': 'ORD-$i',
'customer': 'Cliente $i',
'amount': (i * 10.5),
};
}
}
final context = await engine.processDataStream(
report,
getRecords(),
dataSourceId: 'sales',
);
final pdf = await engine.renderToPdf(context);Assinatura
dart
Future<Map<String, dynamic>> processDataStream(
ReportDefinition report,
Stream<Map<String, dynamic>> dataStream, {
String? dataSourceId,
bool strict = true,
});| Parâmetro | Tipo | Descrição |
|---|---|---|
report | ReportDefinition | Definição do relatório |
dataStream | Stream<Map> | Stream de registros |
dataSourceId | String? | ID do data source que recebe os registros |
strict | bool | Modo strict (padrão: true) |
Quando usar
- Dados vindos de banco de dados com cursor
- APIs paginadas
- Leitura de arquivo grande linha a linha
- Quando a lista completa não cabe em memória
Isolate
O DataProcessor suporta processamento em Isolate para não bloquear a UI thread:
dart
final processor = DataProcessor(useIsolate: true);Isso é independente do streaming — pode ser usado com processData ou processDataStream.
Exemplo completo
dart
import 'dart:io';
import 'package:sulfite_core/sulfite_core.dart';
void main() async {
final engine = SulfiteEngineImpl();
final report = ReportDefinition(
reportId: 'stream_demo',
reportName: 'Stream Demo',
pageSettings: const PageSettings(
format: 'A4',
margins: EdgeInsetsModel(left: 40, right: 40, top: 40, bottom: 40),
),
dataSources: [
DataSource(
id: 'sales',
type: 'list',
schema: {'order_id': 'string', 'amount': 'number'},
),
],
bands: [
Band.header(id: 'header', height: 60, elements: [
ReportElement.text(id: 'title', x: 40, y: 20, content: 'Sales Report'),
]),
Band.detail(id: 'detail', dataSourceId: 'sales', height: 25, elements: [
ReportElement.field(id: 'f1', x: 40, y: 5, width: 100, binding: 'order_id'),
ReportElement.field(id: 'f2', x: 200, y: 5, width: 100, binding: 'amount', format: 'currency:BRL'),
]),
Band.summary(id: 'summary', height: 40, elements: [
ReportElement.aggregate(id: 'total', x: 200, y: 10, width: 100, verb: 'SUM', targetKey: 'amount', format: 'currency:BRL'),
]),
],
);
Stream<Map<String, dynamic>> salesStream() async* {
for (var i = 1; i <= 5000; i++) {
yield {'order_id': 'ORD-$i', 'amount': i * 12.50};
}
}
final context = await engine.processDataStream(
report,
salesStream(),
dataSourceId: 'sales',
);
final pdf = await engine.renderToPdf(context);
File('stream_output.pdf').writeAsBytesSync(pdf);
}