Showing
9 changed files
with
94 additions
and
21 deletions
| @@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
| 16 | 16 | ||
| 17 | import 'dart:async'; | 17 | import 'dart:async'; |
| 18 | import 'dart:io'; | 18 | import 'dart:io'; |
| 19 | +import 'dart:typed_data'; | ||
| 19 | 20 | ||
| 20 | import 'package:flutter/foundation.dart'; | 21 | import 'package:flutter/foundation.dart'; |
| 21 | import 'package:flutter/material.dart'; | 22 | import 'package:flutter/material.dart'; |
| @@ -28,6 +29,7 @@ import 'package:printing_demo/certificate.dart'; | @@ -28,6 +29,7 @@ import 'package:printing_demo/certificate.dart'; | ||
| 28 | import 'package:url_launcher/url_launcher.dart' as ul; | 29 | import 'package:url_launcher/url_launcher.dart' as ul; |
| 29 | 30 | ||
| 30 | import 'calendar.dart'; | 31 | import 'calendar.dart'; |
| 32 | +import 'data.dart'; | ||
| 31 | import 'document.dart'; | 33 | import 'document.dart'; |
| 32 | import 'invoice.dart'; | 34 | import 'invoice.dart'; |
| 33 | import 'report.dart'; | 35 | import 'report.dart'; |
| @@ -40,7 +42,7 @@ class MyApp extends StatefulWidget { | @@ -40,7 +42,7 @@ class MyApp extends StatefulWidget { | ||
| 40 | Example('INVOICE', 'invoice.dart', generateInvoice), | 42 | Example('INVOICE', 'invoice.dart', generateInvoice), |
| 41 | Example('REPORT', 'report.dart', generateReport), | 43 | Example('REPORT', 'report.dart', generateReport), |
| 42 | Example('CALENDAR', 'calendar.dart', generateCalendar), | 44 | Example('CALENDAR', 'calendar.dart', generateCalendar), |
| 43 | - Example('CERTIFICATE', 'certificate.dart', generateCertificate), | 45 | + Example('CERTIFICATE', 'certificate.dart', generateCertificate, true), |
| 44 | ]; | 46 | ]; |
| 45 | 47 | ||
| 46 | @override | 48 | @override |
| @@ -55,12 +57,21 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | @@ -55,12 +57,21 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | ||
| 55 | 57 | ||
| 56 | PrintingInfo? printingInfo; | 58 | PrintingInfo? printingInfo; |
| 57 | 59 | ||
| 60 | + var _data = CustomData(); | ||
| 61 | + var _hasData = false; | ||
| 62 | + var _pending = false; | ||
| 63 | + | ||
| 58 | @override | 64 | @override |
| 59 | void initState() { | 65 | void initState() { |
| 60 | super.initState(); | 66 | super.initState(); |
| 61 | _init(); | 67 | _init(); |
| 62 | } | 68 | } |
| 63 | 69 | ||
| 70 | + @override | ||
| 71 | + void didChangeDependencies() { | ||
| 72 | + super.didChangeDependencies(); | ||
| 73 | + } | ||
| 74 | + | ||
| 64 | Future<void> _init() async { | 75 | Future<void> _init() async { |
| 65 | final info = await Printing.info(); | 76 | final info = await Printing.info(); |
| 66 | 77 | ||
| @@ -73,6 +84,18 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | @@ -73,6 +84,18 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | ||
| 73 | setState(() { | 84 | setState(() { |
| 74 | _tab = _tabController!.index; | 85 | _tab = _tabController!.index; |
| 75 | }); | 86 | }); |
| 87 | + if (MyApp.examples[_tab].needsData && !_hasData && !_pending) { | ||
| 88 | + _pending = true; | ||
| 89 | + askName(context).then((value) { | ||
| 90 | + if (value != null) { | ||
| 91 | + setState(() { | ||
| 92 | + _data = CustomData(name: value); | ||
| 93 | + _hasData = true; | ||
| 94 | + _pending = false; | ||
| 95 | + }); | ||
| 96 | + } | ||
| 97 | + }); | ||
| 98 | + } | ||
| 76 | }); | 99 | }); |
| 77 | 100 | ||
| 78 | setState(() { | 101 | setState(() { |
| @@ -81,10 +104,7 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | @@ -81,10 +104,7 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | ||
| 81 | } | 104 | } |
| 82 | 105 | ||
| 83 | void _showPrintedToast(BuildContext context) { | 106 | void _showPrintedToast(BuildContext context) { |
| 84 | - final scaffold = Scaffold.of(context); | ||
| 85 | - | ||
| 86 | - // ignore: deprecated_member_use | ||
| 87 | - scaffold.showSnackBar( | 107 | + ScaffoldMessenger.of(context).showSnackBar( |
| 88 | const SnackBar( | 108 | const SnackBar( |
| 89 | content: Text('Document printed successfully'), | 109 | content: Text('Document printed successfully'), |
| 90 | ), | 110 | ), |
| @@ -92,10 +112,7 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | @@ -92,10 +112,7 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | ||
| 92 | } | 112 | } |
| 93 | 113 | ||
| 94 | void _showSharedToast(BuildContext context) { | 114 | void _showSharedToast(BuildContext context) { |
| 95 | - final scaffold = Scaffold.of(context); | ||
| 96 | - | ||
| 97 | - // ignore: deprecated_member_use | ||
| 98 | - scaffold.showSnackBar( | 115 | + ScaffoldMessenger.of(context).showSnackBar( |
| 99 | const SnackBar( | 116 | const SnackBar( |
| 100 | content: Text('Document shared successfully'), | 117 | content: Text('Document shared successfully'), |
| 101 | ), | 118 | ), |
| @@ -144,7 +161,7 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | @@ -144,7 +161,7 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | ||
| 144 | ), | 161 | ), |
| 145 | body: PdfPreview( | 162 | body: PdfPreview( |
| 146 | maxPageWidth: 700, | 163 | maxPageWidth: 700, |
| 147 | - build: MyApp.examples[_tab].builder, | 164 | + build: (format) => MyApp.examples[_tab].builder(format, _data), |
| 148 | actions: actions, | 165 | actions: actions, |
| 149 | onPrinted: _showPrintedToast, | 166 | onPrinted: _showPrintedToast, |
| 150 | onShared: _showSharedToast, | 167 | onShared: _showSharedToast, |
| @@ -162,14 +179,47 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | @@ -162,14 +179,47 @@ class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { | ||
| 162 | 'https://github.com/DavBfr/dart_pdf/blob/master/demo/lib/${MyApp.examples[_tab].file}', | 179 | 'https://github.com/DavBfr/dart_pdf/blob/master/demo/lib/${MyApp.examples[_tab].file}', |
| 163 | ); | 180 | ); |
| 164 | } | 181 | } |
| 182 | + | ||
| 183 | + Future<String?> askName(BuildContext context) { | ||
| 184 | + return showDialog<String>( | ||
| 185 | + barrierDismissible: false, | ||
| 186 | + context: context, | ||
| 187 | + builder: (context) { | ||
| 188 | + final controller = TextEditingController(); | ||
| 189 | + | ||
| 190 | + return AlertDialog( | ||
| 191 | + title: Text('Please type your name:'), | ||
| 192 | + contentPadding: EdgeInsets.symmetric(horizontal: 20), | ||
| 193 | + content: TextField( | ||
| 194 | + decoration: InputDecoration(hintText: '[your name]'), | ||
| 195 | + controller: controller, | ||
| 196 | + ), | ||
| 197 | + actions: [ | ||
| 198 | + TextButton( | ||
| 199 | + onPressed: () { | ||
| 200 | + if (controller.text != '') { | ||
| 201 | + Navigator.pop(context, controller.text); | ||
| 202 | + } | ||
| 203 | + }, | ||
| 204 | + child: Text('OK'), | ||
| 205 | + ), | ||
| 206 | + ], | ||
| 207 | + ); | ||
| 208 | + }); | ||
| 209 | + } | ||
| 165 | } | 210 | } |
| 166 | 211 | ||
| 212 | +typedef LayoutCallbackWithData = Future<Uint8List> Function( | ||
| 213 | + PdfPageFormat pageFormat, CustomData data); | ||
| 214 | + | ||
| 167 | class Example { | 215 | class Example { |
| 168 | - const Example(this.name, this.file, this.builder); | 216 | + const Example(this.name, this.file, this.builder, [this.needsData = false]); |
| 169 | 217 | ||
| 170 | final String name; | 218 | final String name; |
| 171 | 219 | ||
| 172 | final String file; | 220 | final String file; |
| 173 | 221 | ||
| 174 | - final LayoutCallback builder; | 222 | + final LayoutCallbackWithData builder; |
| 223 | + | ||
| 224 | + final bool needsData; | ||
| 175 | } | 225 | } |
| @@ -21,6 +21,8 @@ import 'package:intl/intl.dart'; | @@ -21,6 +21,8 @@ import 'package:intl/intl.dart'; | ||
| 21 | import 'package:pdf/pdf.dart'; | 21 | import 'package:pdf/pdf.dart'; |
| 22 | import 'package:pdf/widgets.dart'; | 22 | import 'package:pdf/widgets.dart'; |
| 23 | 23 | ||
| 24 | +import 'data.dart'; | ||
| 25 | + | ||
| 24 | class Calendar extends StatelessWidget { | 26 | class Calendar extends StatelessWidget { |
| 25 | Calendar({ | 27 | Calendar({ |
| 26 | this.date, | 28 | this.date, |
| @@ -174,7 +176,8 @@ class Calendar extends StatelessWidget { | @@ -174,7 +176,8 @@ class Calendar extends StatelessWidget { | ||
| 174 | } | 176 | } |
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | -Future<Uint8List> generateCalendar(PdfPageFormat pageFormat) async { | 179 | +Future<Uint8List> generateCalendar( |
| 180 | + PdfPageFormat pageFormat, CustomData data) async { | ||
| 178 | //Create a PDF document. | 181 | //Create a PDF document. |
| 179 | final document = Document(); | 182 | final document = Document(); |
| 180 | final date = DateTime.now(); | 183 | final date = DateTime.now(); |
| @@ -23,6 +23,8 @@ import 'package:pdf/pdf.dart'; | @@ -23,6 +23,8 @@ import 'package:pdf/pdf.dart'; | ||
| 23 | import 'package:pdf/widgets.dart' as pw; | 23 | import 'package:pdf/widgets.dart' as pw; |
| 24 | import 'package:vector_math/vector_math_64.dart'; | 24 | import 'package:vector_math/vector_math_64.dart'; |
| 25 | 25 | ||
| 26 | +import 'data.dart'; | ||
| 27 | + | ||
| 26 | final _cache = <String, Uint8List>{}; | 28 | final _cache = <String, Uint8List>{}; |
| 27 | 29 | ||
| 28 | Future<Uint8List> _download(String url) async { | 30 | Future<Uint8List> _download(String url) async { |
| @@ -41,7 +43,8 @@ Future<pw.Font> _downloadFont(String url) async { | @@ -41,7 +43,8 @@ Future<pw.Font> _downloadFont(String url) async { | ||
| 41 | return pw.Font.ttf(data.buffer.asByteData()); | 43 | return pw.Font.ttf(data.buffer.asByteData()); |
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | -Future<Uint8List> generateCertificate(PdfPageFormat pageFormat) async { | 46 | +Future<Uint8List> generateCertificate( |
| 47 | + PdfPageFormat pageFormat, CustomData data) async { | ||
| 45 | final lorem = pw.LoremText(); | 48 | final lorem = pw.LoremText(); |
| 46 | final pdf = pw.Document(); | 49 | final pdf = pw.Document(); |
| 47 | 50 | ||
| @@ -97,7 +100,7 @@ Future<Uint8List> generateCertificate(PdfPageFormat pageFormat) async { | @@ -97,7 +100,7 @@ Future<Uint8List> generateCertificate(PdfPageFormat pageFormat) async { | ||
| 97 | child: pw.Divider(color: PdfColors.grey, thickness: 1.5), | 100 | child: pw.Divider(color: PdfColors.grey, thickness: 1.5), |
| 98 | ), | 101 | ), |
| 99 | pw.Text( | 102 | pw.Text( |
| 100 | - 'Louis Mitchell', | 103 | + data.name, |
| 101 | style: pw.TextStyle( | 104 | style: pw.TextStyle( |
| 102 | fontWeight: pw.FontWeight.bold, | 105 | fontWeight: pw.FontWeight.bold, |
| 103 | fontSize: 20, | 106 | fontSize: 20, |
| @@ -127,7 +130,7 @@ Future<Uint8List> generateCertificate(PdfPageFormat pageFormat) async { | @@ -127,7 +130,7 @@ Future<Uint8List> generateCertificate(PdfPageFormat pageFormat) async { | ||
| 127 | pw.Padding( | 130 | pw.Padding( |
| 128 | padding: pw.EdgeInsets.symmetric(horizontal: 10), | 131 | padding: pw.EdgeInsets.symmetric(horizontal: 10), |
| 129 | child: pw.Text( | 132 | child: pw.Text( |
| 130 | - 'Rubix Cube Challenge', | 133 | + 'Flutter PDF Demo', |
| 131 | style: pw.TextStyle( | 134 | style: pw.TextStyle( |
| 132 | fontSize: 10, | 135 | fontSize: 10, |
| 133 | ), | 136 | ), |
demo/lib/data.dart
0 → 100644
| @@ -19,7 +19,10 @@ import 'dart:typed_data'; | @@ -19,7 +19,10 @@ import 'dart:typed_data'; | ||
| 19 | import 'package:pdf/pdf.dart'; | 19 | import 'package:pdf/pdf.dart'; |
| 20 | import 'package:pdf/widgets.dart' as pw; | 20 | import 'package:pdf/widgets.dart' as pw; |
| 21 | 21 | ||
| 22 | -Future<Uint8List> generateDocument(PdfPageFormat format) async { | 22 | +import 'data.dart'; |
| 23 | + | ||
| 24 | +Future<Uint8List> generateDocument( | ||
| 25 | + PdfPageFormat format, CustomData data) async { | ||
| 23 | final doc = pw.Document(pageMode: PdfPageMode.outlines); | 26 | final doc = pw.Document(pageMode: PdfPageMode.outlines); |
| 24 | 27 | ||
| 25 | doc.addPage(pw.MultiPage( | 28 | doc.addPage(pw.MultiPage( |
| @@ -21,7 +21,10 @@ import 'package:intl/intl.dart'; | @@ -21,7 +21,10 @@ import 'package:intl/intl.dart'; | ||
| 21 | import 'package:pdf/pdf.dart'; | 21 | import 'package:pdf/pdf.dart'; |
| 22 | import 'package:pdf/widgets.dart' as pw; | 22 | import 'package:pdf/widgets.dart' as pw; |
| 23 | 23 | ||
| 24 | -Future<Uint8List> generateInvoice(PdfPageFormat pageFormat) async { | 24 | +import 'data.dart'; |
| 25 | + | ||
| 26 | +Future<Uint8List> generateInvoice( | ||
| 27 | + PdfPageFormat pageFormat, CustomData data) async { | ||
| 25 | final lorem = pw.LoremText(); | 28 | final lorem = pw.LoremText(); |
| 26 | 29 | ||
| 27 | final products = <Product>[ | 30 | final products = <Product>[ |
| @@ -21,7 +21,10 @@ import 'package:flutter/services.dart'; | @@ -21,7 +21,10 @@ import 'package:flutter/services.dart'; | ||
| 21 | import 'package:pdf/pdf.dart'; | 21 | import 'package:pdf/pdf.dart'; |
| 22 | import 'package:pdf/widgets.dart' as pw; | 22 | import 'package:pdf/widgets.dart' as pw; |
| 23 | 23 | ||
| 24 | -Future<Uint8List> generateReport(PdfPageFormat pageFormat) async { | 24 | +import 'data.dart'; |
| 25 | + | ||
| 26 | +Future<Uint8List> generateReport( | ||
| 27 | + PdfPageFormat pageFormat, CustomData data) async { | ||
| 25 | const tableHeaders = ['Category', 'Budget', 'Expense', 'Result']; | 28 | const tableHeaders = ['Category', 'Budget', 'Expense', 'Result']; |
| 26 | 29 | ||
| 27 | const dataTable = [ | 30 | const dataTable = [ |
| @@ -21,12 +21,13 @@ import 'dart:typed_data'; | @@ -21,12 +21,13 @@ import 'dart:typed_data'; | ||
| 21 | import 'package:flutter/services.dart'; | 21 | import 'package:flutter/services.dart'; |
| 22 | import 'package:pdf/pdf.dart'; | 22 | import 'package:pdf/pdf.dart'; |
| 23 | import 'package:pdf/widgets.dart' as pw; | 23 | import 'package:pdf/widgets.dart' as pw; |
| 24 | +import 'package:printing_demo/data.dart'; | ||
| 24 | 25 | ||
| 25 | const PdfColor green = PdfColor.fromInt(0xff9ce5d0); | 26 | const PdfColor green = PdfColor.fromInt(0xff9ce5d0); |
| 26 | const PdfColor lightGreen = PdfColor.fromInt(0xffcdf1e7); | 27 | const PdfColor lightGreen = PdfColor.fromInt(0xffcdf1e7); |
| 27 | const sep = 120.0; | 28 | const sep = 120.0; |
| 28 | 29 | ||
| 29 | -Future<Uint8List> generateResume(PdfPageFormat format) async { | 30 | +Future<Uint8List> generateResume(PdfPageFormat format, CustomData data) async { |
| 30 | final doc = pw.Document(title: 'My Résumé', author: 'David PHAM-VAN'); | 31 | final doc = pw.Document(title: 'My Résumé', author: 'David PHAM-VAN'); |
| 31 | 32 | ||
| 32 | final profileImage = pw.MemoryImage( | 33 | final profileImage = pw.MemoryImage( |
| @@ -2,11 +2,13 @@ import 'dart:io'; | @@ -2,11 +2,13 @@ import 'dart:io'; | ||
| 2 | 2 | ||
| 3 | import 'package:flutter_test/flutter_test.dart'; | 3 | import 'package:flutter_test/flutter_test.dart'; |
| 4 | import 'package:pdf/pdf.dart'; | 4 | import 'package:pdf/pdf.dart'; |
| 5 | +import 'package:printing_demo/data.dart'; | ||
| 5 | import 'package:printing_demo/document.dart'; | 6 | import 'package:printing_demo/document.dart'; |
| 6 | 7 | ||
| 7 | void main() { | 8 | void main() { |
| 8 | testWidgets('Pdf Generate the document', (WidgetTester tester) async { | 9 | testWidgets('Pdf Generate the document', (WidgetTester tester) async { |
| 9 | - final doc = await generateDocument(PdfPageFormat.a4); | 10 | + final data = CustomData(); |
| 11 | + final doc = await generateDocument(PdfPageFormat.a4, data); | ||
| 10 | 12 | ||
| 11 | final file = File('document.pdf'); | 13 | final file = File('document.pdf'); |
| 12 | file.writeAsBytesSync(doc); | 14 | file.writeAsBytesSync(doc); |
-
Please register or login to post a comment