From d579c0008904d45eae6106ddc7743281fc71e72c Mon Sep 17 00:00:00 2001 From: Chhin Sras Date: Thu, 30 Jun 2022 11:06:59 +0700 Subject: [PATCH] added: print PDF action --- .flutter-plugins | 2 + .flutter-plugins-dependencies | 1 + example/lib/main.dart | 1 + .../flutter/generated_plugin_registrant.cc | 11 +- .../flutter/generated_plugin_registrant.h | 6 +- example/linux/flutter/generated_plugins.cmake | 24 ++++ .../Flutter/GeneratedPluginRegistrant.swift | 2 + example/pubspec.lock | 128 ++++++++++++++++-- .../flutter/generated_plugin_registrant.cc | 3 + .../windows/flutter/generated_plugins.cmake | 9 ++ lib/src/responsive_datatable.dart | 87 +++++++++++- pubspec.lock | 128 ++++++++++++++++-- pubspec.yaml | 2 + 13 files changed, 378 insertions(+), 26 deletions(-) create mode 100644 .flutter-plugins create mode 100644 .flutter-plugins-dependencies create mode 100644 example/linux/flutter/generated_plugins.cmake diff --git a/.flutter-plugins b/.flutter-plugins new file mode 100644 index 0000000..9e26ec7 --- /dev/null +++ b/.flutter-plugins @@ -0,0 +1,2 @@ +# This is a generated file; do not edit or check into version control. +printing=/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/ diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000..9bdfecc --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"printing","path":"/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/","native_build":true,"dependencies":[]}],"android":[{"name":"printing","path":"/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/","native_build":true,"dependencies":[]}],"macos":[{"name":"printing","path":"/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/","native_build":true,"dependencies":[]}],"linux":[{"name":"printing","path":"/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/","native_build":true,"dependencies":[]}],"windows":[{"name":"printing","path":"/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/","native_build":true,"dependencies":[]}],"web":[{"name":"printing","path":"/Users/chhinsras/Development/flutter/.pub-cache/hosted/pub.dartlang.org/printing-5.9.1/","dependencies":[]}]},"dependencyGraph":[{"name":"printing","dependencies":[]}],"date_created":"2022-06-30 10:47:42.980805","version":"3.0.2"} \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 2bc2b27..208862a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -272,6 +272,7 @@ class _DataPageState extends State { label: Text("new item"), ), reponseScreenSizes: [ScreenSize.xs], + exports: [ExportAction.print], actions: [ if (_isSearch) Expanded( diff --git a/example/linux/flutter/generated_plugin_registrant.cc b/example/linux/flutter/generated_plugin_registrant.cc index f621842..ce0e550 100644 --- a/example/linux/flutter/generated_plugin_registrant.cc +++ b/example/linux/flutter/generated_plugin_registrant.cc @@ -2,11 +2,14 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" -#include +#include -void RegisterPlugins(flutter::PluginRegistry* registry) { - ResponsiveTablePluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("ResponsiveTablePlugin")); +void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) printing_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "PrintingPlugin"); + printing_plugin_register_with_registrar(printing_registrar); } diff --git a/example/linux/flutter/generated_plugin_registrant.h b/example/linux/flutter/generated_plugin_registrant.h index 9846246..e0f0a47 100644 --- a/example/linux/flutter/generated_plugin_registrant.h +++ b/example/linux/flutter/generated_plugin_registrant.h @@ -2,12 +2,14 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ -#include +#include // Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); +void fl_register_plugins(FlPluginRegistry* registry); #endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/example/linux/flutter/generated_plugins.cmake b/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..0c2c3c3 --- /dev/null +++ b/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + printing +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..96cc75f 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,8 @@ import FlutterMacOS import Foundation +import printing func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) } diff --git a/example/pubspec.lock b/example/pubspec.lock index 5347781..5656132 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.1+2" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" async: dependency: transitive description: @@ -15,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + barcode: + dependency: transitive + description: + name: barcode + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" boolean_selector: dependency: transitive description: @@ -49,7 +63,14 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" cupertino_icons: dependency: "direct main" description: @@ -63,7 +84,14 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" flutter: dependency: "direct main" description: flutter @@ -74,6 +102,39 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4" matcher: dependency: transitive description: @@ -87,7 +148,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -101,7 +162,49 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + pdf: + dependency: transitive + description: + name: pdf + url: "https://pub.dartlang.org" + source: hosted + version: "3.8.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + printing: + dependency: transitive + description: + name: printing + url: "https://pub.dartlang.org" + source: hosted + version: "5.9.1" + qr: + dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" responsive_table: dependency: "direct main" description: @@ -120,7 +223,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -155,21 +258,28 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.0" sdks: - dart: ">=2.15.1 <3.0.0" + dart: ">=2.17.0 <3.0.0" flutter: ">=1.17.0" diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index 8b6d468..3dea03b 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + PrintingPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PrintingPlugin")); } diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake index 4d10c25..e685eaf 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -3,6 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + printing +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST ) set(PLUGIN_BUNDLED_LIBRARIES) @@ -13,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST}) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/lib/src/responsive_datatable.dart b/lib/src/responsive_datatable.dart index b985496..abaa855 100644 --- a/lib/src/responsive_datatable.dart +++ b/lib/src/responsive_datatable.dart @@ -1,6 +1,11 @@ import 'package:adaptivex/adaptivex.dart'; import 'package:flutter/material.dart'; +import 'package:pdf/pdf.dart'; +import 'package:printing/printing.dart'; import 'datatable_header.dart'; +import 'package:pdf/widgets.dart' as pw; + +enum ExportAction { print, pdf, excel, csv } class ResponsiveDatatable extends StatefulWidget { final bool showSelect; @@ -8,6 +13,7 @@ class ResponsiveDatatable extends StatefulWidget { final List>? source; final List>? selecteds; final Widget? title; + final List? exports; final List? actions; final List? footers; final Function(bool? value)? onSelectAll; @@ -74,6 +80,7 @@ class ResponsiveDatatable extends StatefulWidget { this.source, this.selecteds, this.title, + this.exports, this.actions, this.footers, this.sortColumn, @@ -388,6 +395,62 @@ class _ResponsiveDatatableState extends State { return widgets; } + printPDF() { + Printing.layoutPdf(onLayout: ((format) { + final pdf = pw.Document(); + pdf.addPage( + pw.MultiPage( + pageFormat: PdfPageFormat.a4, + maxPages: 100, + build: (pw.Context context) => [ + pw.Center( + heightFactor: 2.0, + child: pw.Text('Responsive Table Data', + style: const pw.TextStyle(fontSize: 16))), + pw.Table( + defaultColumnWidth: const pw.FixedColumnWidth(120.0), + border: pw.TableBorder.all( + color: PdfColor.fromHex('#8E8E8E'), width: 0.5), + children: [ + pw.TableRow( + decoration: const pw.BoxDecoration( + color: PdfColors.grey, + ), + children: [ + for (var column in widget.headers) + pw.Container( + margin: const pw.EdgeInsets.all(2.0), + padding: const pw.EdgeInsets.all(2.0), + child: pw.Text(column.text, + textAlign: pw.TextAlign.center, + style: pw.TextStyle( + fontWeight: pw.FontWeight.bold))) + ]), + for (int index = 0; index < widget.source!.length; index++) + pw.TableRow( + verticalAlignment: pw.TableCellVerticalAlignment.middle, + decoration: pw.BoxDecoration( + color: index % 2 == 1 + ? PdfColors.grey200 + : PdfColors.white), + children: [ + for (var column in widget.headers) + pw.Container( + margin: const pw.EdgeInsets.all(2.0), + padding: const pw.EdgeInsets.all(2.0), + child: pw.Text(widget.source![index][column.value] + .toString())), + ], + ) + ], + ), + ], + ), + ); + return pdf.save(); + })); + } + @override Widget build(BuildContext context) { return widget.reponseScreenSizes.isNotEmpty && @@ -408,7 +471,17 @@ class _ResponsiveDatatableState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (widget.title != null) widget.title!, + Row( + children: [ + if (widget.title != null) widget.title!, + if (widget.exports != null && + widget.exports!.contains(ExportAction.print)) + IconButton( + onPressed: () => printPDF(), + color: Theme.of(context).primaryColor, + icon: const Icon(Icons.print)), + ], + ), if (widget.actions != null) ...widget.actions! ], ), @@ -461,7 +534,17 @@ class _ResponsiveDatatableState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (widget.title != null) widget.title!, + Row( + children: [ + if (widget.title != null) widget.title!, + if (widget.exports != null && + widget.exports!.contains(ExportAction.print)) + IconButton( + onPressed: () => printPDF(), + color: Theme.of(context).primaryColor, + icon: const Icon(Icons.print)), + ], + ), if (widget.actions != null) ...widget.actions! ], ), diff --git a/pubspec.lock b/pubspec.lock index 3870515..92eaa01 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.1+2" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" async: dependency: transitive description: @@ -15,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + barcode: + dependency: transitive + description: + name: barcode + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" boolean_selector: dependency: transitive description: @@ -49,14 +63,28 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" flutter: dependency: "direct main" description: flutter @@ -74,6 +102,39 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4" lints: dependency: transitive description: @@ -94,7 +155,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -108,7 +169,49 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + pdf: + dependency: "direct main" + description: + name: pdf + url: "https://pub.dartlang.org" + source: hosted + version: "3.8.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + printing: + dependency: "direct main" + description: + name: printing + url: "https://pub.dartlang.org" + source: hosted + version: "5.9.1" + qr: + dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" sky_engine: dependency: transitive description: flutter @@ -120,7 +223,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -155,21 +258,28 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.0" sdks: - dart: ">=2.15.1 <3.0.0" + dart: ">=2.17.0 <3.0.0" flutter: ">=1.17.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3b0a993..9acc588 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,6 +9,8 @@ environment: dependencies: adaptivex: ^0.0.1+2 + printing: ^5.9.1 + pdf: ^3.8.1 flutter: sdk: flutter