generate method

Future<Uint8List> generate(
  1. PdfTemplate template,
  2. Map<String, dynamic> data
)

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();
}