generate method
Generates a PDF document as a byte array from the given template and data.
The data map is used to resolve dynamic bindings in text, images, and tables.
Implementation
Future<Uint8List> generate(PdfTemplate template, Map<String, dynamic> data) async {
final pdf = pw.Document();
// Pre-calculate visibility and pre-fetch images async
final visibleElements = template.elements.where((el) => _checkVisibility(el.currentVisibleIfKey, data)).toList();
final preloadedImages = <int, pw.MemoryImage?>{};
for (int i = 0; i < visibleElements.length; i++) {
final el = visibleElements[i];
if (el is PdfImageElement) {
preloadedImages[i] = await _preloadImage(el, data);
}
}
final marginsInPt = template.pageMargins;
final pageFormat = switch (template.layoutType) {
LayoutType.roll => PdfPageFormat.roll80,
LayoutType.a5 => PdfPageFormat.a5,
LayoutType.custom => PdfPageFormat(
template.customWidth * PdfPageFormat.mm,
template.customHeight * PdfPageFormat.mm,
),
_ => PdfPageFormat.a4,
};
final formattedPage = pageFormat.copyWith(
marginLeft: marginsInPt,
marginRight: marginsInPt,
marginTop: marginsInPt,
marginBottom: marginsInPt,
);
final widgets = List.generate(
visibleElements.length,
(i) => _buildElement(visibleElements[i], data, template.baseFontSize, preloadedImages[i]),
);
if (template.layoutType == LayoutType.roll) {
pdf.addPage(pw.Page(
pageFormat: formattedPage,
build: (context) => pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: widgets,
),
));
} else {
pdf.addPage(pw.MultiPage(
pageFormat: formattedPage,
build: (context) => widgets,
));
}
return pdf.save();
}