Commit f6fc8ec

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-01-08 14:19:57
implement two column pdfs
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 3ceecbe
Changed files (1)
lib
model
export_import
lib/model/export_import/pdf_converter.dart
@@ -1,3 +1,4 @@
+import 'dart:math';
 import 'dart:typed_data';
 import 'dart:ui';
 
@@ -38,13 +39,20 @@ class PdfConverter {
     pdf.addPage(pw.MultiPage(
         pageFormat: PdfPageFormat.a4,
         build: (pw.Context context) {
+          final title = (pdfSettings.exportTitle) ? _buildPdfTitle(records, analyzer) : null;
+          title?.layout(context, const pw.BoxConstraints());
+          final statistics = (pdfSettings.exportStatistics) ? _buildPdfStatistics(analyzer) : null;
+          statistics?.layout(context, const pw.BoxConstraints());
+          final availableHeight = PdfPageFormat.a4.availableHeight
+              - (title?.box?.height ?? 0)
+              - (statistics?.box?.height ?? 0);
           return [
             if (pdfSettings.exportTitle)
-              _buildPdfTitle(records, analyzer),
+              title!,
             if (pdfSettings.exportStatistics)
-              _buildPdfStatistics(analyzer),
+              statistics!,
             if (pdfSettings.exportData)
-              _buildPdfTable(records),
+              _buildPdfTable(records, availableHeight),
           ];
         }));
     return await pdf.save();
@@ -80,51 +88,78 @@ class PdfConverter {
     );
   }
 
-  pw.Widget _buildPdfTable(Iterable<BloodPressureRecord> records) {
+  pw.Widget _buildPdfTable(Iterable<BloodPressureRecord> records, double availableHeight) {
     final columns = pdfSettings.exportFieldsConfiguration.getActiveColumns(availableColumns);
-    
-    return pw.TableHelper.fromTextArray(
-      border: null,
-      cellAlignment: pw.Alignment.centerLeft,
-      headerDecoration: const pw.BoxDecoration(
-          border: pw.Border(bottom: pw.BorderSide(color: PdfColors.black))
-      ),
-      headerHeight: pdfSettings.headerHeight,
-      cellHeight: pdfSettings.cellHeight,
-      cellAlignments: { 
-        for (final v in List.generate(columns.length, (idx)=>idx)) 
-          v : pw.Alignment.centerLeft,
-      },
-      headerStyle: pw.TextStyle(
-        color: PdfColors.black,
-        fontSize: pdfSettings.headerFontSize,
-        fontWeight: pw.FontWeight.bold,
-      ),
-      cellStyle: pw.TextStyle(
-        fontSize: pdfSettings.cellFontSize,
-      ),
-      headerCellDecoration: pw.BoxDecoration(
-        border: pw.Border(
-          bottom: pw.BorderSide(
-            color: settings.accentColor.toPdfColor(),
-            width: 5,
+    final rowCount =
+      (availableHeight - pdfSettings.headerHeight)
+        ~/ (pdfSettings.cellHeight + 5);
+
+    final data = records.map(
+      (record) => columns.map(
+        (column) => column.encode(record)
+      ).toList()
+    ).toList();
+
+    final List<pw.Widget> tables = [];
+    for (int offset = 0; offset < data.length; offset += rowCount) {
+      final dataRange = data.getRange(offset, min(offset + rowCount, data.length)).toList();
+      tables.add(pw.SizedBox(
+        width: PdfPageFormat.a4.availableWidth ~/2 - 5, // sized box between columns at bottom
+        child: pw.TableHelper.fromTextArray(
+          border: null,
+          cellAlignment: pw.Alignment.centerLeft,
+          headerDecoration: const pw.BoxDecoration(
+              border: pw.Border(bottom: pw.BorderSide(color: PdfColors.black))
           ),
-        ),
-      ),
-      rowDecoration: const pw.BoxDecoration(
-        border: pw.Border(
-          bottom: pw.BorderSide(
-            color: PdfColors.blueGrey,
-            width: .5,
+          headerHeight: pdfSettings.headerHeight,
+          cellHeight: pdfSettings.cellHeight,
+          cellAlignments: {
+            for (final v in List.generate(columns.length, (idx)=>idx))
+              v : pw.Alignment.centerLeft,
+          },
+          headerStyle: pw.TextStyle(
+            color: PdfColors.black,
+            fontSize: pdfSettings.headerFontSize,
+            fontWeight: pw.FontWeight.bold,
           ),
-        ),
-      ),
-      headers: columns.map((c) => c.userTitle(localizations)).toList(),
-      data: records.map(
-              (record) => columns.map(
-                  (column) => column.encode(record)
-          ).toList()
-      ).toList(),
+          cellStyle: pw.TextStyle(
+            fontSize: pdfSettings.cellFontSize,
+          ),
+          headerCellDecoration: pw.BoxDecoration(
+            border: pw.Border(
+              bottom: pw.BorderSide(
+                color: settings.accentColor.toPdfColor(),
+                width: 5,
+              ),
+            ),
+          ),
+          rowDecoration: const pw.BoxDecoration(
+            border: pw.Border(
+              bottom: pw.BorderSide(
+                color: PdfColors.blueGrey,
+                width: .5,
+              ),
+            ),
+          ),
+          headers: columns.map((c) => c.userTitle(localizations)).toList(),
+          data: dataRange,
+        )
+      ));
+    }
+
+    return pw.Column(
+      children: [
+        for (int i = 0; i < tables.length; i += 2)
+          pw.Row(
+            crossAxisAlignment: pw.CrossAxisAlignment.start,
+            children: [ // TODO: more generic detection of column count
+              tables[i],
+              pw.SizedBox(width: 10),
+              if (i+1 < tables.length)
+                tables[i+1],
+            ]
+          )
+      ]
     );
   }
 }