Showing
13 changed files
with
307 additions
and
284 deletions
@@ -81,7 +81,7 @@ test-printing: $(FONTS) get-printing .coverage | @@ -81,7 +81,7 @@ test-printing: $(FONTS) get-printing .coverage | ||
81 | 81 | ||
82 | test-readme: $(FONTS) get-readme | 82 | test-readme: $(FONTS) get-readme |
83 | cd test; dart extract_readme.dart | 83 | cd test; dart extract_readme.dart |
84 | - cd test; dartanalyzer readme.dart | 84 | + cd test; dartanalyzer readme-*.dart |
85 | 85 | ||
86 | test-web: | 86 | test-web: |
87 | cd pdf/web_example; pub get | 87 | cd pdf/web_example; pub get |
@@ -20,16 +20,31 @@ The coordinate system is using the internal Pdf unit: | @@ -20,16 +20,31 @@ The coordinate system is using the internal Pdf unit: | ||
20 | 20 | ||
21 | [](https://www.buymeacoffee.com/JORBmbw9h "Buy Me A Coffee") | 21 | [](https://www.buymeacoffee.com/JORBmbw9h "Buy Me A Coffee") |
22 | 22 | ||
23 | -Example: | 23 | +## Installing |
24 | + | ||
25 | +If you want to print the Pdf document on an actual printer with Flutter, | ||
26 | +follow the instructions at <https://pub.dev/packages/printing> | ||
27 | + | ||
28 | +1. Add this package to your package's `pubspec.yaml` file as described | ||
29 | + on the installation tab | ||
30 | + | ||
31 | +2. Import the libraries | ||
32 | + | ||
33 | + ```dart | ||
34 | + import 'package:pdf/pdf.dart'; | ||
35 | + import 'package:pdf/widgets.dart' as pw; | ||
36 | + ``` | ||
37 | + | ||
38 | +## Examples | ||
24 | 39 | ||
25 | ```dart | 40 | ```dart |
26 | -final pdf = Document(); | 41 | +final pdf = pw.Document(); |
27 | 42 | ||
28 | -pdf.addPage(Page( | 43 | +pdf.addPage(pw.Page( |
29 | pageFormat: PdfPageFormat.a4, | 44 | pageFormat: PdfPageFormat.a4, |
30 | - build: (Context context) { | ||
31 | - return Center( | ||
32 | - child: Text("Hello World"), | 45 | + build: (pw.Context context) { |
46 | + return pw.Center( | ||
47 | + child: pw.Text("Hello World"), | ||
33 | ); // Center | 48 | ); // Center |
34 | })); // Page | 49 | })); // Page |
35 | ``` | 50 | ``` |
@@ -45,10 +60,10 @@ final image = PdfImage( | @@ -45,10 +60,10 @@ final image = PdfImage( | ||
45 | height: img.height, | 60 | height: img.height, |
46 | ); | 61 | ); |
47 | 62 | ||
48 | -pdf.addPage(Page( | ||
49 | - build: (Context context) { | ||
50 | - return Center( | ||
51 | - child: Image(image), | 63 | +pdf.addPage(pw.Page( |
64 | + build: (pw.Context context) { | ||
65 | + return pw.Center( | ||
66 | + child: pw.Image(image), | ||
52 | ); // Center | 67 | ); // Center |
53 | })); // Page | 68 | })); // Page |
54 | ``` | 69 | ``` |
@@ -57,13 +72,13 @@ To use a TrueType font: | @@ -57,13 +72,13 @@ To use a TrueType font: | ||
57 | 72 | ||
58 | ```dart | 73 | ```dart |
59 | final Uint8List fontData = File('open-sans.ttf').readAsBytesSync(); | 74 | final Uint8List fontData = File('open-sans.ttf').readAsBytesSync(); |
60 | -final ttf = Font.ttf(fontData.buffer.asByteData()); | 75 | +final ttf = pw.Font.ttf(fontData.buffer.asByteData()); |
61 | 76 | ||
62 | -pdf.addPage(Page( | 77 | +pdf.addPage(pw.Page( |
63 | pageFormat: PdfPageFormat.a4, | 78 | pageFormat: PdfPageFormat.a4, |
64 | - build: (Context context) { | ||
65 | - return Center( | ||
66 | - child: Text('Hello World', style: TextStyle(font: ttf, fontSize: 40)), | 79 | + build: (pw.Context context) { |
80 | + return pw.Center( | ||
81 | + child: pw.Text('Hello World', style: pw.TextStyle(font: ttf, fontSize: 40)), | ||
67 | ); // Center | 82 | ); // Center |
68 | })); // Page | 83 | })); // Page |
69 | ``` | 84 | ``` |
@@ -3,130 +3,132 @@ | @@ -3,130 +3,132 @@ | ||
3 | import 'dart:io'; | 3 | import 'dart:io'; |
4 | 4 | ||
5 | import 'package:pdf/pdf.dart'; | 5 | import 'package:pdf/pdf.dart'; |
6 | -import 'package:pdf/widgets.dart'; | 6 | +import 'package:pdf/widgets.dart' as pw; |
7 | 7 | ||
8 | void main() { | 8 | void main() { |
9 | - final Document pdf = Document(); | 9 | + final pw.Document doc = pw.Document(); |
10 | 10 | ||
11 | - pdf.addPage(MultiPage( | 11 | + doc.addPage(pw.MultiPage( |
12 | pageFormat: | 12 | pageFormat: |
13 | PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm), | 13 | PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm), |
14 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
15 | - header: (Context context) { | 14 | + crossAxisAlignment: pw.CrossAxisAlignment.start, |
15 | + header: (pw.Context context) { | ||
16 | if (context.pageNumber == 1) { | 16 | if (context.pageNumber == 1) { |
17 | return null; | 17 | return null; |
18 | } | 18 | } |
19 | - return Container( | ||
20 | - alignment: Alignment.centerRight, | ||
21 | - margin: const EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm), | ||
22 | - padding: const EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm), | ||
23 | - decoration: const BoxDecoration( | ||
24 | - border: | ||
25 | - BoxBorder(bottom: true, width: 0.5, color: PdfColors.grey)), | ||
26 | - child: Text('Portable Document Format', | ||
27 | - style: Theme.of(context) | 19 | + return pw.Container( |
20 | + alignment: pw.Alignment.centerRight, | ||
21 | + margin: const pw.EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm), | ||
22 | + padding: const pw.EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm), | ||
23 | + decoration: const pw.BoxDecoration( | ||
24 | + border: pw.BoxBorder( | ||
25 | + bottom: true, width: 0.5, color: PdfColors.grey)), | ||
26 | + child: pw.Text('Portable Document Format', | ||
27 | + style: pw.Theme.of(context) | ||
28 | .defaultTextStyle | 28 | .defaultTextStyle |
29 | .copyWith(color: PdfColors.grey))); | 29 | .copyWith(color: PdfColors.grey))); |
30 | }, | 30 | }, |
31 | - footer: (Context context) { | ||
32 | - return Container( | ||
33 | - alignment: Alignment.centerRight, | ||
34 | - margin: const EdgeInsets.only(top: 1.0 * PdfPageFormat.cm), | ||
35 | - child: Text('Page ${context.pageNumber} of ${context.pagesCount}', | ||
36 | - style: Theme.of(context) | 31 | + footer: (pw.Context context) { |
32 | + return pw.Container( | ||
33 | + alignment: pw.Alignment.centerRight, | ||
34 | + margin: const pw.EdgeInsets.only(top: 1.0 * PdfPageFormat.cm), | ||
35 | + child: pw.Text( | ||
36 | + 'Page ${context.pageNumber} of ${context.pagesCount}', | ||
37 | + style: pw.Theme.of(context) | ||
37 | .defaultTextStyle | 38 | .defaultTextStyle |
38 | .copyWith(color: PdfColors.grey))); | 39 | .copyWith(color: PdfColors.grey))); |
39 | }, | 40 | }, |
40 | - build: (Context context) => <Widget>[ | ||
41 | - Header( | 41 | + build: (pw.Context context) => <pw.Widget>[ |
42 | + pw.Header( | ||
42 | level: 0, | 43 | level: 0, |
43 | - child: Row( | ||
44 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
45 | - children: <Widget>[ | ||
46 | - Text('Portable Document Format', textScaleFactor: 2), | ||
47 | - PdfLogo() | 44 | + child: pw.Row( |
45 | + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, | ||
46 | + children: <pw.Widget>[ | ||
47 | + pw.Text('Portable Document Format', textScaleFactor: 2), | ||
48 | + pw.PdfLogo() | ||
48 | ])), | 49 | ])), |
49 | - Paragraph( | 50 | + pw.Paragraph( |
50 | text: | 51 | text: |
51 | 'The Portable Document Format (PDF) is a file format developed by Adobe in the 1990s to present documents, including text formatting and images, in a manner independent of application software, hardware, and operating systems. Based on the PostScript language, each PDF file encapsulates a complete description of a fixed-layout flat document, including the text, fonts, vector graphics, raster images and other information needed to display it. PDF was standardized as an open format, ISO 32000, in 2008, and no longer requires any royalties for its implementation.'), | 52 | 'The Portable Document Format (PDF) is a file format developed by Adobe in the 1990s to present documents, including text formatting and images, in a manner independent of application software, hardware, and operating systems. Based on the PostScript language, each PDF file encapsulates a complete description of a fixed-layout flat document, including the text, fonts, vector graphics, raster images and other information needed to display it. PDF was standardized as an open format, ISO 32000, in 2008, and no longer requires any royalties for its implementation.'), |
52 | - Paragraph( | 53 | + pw.Paragraph( |
53 | text: | 54 | text: |
54 | 'Today, PDF files may contain a variety of content besides flat text and graphics including logical structuring elements, interactive elements such as annotations and form-fields, layers, rich media (including video content) and three dimensional objects using U3D or PRC, and various other data formats. The PDF specification also provides for encryption and digital signatures, file attachments and metadata to enable workflows requiring these features.'), | 55 | 'Today, PDF files may contain a variety of content besides flat text and graphics including logical structuring elements, interactive elements such as annotations and form-fields, layers, rich media (including video content) and three dimensional objects using U3D or PRC, and various other data formats. The PDF specification also provides for encryption and digital signatures, file attachments and metadata to enable workflows requiring these features.'), |
55 | - Header(level: 1, text: 'History and standardization'), | ||
56 | - Paragraph( | 56 | + pw.Header(level: 1, text: 'History and standardization'), |
57 | + pw.Paragraph( | ||
57 | text: | 58 | text: |
58 | "Adobe Systems made the PDF specification available free of charge in 1993. In the early years PDF was popular mainly in desktop publishing workflows, and competed with a variety of formats such as DjVu, Envoy, Common Ground Digital Paper, Farallon Replica and even Adobe's own PostScript format."), | 59 | "Adobe Systems made the PDF specification available free of charge in 1993. In the early years PDF was popular mainly in desktop publishing workflows, and competed with a variety of formats such as DjVu, Envoy, Common Ground Digital Paper, Farallon Replica and even Adobe's own PostScript format."), |
59 | - Paragraph( | 60 | + pw.Paragraph( |
60 | text: | 61 | text: |
61 | 'PDF was a proprietary format controlled by Adobe until it was released as an open standard on July 1, 2008, and published by the International Organization for Standardization as ISO 32000-1:2008, at which time control of the specification passed to an ISO Committee of volunteer industry experts. In 2008, Adobe published a Public Patent License to ISO 32000-1 granting royalty-free rights for all patents owned by Adobe that are necessary to make, use, sell, and distribute PDF compliant implementations.'), | 62 | 'PDF was a proprietary format controlled by Adobe until it was released as an open standard on July 1, 2008, and published by the International Organization for Standardization as ISO 32000-1:2008, at which time control of the specification passed to an ISO Committee of volunteer industry experts. In 2008, Adobe published a Public Patent License to ISO 32000-1 granting royalty-free rights for all patents owned by Adobe that are necessary to make, use, sell, and distribute PDF compliant implementations.'), |
62 | - Paragraph( | 63 | + pw.Paragraph( |
63 | text: | 64 | text: |
64 | "PDF 1.7, the sixth edition of the PDF specification that became ISO 32000-1, includes some proprietary technologies defined only by Adobe, such as Adobe XML Forms Architecture (XFA) and JavaScript extension for Acrobat, which are referenced by ISO 32000-1 as normative and indispensable for the full implementation of the ISO 32000-1 specification. These proprietary technologies are not standardized and their specification is published only on Adobe's website. Many of them are also not supported by popular third-party implementations of PDF."), | 65 | "PDF 1.7, the sixth edition of the PDF specification that became ISO 32000-1, includes some proprietary technologies defined only by Adobe, such as Adobe XML Forms Architecture (XFA) and JavaScript extension for Acrobat, which are referenced by ISO 32000-1 as normative and indispensable for the full implementation of the ISO 32000-1 specification. These proprietary technologies are not standardized and their specification is published only on Adobe's website. Many of them are also not supported by popular third-party implementations of PDF."), |
65 | - Paragraph( | 66 | + pw.Paragraph( |
66 | text: | 67 | text: |
67 | 'On July 28, 2017, ISO 32000-2:2017 (PDF 2.0) was published. ISO 32000-2 does not include any proprietary technologies as normative references.'), | 68 | 'On July 28, 2017, ISO 32000-2:2017 (PDF 2.0) was published. ISO 32000-2 does not include any proprietary technologies as normative references.'), |
68 | - Header(level: 1, text: 'Technical foundations'), | ||
69 | - Paragraph(text: 'The PDF combines three technologies:'), | ||
70 | - Bullet( | 69 | + pw.Header(level: 1, text: 'Technical foundations'), |
70 | + pw.Paragraph(text: 'The PDF combines three technologies:'), | ||
71 | + pw.Bullet( | ||
71 | text: | 72 | text: |
72 | 'A subset of the PostScript page description programming language, for generating the layout and graphics.'), | 73 | 'A subset of the PostScript page description programming language, for generating the layout and graphics.'), |
73 | - Bullet( | 74 | + pw.Bullet( |
74 | text: | 75 | text: |
75 | 'A font-embedding/replacement system to allow fonts to travel with the documents.'), | 76 | 'A font-embedding/replacement system to allow fonts to travel with the documents.'), |
76 | - Bullet( | 77 | + pw.Bullet( |
77 | text: | 78 | text: |
78 | 'A structured storage system to bundle these elements and any associated content into a single file, with data compression where appropriate.'), | 79 | 'A structured storage system to bundle these elements and any associated content into a single file, with data compression where appropriate.'), |
79 | - Header(level: 2, text: 'PostScript'), | ||
80 | - Paragraph( | 80 | + pw.Header(level: 2, text: 'PostScript'), |
81 | + pw.Paragraph( | ||
81 | text: | 82 | text: |
82 | 'PostScript is a page description language run in an interpreter to generate an image, a process requiring many resources. It can handle graphics and standard features of programming languages such as if and loop commands. PDF is largely based on PostScript but simplified to remove flow control features like these, while graphics commands such as lineto remain.'), | 83 | 'PostScript is a page description language run in an interpreter to generate an image, a process requiring many resources. It can handle graphics and standard features of programming languages such as if and loop commands. PDF is largely based on PostScript but simplified to remove flow control features like these, while graphics commands such as lineto remain.'), |
83 | - Paragraph( | 84 | + pw.Paragraph( |
84 | text: | 85 | text: |
85 | 'Often, the PostScript-like PDF code is generated from a source PostScript file. The graphics commands that are output by the PostScript code are collected and tokenized. Any files, graphics, or fonts to which the document refers also are collected. Then, everything is compressed to a single file. Therefore, the entire PostScript world (fonts, layout, measurements) remains intact.'), | 86 | 'Often, the PostScript-like PDF code is generated from a source PostScript file. The graphics commands that are output by the PostScript code are collected and tokenized. Any files, graphics, or fonts to which the document refers also are collected. Then, everything is compressed to a single file. Therefore, the entire PostScript world (fonts, layout, measurements) remains intact.'), |
86 | - Column( | ||
87 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
88 | - children: <Widget>[ | ||
89 | - Paragraph( | 87 | + pw.Column( |
88 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
89 | + children: <pw.Widget>[ | ||
90 | + pw.Paragraph( | ||
90 | text: | 91 | text: |
91 | 'As a document format, PDF has several advantages over PostScript:'), | 92 | 'As a document format, PDF has several advantages over PostScript:'), |
92 | - Bullet( | 93 | + pw.Bullet( |
93 | text: | 94 | text: |
94 | 'PDF contains tokenized and interpreted results of the PostScript source code, for direct correspondence between changes to items in the PDF page description and changes to the resulting page appearance.'), | 95 | 'PDF contains tokenized and interpreted results of the PostScript source code, for direct correspondence between changes to items in the PDF page description and changes to the resulting page appearance.'), |
95 | - Bullet( | 96 | + pw.Bullet( |
96 | text: | 97 | text: |
97 | 'PDF (from version 1.4) supports graphic transparency; PostScript does not.'), | 98 | 'PDF (from version 1.4) supports graphic transparency; PostScript does not.'), |
98 | - Bullet( | 99 | + pw.Bullet( |
99 | text: | 100 | text: |
100 | 'PostScript is an interpreted programming language with an implicit global state, so instructions accompanying the description of one page can affect the appearance of any following page. Therefore, all preceding pages in a PostScript document must be processed to determine the correct appearance of a given page, whereas each page in a PDF document is unaffected by the others. As a result, PDF viewers allow the user to quickly jump to the final pages of a long document, whereas a PostScript viewer needs to process all pages sequentially before being able to display the destination page (unless the optional PostScript Document Structuring Conventions have been carefully complied with).'), | 101 | 'PostScript is an interpreted programming language with an implicit global state, so instructions accompanying the description of one page can affect the appearance of any following page. Therefore, all preceding pages in a PostScript document must be processed to determine the correct appearance of a given page, whereas each page in a PDF document is unaffected by the others. As a result, PDF viewers allow the user to quickly jump to the final pages of a long document, whereas a PostScript viewer needs to process all pages sequentially before being able to display the destination page (unless the optional PostScript Document Structuring Conventions have been carefully complied with).'), |
101 | ]), | 102 | ]), |
102 | - Header(level: 1, text: 'Content'), | ||
103 | - Paragraph( | 103 | + pw.Header(level: 1, text: 'Content'), |
104 | + pw.Paragraph( | ||
104 | text: | 105 | text: |
105 | 'A PDF file is often a combination of vector graphics, text, and bitmap graphics. The basic types of content in a PDF are:'), | 106 | 'A PDF file is often a combination of vector graphics, text, and bitmap graphics. The basic types of content in a PDF are:'), |
106 | - Bullet( | 107 | + pw.Bullet( |
107 | text: | 108 | text: |
108 | 'Text stored as content streams (i.e., not encoded in plain text)'), | 109 | 'Text stored as content streams (i.e., not encoded in plain text)'), |
109 | - Bullet( | 110 | + pw.Bullet( |
110 | text: | 111 | text: |
111 | 'Vector graphics for illustrations and designs that consist of shapes and lines'), | 112 | 'Vector graphics for illustrations and designs that consist of shapes and lines'), |
112 | - Bullet( | 113 | + pw.Bullet( |
113 | text: | 114 | text: |
114 | 'Raster graphics for photographs and other types of image'), | 115 | 'Raster graphics for photographs and other types of image'), |
115 | - Bullet(text: 'Multimedia objects in the document'), | ||
116 | - Paragraph( | 116 | + pw.Bullet(text: 'Multimedia objects in the document'), |
117 | + pw.Paragraph( | ||
117 | text: | 118 | text: |
118 | 'In later PDF revisions, a PDF document can also support links (inside document or web page), forms, JavaScript (initially available as plugin for Acrobat 3.0), or any other types of embedded contents that can be handled using plug-ins.'), | 119 | 'In later PDF revisions, a PDF document can also support links (inside document or web page), forms, JavaScript (initially available as plugin for Acrobat 3.0), or any other types of embedded contents that can be handled using plug-ins.'), |
119 | - Paragraph( | 120 | + pw.Paragraph( |
120 | text: | 121 | text: |
121 | 'PDF 1.6 supports interactive 3D documents embedded in the PDF - 3D drawings can be embedded using U3D or PRC and various other data formats.'), | 122 | 'PDF 1.6 supports interactive 3D documents embedded in the PDF - 3D drawings can be embedded using U3D or PRC and various other data formats.'), |
122 | - Paragraph( | 123 | + pw.Paragraph( |
123 | text: | 124 | text: |
124 | 'Two PDF files that look similar on a computer screen may be of very different sizes. For example, a high resolution raster image takes more space than a low resolution one. Typically higher resolution is needed for printing documents than for displaying them on screen. Other things that may increase the size of a file is embedding full fonts, especially for Asiatic scripts, and storing text as graphics. '), | 125 | 'Two PDF files that look similar on a computer screen may be of very different sizes. For example, a high resolution raster image takes more space than a low resolution one. Typically higher resolution is needed for printing documents than for displaying them on screen. Other things that may increase the size of a file is embedding full fonts, especially for Asiatic scripts, and storing text as graphics. '), |
125 | - Header(level: 1, text: 'File formats and Adobe Acrobat versions'), | ||
126 | - Paragraph( | 126 | + pw.Header( |
127 | + level: 1, text: 'File formats and Adobe Acrobat versions'), | ||
128 | + pw.Paragraph( | ||
127 | text: | 129 | text: |
128 | 'The PDF file format has changed several times, and continues to evolve, along with the release of new versions of Adobe Acrobat. There have been nine versions of PDF and the corresponding version of the software:'), | 130 | 'The PDF file format has changed several times, and continues to evolve, along with the release of new versions of Adobe Acrobat. There have been nine versions of PDF and the corresponding version of the software:'), |
129 | - Table.fromTextArray(context: context, data: const <List<String>>[ | 131 | + pw.Table.fromTextArray(context: context, data: const <List<String>>[ |
130 | <String>['Date', 'PDF Version', 'Acrobat Version'], | 132 | <String>['Date', 'PDF Version', 'Acrobat Version'], |
131 | <String>['1993', 'PDF 1.0', 'Acrobat 1'], | 133 | <String>['1993', 'PDF 1.0', 'Acrobat 1'], |
132 | <String>['1994', 'PDF 1.1', 'Acrobat 2'], | 134 | <String>['1994', 'PDF 1.1', 'Acrobat 2'], |
@@ -142,12 +144,12 @@ void main() { | @@ -142,12 +144,12 @@ void main() { | ||
142 | <String>['2012', 'PDF 1.7', 'Acrobat XI'], | 144 | <String>['2012', 'PDF 1.7', 'Acrobat XI'], |
143 | <String>['2017', 'PDF 2.0', 'Acrobat DC'], | 145 | <String>['2017', 'PDF 2.0', 'Acrobat DC'], |
144 | ]), | 146 | ]), |
145 | - Padding(padding: const EdgeInsets.all(10)), | ||
146 | - Paragraph( | 147 | + pw.Padding(padding: const pw.EdgeInsets.all(10)), |
148 | + pw.Paragraph( | ||
147 | text: | 149 | text: |
148 | 'Text is available under the Creative Commons Attribution Share Alike License.') | 150 | 'Text is available under the Creative Commons Attribution Share Alike License.') |
149 | ])); | 151 | ])); |
150 | 152 | ||
151 | final File file = File('example.pdf'); | 153 | final File file = File('example.pdf'); |
152 | - file.writeAsBytesSync(pdf.save()); | 154 | + file.writeAsBytesSync(doc.save()); |
153 | } | 155 | } |
@@ -15,16 +15,46 @@ for documentation. | @@ -15,16 +15,46 @@ for documentation. | ||
15 | 15 | ||
16 | [](https://www.buymeacoffee.com/JORBmbw9h "Buy Me A Coffee") | 16 | [](https://www.buymeacoffee.com/JORBmbw9h "Buy Me A Coffee") |
17 | 17 | ||
18 | -Example: | 18 | +## Installing |
19 | + | ||
20 | +1. Add this package to your package's `pubspec.yaml` file as described | ||
21 | + on the installation tab | ||
22 | + | ||
23 | +2. Import the libraries | ||
24 | + | ||
25 | + ```dart | ||
26 | + import 'package:pdf/pdf.dart'; | ||
27 | + import 'package:pdf/widgets.dart' as pw; | ||
28 | + import 'package:printing/printing.dart'; | ||
29 | + ``` | ||
30 | + | ||
31 | +3. Enable Swift on the iOS project, in `ios/Podfile`: | ||
32 | + | ||
33 | + ```Ruby | ||
34 | + target 'Runner' do | ||
35 | + use_frameworks! # <-- Add this line | ||
36 | + ``` | ||
37 | + | ||
38 | +4. Set minimum Android version in `android/app/build.gradle`: | ||
39 | + | ||
40 | + ```java | ||
41 | + defaultConfig { | ||
42 | + ... | ||
43 | + minSdkVersion 21 // <-- Change this line to 21 or more | ||
44 | + ... | ||
45 | + } | ||
46 | + ``` | ||
47 | + | ||
48 | +## Examples | ||
19 | 49 | ||
20 | ```dart | 50 | ```dart |
21 | -final pdf = Document(); | 51 | +final doc = pw.Document(); |
22 | 52 | ||
23 | -pdf.addPage(Page( | 53 | +doc.addPage(pw.Page( |
24 | pageFormat: PdfPageFormat.a4, | 54 | pageFormat: PdfPageFormat.a4, |
25 | - build: (Context context) { | ||
26 | - return Center( | ||
27 | - child: Text("Hello World"), | 55 | + build: (pw.Context context) { |
56 | + return pw.Center( | ||
57 | + child: pw.Text("Hello World"), | ||
28 | ); // Center | 58 | ); // Center |
29 | })); // Page | 59 | })); // Page |
30 | ``` | 60 | ``` |
@@ -33,12 +63,12 @@ To load an image from an ImageProvider: | @@ -33,12 +63,12 @@ To load an image from an ImageProvider: | ||
33 | 63 | ||
34 | ```dart | 64 | ```dart |
35 | const imageProvider = const AssetImage('assets/image.png'); | 65 | const imageProvider = const AssetImage('assets/image.png'); |
36 | -final PdfImage image = await pdfImageFromImageProvider(pdf: pdf.document, image: imageProvider); | 66 | +final PdfImage image = await pdfImageFromImageProvider(pdf: doc.document, image: imageProvider); |
37 | 67 | ||
38 | -pdf.addPage(Page( | ||
39 | - build: (Context context) { | ||
40 | - return Center( | ||
41 | - child: Image(image), | 68 | +doc.addPage(pw.Page( |
69 | + build: (pw.Context context) { | ||
70 | + return pw.Center( | ||
71 | + child: pw.Image(image), | ||
42 | ); // Center | 72 | ); // Center |
43 | })); // Page | 73 | })); // Page |
44 | ``` | 74 | ``` |
@@ -47,12 +77,12 @@ To use a TrueType font from a flutter bundle: | @@ -47,12 +77,12 @@ To use a TrueType font from a flutter bundle: | ||
47 | 77 | ||
48 | ```dart | 78 | ```dart |
49 | final font = await rootBundle.load("assets/open-sans.ttf"); | 79 | final font = await rootBundle.load("assets/open-sans.ttf"); |
50 | -final ttf = Font.ttf(font); | 80 | +final ttf = pw.Font.ttf(font); |
51 | 81 | ||
52 | -pdf.addPage(Page( | ||
53 | - build: (Context context) { | ||
54 | - return Center( | ||
55 | - child: Text('Dart is awesome', style: TextStyle(font: ttf, fontSize: 40)), | 82 | +doc.addPage(pw.Page( |
83 | + build: (pw.Context context) { | ||
84 | + return pw.Center( | ||
85 | + child: pw.Text('Dart is awesome', style: pw.TextStyle(font: ttf, fontSize: 40)), | ||
56 | ); // Center | 86 | ); // Center |
57 | })); // Page | 87 | })); // Page |
58 | ``` | 88 | ``` |
@@ -62,20 +92,20 @@ To save the pdf file using the [path_provider](https://pub.dev/packages/path_pro | @@ -62,20 +92,20 @@ To save the pdf file using the [path_provider](https://pub.dev/packages/path_pro | ||
62 | ```dart | 92 | ```dart |
63 | final output = await getTemporaryDirectory(); | 93 | final output = await getTemporaryDirectory(); |
64 | final file = File("${output.path}/example.pdf"); | 94 | final file = File("${output.path}/example.pdf"); |
65 | -await file.writeAsBytes(pdf.save()); | 95 | +await file.writeAsBytes(doc.save()); |
66 | ``` | 96 | ``` |
67 | 97 | ||
68 | You can also print the document using the iOS or Android print service: | 98 | You can also print the document using the iOS or Android print service: |
69 | 99 | ||
70 | ```dart | 100 | ```dart |
71 | await Printing.layoutPdf( | 101 | await Printing.layoutPdf( |
72 | - onLayout: (PdfPageFormat format) async => pdf.save()); | 102 | + onLayout: (PdfPageFormat format) async => doc.save()); |
73 | ``` | 103 | ``` |
74 | 104 | ||
75 | Or share the document to other applications: | 105 | Or share the document to other applications: |
76 | 106 | ||
77 | ```dart | 107 | ```dart |
78 | -await Printing.sharePdf(bytes: pdf.save(), filename: 'my-document.pdf'); | 108 | +await Printing.sharePdf(bytes: doc.save(), filename: 'my-document.pdf'); |
79 | ``` | 109 | ``` |
80 | 110 | ||
81 | To print an HTML document: | 111 | To print an HTML document: |
@@ -91,29 +121,8 @@ await Printing.layoutPdf( | @@ -91,29 +121,8 @@ await Printing.layoutPdf( | ||
91 | Convert a Pdf to images, one image per page, get only pages 1 and 2 at 72 dpi: | 121 | Convert a Pdf to images, one image per page, get only pages 1 and 2 at 72 dpi: |
92 | 122 | ||
93 | ```dart | 123 | ```dart |
94 | -await for (var page in Printing.raster(pdf.save(), pages: [0, 1], dpi: 72)) { | ||
95 | - final image = page.toImage(); | ||
96 | - // ...or page.toPng() | 124 | +await for (var page in Printing.raster(doc.save(), pages: [0, 1], dpi: 72)) { |
125 | + final image = page.toImage(); // ...or page.toPng() | ||
126 | + print(image); | ||
97 | } | 127 | } |
98 | ``` | 128 | ``` |
99 | - | ||
100 | -## Installing | ||
101 | - | ||
102 | -1. Add this package to your package's `pubspec.yaml` file as described on the installation tab | ||
103 | - | ||
104 | -2. Enable Swift on the iOS project, in `ios/Podfile`: | ||
105 | - | ||
106 | - ```Ruby | ||
107 | - target 'Runner' do | ||
108 | - use_frameworks! # <-- Add this line | ||
109 | - ``` | ||
110 | - | ||
111 | -3. Set minimum Android version in `android/app/build.gradle`: | ||
112 | - | ||
113 | - ```java | ||
114 | - defaultConfig { | ||
115 | - ... | ||
116 | - minSdkVersion 21 // <-- Change this line to 21 or more | ||
117 | - ... | ||
118 | - } | ||
119 | - ``` |
1 | import 'dart:async'; | 1 | import 'dart:async'; |
2 | 2 | ||
3 | import 'package:flutter/foundation.dart' show kIsWeb; | 3 | import 'package:flutter/foundation.dart' show kIsWeb; |
4 | -import 'package:flutter/widgets.dart' as fw; | 4 | +import 'package:flutter/widgets.dart'; |
5 | import 'package:pdf/pdf.dart'; | 5 | import 'package:pdf/pdf.dart'; |
6 | -import 'package:pdf/widgets.dart'; | 6 | +import 'package:pdf/widgets.dart' as pw; |
7 | import 'package:printing/printing.dart'; | 7 | import 'package:printing/printing.dart'; |
8 | 8 | ||
9 | import 'example_widgets.dart'; | 9 | import 'example_widgets.dart'; |
10 | 10 | ||
11 | -Future<Document> generateDocument(PdfPageFormat format) async { | ||
12 | - final Document pdf = Document(title: 'My Résumé', author: 'David PHAM-VAN'); | 11 | +Future<pw.Document> generateDocument(PdfPageFormat format) async { |
12 | + final pw.Document doc = | ||
13 | + pw.Document(title: 'My Résumé', author: 'David PHAM-VAN'); | ||
13 | 14 | ||
14 | final PdfImage profileImage = kIsWeb | 15 | final PdfImage profileImage = kIsWeb |
15 | ? null | 16 | ? null |
16 | : await pdfImageFromImageProvider( | 17 | : await pdfImageFromImageProvider( |
17 | - pdf: pdf.document, | ||
18 | - image: const fw.NetworkImage( | 18 | + pdf: doc.document, |
19 | + image: const NetworkImage( | ||
19 | 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&s=200'), | 20 | 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&s=200'), |
20 | onError: (dynamic exception, StackTrace stackTrace) { | 21 | onError: (dynamic exception, StackTrace stackTrace) { |
21 | print('Unable to download image'); | 22 | print('Unable to download image'); |
22 | }); | 23 | }); |
23 | 24 | ||
24 | - final PageTheme pageTheme = myPageTheme(format); | 25 | + final pw.PageTheme pageTheme = myPageTheme(format); |
25 | 26 | ||
26 | - pdf.addPage(Page( | 27 | + doc.addPage(pw.Page( |
27 | pageTheme: pageTheme, | 28 | pageTheme: pageTheme, |
28 | - build: (Context context) => Row(children: <Widget>[ | ||
29 | - Expanded( | ||
30 | - child: Column( | ||
31 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
32 | - children: <Widget>[ | ||
33 | - Container( | ||
34 | - padding: const EdgeInsets.only(left: 30, bottom: 20), | ||
35 | - child: Column( | ||
36 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
37 | - children: <Widget>[ | ||
38 | - Text('Parnella Charlesbois', | 29 | + build: (pw.Context context) => pw.Row(children: <pw.Widget>[ |
30 | + pw.Expanded( | ||
31 | + child: pw.Column( | ||
32 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
33 | + children: <pw.Widget>[ | ||
34 | + pw.Container( | ||
35 | + padding: const pw.EdgeInsets.only(left: 30, bottom: 20), | ||
36 | + child: pw.Column( | ||
37 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
38 | + children: <pw.Widget>[ | ||
39 | + pw.Text('Parnella Charlesbois', | ||
39 | textScaleFactor: 2, | 40 | textScaleFactor: 2, |
40 | - style: Theme.of(context) | 41 | + style: pw.Theme.of(context) |
41 | .defaultTextStyle | 42 | .defaultTextStyle |
42 | - .copyWith(fontWeight: FontWeight.bold)), | ||
43 | - Padding(padding: const EdgeInsets.only(top: 10)), | ||
44 | - Text('Electrotyper', | 43 | + .copyWith(fontWeight: pw.FontWeight.bold)), |
44 | + pw.Padding(padding: const pw.EdgeInsets.only(top: 10)), | ||
45 | + pw.Text('Electrotyper', | ||
45 | textScaleFactor: 1.2, | 46 | textScaleFactor: 1.2, |
46 | - style: Theme.of(context).defaultTextStyle.copyWith( | ||
47 | - fontWeight: FontWeight.bold, color: green)), | ||
48 | - Padding(padding: const EdgeInsets.only(top: 20)), | ||
49 | - Row( | ||
50 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
51 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
52 | - children: <Widget>[ | ||
53 | - Column( | ||
54 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
55 | - children: <Widget>[ | ||
56 | - Text('568 Port Washington Road'), | ||
57 | - Text('Nordegg, AB T0M 2H0'), | ||
58 | - Text('Canada, ON'), | 47 | + style: pw.Theme.of(context).defaultTextStyle.copyWith( |
48 | + fontWeight: pw.FontWeight.bold, color: green)), | ||
49 | + pw.Padding(padding: const pw.EdgeInsets.only(top: 20)), | ||
50 | + pw.Row( | ||
51 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
52 | + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, | ||
53 | + children: <pw.Widget>[ | ||
54 | + pw.Column( | ||
55 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
56 | + children: <pw.Widget>[ | ||
57 | + pw.Text('568 Port Washington Road'), | ||
58 | + pw.Text('Nordegg, AB T0M 2H0'), | ||
59 | + pw.Text('Canada, ON'), | ||
59 | ]), | 60 | ]), |
60 | - Column( | ||
61 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
62 | - children: <Widget>[ | ||
63 | - Text('+1 403-721-6898'), | 61 | + pw.Column( |
62 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
63 | + children: <pw.Widget>[ | ||
64 | + pw.Text('+1 403-721-6898'), | ||
64 | UrlText('p.charlesbois@yahoo.com', | 65 | UrlText('p.charlesbois@yahoo.com', |
65 | 'mailto:p.charlesbois@yahoo.com'), | 66 | 'mailto:p.charlesbois@yahoo.com'), |
66 | UrlText('wholeprices.ca', | 67 | UrlText('wholeprices.ca', |
67 | 'https://wholeprices.ca'), | 68 | 'https://wholeprices.ca'), |
68 | ]), | 69 | ]), |
69 | - Padding(padding: EdgeInsets.zero) | 70 | + pw.Padding(padding: pw.EdgeInsets.zero) |
70 | ]), | 71 | ]), |
71 | ])), | 72 | ])), |
72 | Category(title: 'Work Experience'), | 73 | Category(title: 'Work Experience'), |
@@ -77,32 +78,32 @@ Future<Document> generateDocument(PdfPageFormat format) async { | @@ -77,32 +78,32 @@ Future<Document> generateDocument(PdfPageFormat format) async { | ||
77 | Block(title: 'Bachelor Of Commerce'), | 78 | Block(title: 'Bachelor Of Commerce'), |
78 | Block(title: 'Bachelor Interior Design'), | 79 | Block(title: 'Bachelor Interior Design'), |
79 | ])), | 80 | ])), |
80 | - Container( | 81 | + pw.Container( |
81 | height: double.infinity, | 82 | height: double.infinity, |
82 | width: 2, | 83 | width: 2, |
83 | - margin: const EdgeInsets.symmetric(horizontal: 5), | 84 | + margin: const pw.EdgeInsets.symmetric(horizontal: 5), |
84 | color: green, | 85 | color: green, |
85 | ), | 86 | ), |
86 | - Column( | ||
87 | - crossAxisAlignment: CrossAxisAlignment.center, | ||
88 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
89 | - children: <Widget>[ | ||
90 | - ClipOval( | ||
91 | - child: Container( | 87 | + pw.Column( |
88 | + crossAxisAlignment: pw.CrossAxisAlignment.center, | ||
89 | + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, | ||
90 | + children: <pw.Widget>[ | ||
91 | + pw.ClipOval( | ||
92 | + child: pw.Container( | ||
92 | width: 100, | 93 | width: 100, |
93 | height: 100, | 94 | height: 100, |
94 | color: lightGreen, | 95 | color: lightGreen, |
95 | child: profileImage == null | 96 | child: profileImage == null |
96 | - ? Container() | ||
97 | - : Image(profileImage))), | ||
98 | - Column(children: <Widget>[ | ||
99 | - Percent(size: 60, value: .7, title: Text('Word')), | ||
100 | - Percent(size: 60, value: .4, title: Text('Excel')), | 97 | + ? pw.Container() |
98 | + : pw.Image(profileImage))), | ||
99 | + pw.Column(children: <pw.Widget>[ | ||
100 | + Percent(size: 60, value: .7, title: pw.Text('Word')), | ||
101 | + Percent(size: 60, value: .4, title: pw.Text('Excel')), | ||
101 | ]), | 102 | ]), |
102 | - QrCodeWidget(data: 'Parnella Charlesbois', size: 60), | 103 | + pw.QrCodeWidget(data: 'Parnella Charlesbois', size: 60), |
103 | ], | 104 | ], |
104 | ) | 105 | ) |
105 | ]), | 106 | ]), |
106 | )); | 107 | )); |
107 | - return pdf; | 108 | + return doc; |
108 | } | 109 | } |
1 | import 'package:meta/meta.dart'; | 1 | import 'package:meta/meta.dart'; |
2 | import 'package:pdf/pdf.dart'; | 2 | import 'package:pdf/pdf.dart'; |
3 | -import 'package:pdf/widgets.dart'; | 3 | +import 'package:pdf/widgets.dart' as pw; |
4 | 4 | ||
5 | const PdfColor green = PdfColor.fromInt(0xff9ce5d0); | 5 | const PdfColor green = PdfColor.fromInt(0xff9ce5d0); |
6 | const PdfColor lightGreen = PdfColor.fromInt(0xffcdf1e7); | 6 | const PdfColor lightGreen = PdfColor.fromInt(0xffcdf1e7); |
7 | 7 | ||
8 | -PageTheme myPageTheme(PdfPageFormat format) { | ||
9 | - return PageTheme( | 8 | +pw.PageTheme myPageTheme(PdfPageFormat format) { |
9 | + return pw.PageTheme( | ||
10 | pageFormat: format.applyMargin( | 10 | pageFormat: format.applyMargin( |
11 | left: 2.0 * PdfPageFormat.cm, | 11 | left: 2.0 * PdfPageFormat.cm, |
12 | top: 4.0 * PdfPageFormat.cm, | 12 | top: 4.0 * PdfPageFormat.cm, |
13 | right: 2.0 * PdfPageFormat.cm, | 13 | right: 2.0 * PdfPageFormat.cm, |
14 | bottom: 2.0 * PdfPageFormat.cm), | 14 | bottom: 2.0 * PdfPageFormat.cm), |
15 | - buildBackground: (Context context) { | ||
16 | - return FullPage( | 15 | + buildBackground: (pw.Context context) { |
16 | + return pw.FullPage( | ||
17 | ignoreMargins: true, | 17 | ignoreMargins: true, |
18 | - child: CustomPaint( | 18 | + child: pw.CustomPaint( |
19 | size: PdfPoint(format.width, format.height), | 19 | size: PdfPoint(format.width, format.height), |
20 | painter: (PdfGraphics canvas, PdfPoint size) { | 20 | painter: (PdfGraphics canvas, PdfPoint size) { |
21 | context.canvas | 21 | context.canvas |
@@ -55,60 +55,62 @@ PageTheme myPageTheme(PdfPageFormat format) { | @@ -55,60 +55,62 @@ PageTheme myPageTheme(PdfPageFormat format) { | ||
55 | ); | 55 | ); |
56 | } | 56 | } |
57 | 57 | ||
58 | -class Block extends StatelessWidget { | 58 | +class Block extends pw.StatelessWidget { |
59 | Block({this.title}); | 59 | Block({this.title}); |
60 | 60 | ||
61 | final String title; | 61 | final String title; |
62 | 62 | ||
63 | @override | 63 | @override |
64 | - Widget build(Context context) { | ||
65 | - return Column( | ||
66 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
67 | - children: <Widget>[ | ||
68 | - Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ | ||
69 | - Container( | 64 | + pw.Widget build(pw.Context context) { |
65 | + return pw.Column( | ||
66 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
67 | + children: <pw.Widget>[ | ||
68 | + pw.Row( | ||
69 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
70 | + children: <pw.Widget>[ | ||
71 | + pw.Container( | ||
70 | width: 6, | 72 | width: 6, |
71 | height: 6, | 73 | height: 6, |
72 | - margin: const EdgeInsets.only(top: 2.5, left: 2, right: 5), | ||
73 | - decoration: | ||
74 | - const BoxDecoration(color: green, shape: BoxShape.circle), | 74 | + margin: const pw.EdgeInsets.only(top: 2.5, left: 2, right: 5), |
75 | + decoration: const pw.BoxDecoration( | ||
76 | + color: green, shape: pw.BoxShape.circle), | ||
75 | ), | 77 | ), |
76 | - Text(title, | ||
77 | - style: Theme.of(context) | 78 | + pw.Text(title, |
79 | + style: pw.Theme.of(context) | ||
78 | .defaultTextStyle | 80 | .defaultTextStyle |
79 | - .copyWith(fontWeight: FontWeight.bold)), | 81 | + .copyWith(fontWeight: pw.FontWeight.bold)), |
80 | ]), | 82 | ]), |
81 | - Container( | ||
82 | - decoration: const BoxDecoration( | ||
83 | - border: BoxBorder(left: true, color: green, width: 2)), | ||
84 | - padding: const EdgeInsets.only(left: 10, top: 5, bottom: 5), | ||
85 | - margin: const EdgeInsets.only(left: 5), | ||
86 | - child: Column( | ||
87 | - crossAxisAlignment: CrossAxisAlignment.start, | ||
88 | - children: <Widget>[ | ||
89 | - Lorem(length: 20), | 83 | + pw.Container( |
84 | + decoration: const pw.BoxDecoration( | ||
85 | + border: pw.BoxBorder(left: true, color: green, width: 2)), | ||
86 | + padding: const pw.EdgeInsets.only(left: 10, top: 5, bottom: 5), | ||
87 | + margin: const pw.EdgeInsets.only(left: 5), | ||
88 | + child: pw.Column( | ||
89 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
90 | + children: <pw.Widget>[ | ||
91 | + pw.Lorem(length: 20), | ||
90 | ]), | 92 | ]), |
91 | ), | 93 | ), |
92 | ]); | 94 | ]); |
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ||
96 | -class Category extends StatelessWidget { | 98 | +class Category extends pw.StatelessWidget { |
97 | Category({this.title}); | 99 | Category({this.title}); |
98 | 100 | ||
99 | final String title; | 101 | final String title; |
100 | 102 | ||
101 | @override | 103 | @override |
102 | - Widget build(Context context) { | ||
103 | - return Container( | ||
104 | - decoration: const BoxDecoration(color: lightGreen, borderRadius: 6), | ||
105 | - margin: const EdgeInsets.only(bottom: 10, top: 20), | ||
106 | - padding: const EdgeInsets.fromLTRB(10, 7, 10, 4), | ||
107 | - child: Text(title, textScaleFactor: 1.5)); | 104 | + pw.Widget build(pw.Context context) { |
105 | + return pw.Container( | ||
106 | + decoration: const pw.BoxDecoration(color: lightGreen, borderRadius: 6), | ||
107 | + margin: const pw.EdgeInsets.only(bottom: 10, top: 20), | ||
108 | + padding: const pw.EdgeInsets.fromLTRB(10, 7, 10, 4), | ||
109 | + child: pw.Text(title, textScaleFactor: 1.5)); | ||
108 | } | 110 | } |
109 | } | 111 | } |
110 | 112 | ||
111 | -class Percent extends StatelessWidget { | 113 | +class Percent extends pw.StatelessWidget { |
112 | Percent({ | 114 | Percent({ |
113 | @required this.size, | 115 | @required this.size, |
114 | @required this.value, | 116 | @required this.value, |
@@ -123,7 +125,7 @@ class Percent extends StatelessWidget { | @@ -123,7 +125,7 @@ class Percent extends StatelessWidget { | ||
123 | 125 | ||
124 | final double value; | 126 | final double value; |
125 | 127 | ||
126 | - final Widget title; | 128 | + final pw.Widget title; |
127 | 129 | ||
128 | final double fontSize; | 130 | final double fontSize; |
129 | 131 | ||
@@ -134,22 +136,22 @@ class Percent extends StatelessWidget { | @@ -134,22 +136,22 @@ class Percent extends StatelessWidget { | ||
134 | final double strokeWidth; | 136 | final double strokeWidth; |
135 | 137 | ||
136 | @override | 138 | @override |
137 | - Widget build(Context context) { | ||
138 | - final List<Widget> widgets = <Widget>[ | ||
139 | - Container( | 139 | + pw.Widget build(pw.Context context) { |
140 | + final List<pw.Widget> widgets = <pw.Widget>[ | ||
141 | + pw.Container( | ||
140 | width: size, | 142 | width: size, |
141 | height: size, | 143 | height: size, |
142 | - child: Stack( | ||
143 | - alignment: Alignment.center, | ||
144 | - fit: StackFit.expand, | ||
145 | - children: <Widget>[ | ||
146 | - Center( | ||
147 | - child: Text( | 144 | + child: pw.Stack( |
145 | + alignment: pw.Alignment.center, | ||
146 | + fit: pw.StackFit.expand, | ||
147 | + children: <pw.Widget>[ | ||
148 | + pw.Center( | ||
149 | + child: pw.Text( | ||
148 | '${(value * 100).round().toInt()}%', | 150 | '${(value * 100).round().toInt()}%', |
149 | textScaleFactor: fontSize, | 151 | textScaleFactor: fontSize, |
150 | ), | 152 | ), |
151 | ), | 153 | ), |
152 | - CircularProgressIndicator( | 154 | + pw.CircularProgressIndicator( |
153 | value: value, | 155 | value: value, |
154 | backgroundColor: backgroundColor, | 156 | backgroundColor: backgroundColor, |
155 | color: color, | 157 | color: color, |
@@ -164,23 +166,23 @@ class Percent extends StatelessWidget { | @@ -164,23 +166,23 @@ class Percent extends StatelessWidget { | ||
164 | widgets.add(title); | 166 | widgets.add(title); |
165 | } | 167 | } |
166 | 168 | ||
167 | - return Column(children: widgets); | 169 | + return pw.Column(children: widgets); |
168 | } | 170 | } |
169 | } | 171 | } |
170 | 172 | ||
171 | -class UrlText extends StatelessWidget { | 173 | +class UrlText extends pw.StatelessWidget { |
172 | UrlText(this.text, this.url); | 174 | UrlText(this.text, this.url); |
173 | 175 | ||
174 | final String text; | 176 | final String text; |
175 | final String url; | 177 | final String url; |
176 | 178 | ||
177 | @override | 179 | @override |
178 | - Widget build(Context context) { | ||
179 | - return UrlLink( | 180 | + pw.Widget build(pw.Context context) { |
181 | + return pw.UrlLink( | ||
180 | destination: url, | 182 | destination: url, |
181 | - child: Text(text, | ||
182 | - style: TextStyle( | ||
183 | - decoration: TextDecoration.underline, | 183 | + child: pw.Text(text, |
184 | + style: pw.TextStyle( | ||
185 | + decoration: pw.TextDecoration.underline, | ||
184 | color: PdfColors.blue, | 186 | color: PdfColors.blue, |
185 | )), | 187 | )), |
186 | ); | 188 | ); |
@@ -11,7 +11,7 @@ import 'package:markdown/markdown.dart' as markdown; | @@ -11,7 +11,7 @@ import 'package:markdown/markdown.dart' as markdown; | ||
11 | import 'package:path_provider/path_provider.dart'; | 11 | import 'package:path_provider/path_provider.dart'; |
12 | 12 | ||
13 | import 'package:pdf/pdf.dart'; | 13 | import 'package:pdf/pdf.dart'; |
14 | -import 'package:pdf/widgets.dart' as pdf; | 14 | +import 'package:pdf/widgets.dart' as pw; |
15 | import 'package:printing/printing.dart'; | 15 | import 'package:printing/printing.dart'; |
16 | 16 | ||
17 | import 'document.dart'; | 17 | import 'document.dart'; |
@@ -140,7 +140,7 @@ class MyAppState extends State<MyApp> { | @@ -140,7 +140,7 @@ class MyAppState extends State<MyApp> { | ||
140 | 140 | ||
141 | Future<void> _sharePdf() async { | 141 | Future<void> _sharePdf() async { |
142 | print('Share ...'); | 142 | print('Share ...'); |
143 | - final pdf.Document document = await generateDocument(PdfPageFormat.a4); | 143 | + final pw.Document document = await generateDocument(PdfPageFormat.a4); |
144 | 144 | ||
145 | // Calculate the widget center for iPad sharing popup position | 145 | // Calculate the widget center for iPad sharing popup position |
146 | final RenderBox referenceBox = | 146 | final RenderBox referenceBox = |
@@ -165,19 +165,19 @@ class MyAppState extends State<MyApp> { | @@ -165,19 +165,19 @@ class MyAppState extends State<MyApp> { | ||
165 | 165 | ||
166 | final bool result = | 166 | final bool result = |
167 | await Printing.layoutPdf(onLayout: (PdfPageFormat format) { | 167 | await Printing.layoutPdf(onLayout: (PdfPageFormat format) { |
168 | - final pdf.Document document = pdf.Document(); | 168 | + final pw.Document document = pw.Document(); |
169 | 169 | ||
170 | final PdfImage image = PdfImage(document.document, | 170 | final PdfImage image = PdfImage(document.document, |
171 | image: bytes.buffer.asUint8List(), | 171 | image: bytes.buffer.asUint8List(), |
172 | width: im.width, | 172 | width: im.width, |
173 | height: im.height); | 173 | height: im.height); |
174 | 174 | ||
175 | - document.addPage(pdf.Page( | 175 | + document.addPage(pw.Page( |
176 | pageFormat: format, | 176 | pageFormat: format, |
177 | - build: (pdf.Context context) { | ||
178 | - return pdf.Center( | ||
179 | - child: pdf.Expanded( | ||
180 | - child: pdf.Image(image), | 177 | + build: (pw.Context context) { |
178 | + return pw.Center( | ||
179 | + child: pw.Expanded( | ||
180 | + child: pw.Image(image), | ||
181 | ), | 181 | ), |
182 | ); // Center | 182 | ); // Center |
183 | })); // Page | 183 | })); // Page |
@@ -289,10 +289,10 @@ class MyAppState extends State<MyApp> { | @@ -289,10 +289,10 @@ class MyAppState extends State<MyApp> { | ||
289 | Switch.adaptive( | 289 | Switch.adaptive( |
290 | onChanged: (bool value) { | 290 | onChanged: (bool value) { |
291 | setState(() { | 291 | setState(() { |
292 | - pdf.Document.debug = value; | 292 | + pw.Document.debug = value; |
293 | }); | 293 | }); |
294 | }, | 294 | }, |
295 | - value: pdf.Document.debug, | 295 | + value: pw.Document.debug, |
296 | ), | 296 | ), |
297 | ], | 297 | ], |
298 | ) | 298 | ) |
@@ -2,14 +2,14 @@ import 'dart:io'; | @@ -2,14 +2,14 @@ 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:pdf/widgets.dart'; | 5 | +import 'package:pdf/widgets.dart' as pw; |
6 | import 'package:printing_example/document.dart'; | 6 | import 'package:printing_example/document.dart'; |
7 | 7 | ||
8 | void main() { | 8 | void main() { |
9 | testWidgets('Pdf Generate the document', (WidgetTester tester) async { | 9 | testWidgets('Pdf Generate the document', (WidgetTester tester) async { |
10 | - final Document document = await generateDocument(PdfPageFormat.a4); | 10 | + final pw.Document doc = await generateDocument(PdfPageFormat.a4); |
11 | 11 | ||
12 | final File file = File('document.pdf'); | 12 | final File file = File('document.pdf'); |
13 | - file.writeAsBytesSync(document.save()); | 13 | + file.writeAsBytesSync(doc.save()); |
14 | }); | 14 | }); |
15 | } | 15 | } |
@@ -21,11 +21,11 @@ import 'package:flutter/services.dart'; | @@ -21,11 +21,11 @@ import 'package:flutter/services.dart'; | ||
21 | import 'package:flutter/widgets.dart'; | 21 | import 'package:flutter/widgets.dart'; |
22 | import 'package:flutter_test/flutter_test.dart'; | 22 | import 'package:flutter_test/flutter_test.dart'; |
23 | import 'package:pdf/pdf.dart'; | 23 | import 'package:pdf/pdf.dart'; |
24 | -import 'package:pdf/widgets.dart' as pdf; | 24 | +import 'package:pdf/widgets.dart' as pw; |
25 | import 'package:printing/printing.dart'; | 25 | import 'package:printing/printing.dart'; |
26 | 26 | ||
27 | -pdf.Document doc; | ||
28 | -pdf.Font ttf; | 27 | +pw.Document doc; |
28 | +pw.Font ttf; | ||
29 | 29 | ||
30 | void main() { | 30 | void main() { |
31 | final String path = | 31 | final String path = |
@@ -53,10 +53,10 @@ void main() { | @@ -53,10 +53,10 @@ void main() { | ||
53 | pdf: doc.document, image: FileImage(File('$path/example.png'))); | 53 | pdf: doc.document, image: FileImage(File('$path/example.png'))); |
54 | 54 | ||
55 | doc.addPage( | 55 | doc.addPage( |
56 | - pdf.Page( | ||
57 | - build: (pdf.Context context) => pdf.Center( | ||
58 | - child: pdf.Container( | ||
59 | - child: pdf.Image(image), | 56 | + pw.Page( |
57 | + build: (pw.Context context) => pw.Center( | ||
58 | + child: pw.Container( | ||
59 | + child: pw.Image(image), | ||
60 | ), | 60 | ), |
61 | ), | 61 | ), |
62 | ), | 62 | ), |
@@ -64,12 +64,12 @@ void main() { | @@ -64,12 +64,12 @@ void main() { | ||
64 | }); | 64 | }); |
65 | 65 | ||
66 | setUpAll(() { | 66 | setUpAll(() { |
67 | - pdf.Document.debug = true; | ||
68 | - pdf.RichText.debug = true; | 67 | + pw.Document.debug = true; |
68 | + pw.RichText.debug = true; | ||
69 | final Uint8List fontData = | 69 | final Uint8List fontData = |
70 | File('$path/../pdf/open-sans.ttf').readAsBytesSync(); | 70 | File('$path/../pdf/open-sans.ttf').readAsBytesSync(); |
71 | - ttf = pdf.Font.ttf(fontData.buffer.asByteData()); | ||
72 | - doc = pdf.Document(); | 71 | + ttf = pw.Font.ttf(fontData.buffer.asByteData()); |
72 | + doc = pw.Document(); | ||
73 | }); | 73 | }); |
74 | 74 | ||
75 | tearDownAll(() { | 75 | tearDownAll(() { |
@@ -30,7 +30,7 @@ Iterable<String> getCode(List<md.Node> nodes, [bool isCode = false]) sync* { | @@ -30,7 +30,7 @@ Iterable<String> getCode(List<md.Node> nodes, [bool isCode = false]) sync* { | ||
30 | yield* getCode(node.children, | 30 | yield* getCode(node.children, |
31 | node.tag == 'code' && node.attributes['class'] == 'language-dart'); | 31 | node.tag == 'code' && node.attributes['class'] == 'language-dart'); |
32 | } else if (node is md.Text) { | 32 | } else if (node is md.Text) { |
33 | - if (isCode) { | 33 | + if (isCode && !node.text.startsWith('import')) { |
34 | yield '// ------------'; | 34 | yield '// ------------'; |
35 | yield node.text; | 35 | yield node.text; |
36 | } | 36 | } |
@@ -40,47 +40,39 @@ Iterable<String> getCode(List<md.Node> nodes, [bool isCode = false]) sync* { | @@ -40,47 +40,39 @@ Iterable<String> getCode(List<md.Node> nodes, [bool isCode = false]) sync* { | ||
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
43 | -void main() { | 43 | +void buildFile(String src, String dest, bool flutter) { |
44 | final md.Document document = md.Document( | 44 | final md.Document document = md.Document( |
45 | extensionSet: md.ExtensionSet.commonMark, | 45 | extensionSet: md.ExtensionSet.commonMark, |
46 | encodeHtml: false, | 46 | encodeHtml: false, |
47 | ); | 47 | ); |
48 | 48 | ||
49 | - final output = File('readme.dart'); | 49 | + final output = File(dest); |
50 | final st = output.openWrite(); | 50 | final st = output.openWrite(); |
51 | st.writeln('import \'dart:io\';'); | 51 | st.writeln('import \'dart:io\';'); |
52 | - st.writeln('import \'dart:typed_data\';'); | ||
53 | - st.writeln('import \'package:pdf/pdf.dart\';'); | ||
54 | - st.writeln('import \'package:pdf/widgets.dart\';'); | ||
55 | - st.writeln('import \'package:image/image.dart\' show decodeImage;'); | ||
56 | - st.writeln('import \'package:printing/printing.dart\';'); | 52 | + if (flutter) { |
57 | st.writeln('import \'package:flutter/services.dart\' show rootBundle;'); | 53 | st.writeln('import \'package:flutter/services.dart\' show rootBundle;'); |
58 | st.writeln('import \'package:flutter/widgets.dart\' show AssetImage;'); | 54 | st.writeln('import \'package:flutter/widgets.dart\' show AssetImage;'); |
59 | st.writeln('import \'package:path_provider/path_provider.dart\';'); | 55 | st.writeln('import \'package:path_provider/path_provider.dart\';'); |
60 | - | ||
61 | - { | ||
62 | - final data = File('../pdf/README.md').readAsStringSync(); | ||
63 | - final List<String> lines = data.replaceAll('\r\n', '\n').split('\n'); | ||
64 | - final List<md.Node> parsedLines = document.parseLines(lines); | ||
65 | - final Iterable<String> code = getCode(parsedLines); | ||
66 | - | ||
67 | - st.writeln('Future pdfReadme() async {'); | ||
68 | - st.writeln(code.join('\n')); | ||
69 | - st.writeln('}'); | 56 | + st.writeln('import \'package:printing/printing.dart\';'); |
57 | + } else { | ||
58 | + st.writeln('import \'dart:typed_data\';'); | ||
59 | + st.writeln('import \'package:image/image.dart\' show decodeImage;'); | ||
70 | } | 60 | } |
71 | - { | ||
72 | - final data = File('../printing/README.md').readAsStringSync(); | 61 | + st.writeln('import \'package:pdf/pdf.dart\';'); |
62 | + st.writeln('import \'package:pdf/widgets.dart\' as pw;'); | ||
63 | + | ||
64 | + final data = File(src).readAsStringSync(); | ||
73 | final List<String> lines = data.replaceAll('\r\n', '\n').split('\n'); | 65 | final List<String> lines = data.replaceAll('\r\n', '\n').split('\n'); |
74 | final List<md.Node> parsedLines = document.parseLines(lines); | 66 | final List<md.Node> parsedLines = document.parseLines(lines); |
75 | final Iterable<String> code = getCode(parsedLines); | 67 | final Iterable<String> code = getCode(parsedLines); |
76 | 68 | ||
77 | - st.writeln('Future printingReadme() async {'); | ||
78 | - st.writeln(code.join('\n')); | ||
79 | - st.writeln('}'); | ||
80 | - } | ||
81 | st.writeln('Future main() async {'); | 69 | st.writeln('Future main() async {'); |
82 | - st.writeln('await pdfReadme();'); | ||
83 | - st.writeln('await printingReadme();'); | 70 | + st.writeln(code.join('\n')); |
84 | st.writeln('}'); | 71 | st.writeln('}'); |
85 | st.close(); | 72 | st.close(); |
86 | } | 73 | } |
74 | + | ||
75 | +void main() { | ||
76 | + buildFile('../pdf/README.md', 'readme-pdf.dart', false); | ||
77 | + buildFile('../printing/README.md', 'readme-printing.dart', true); | ||
78 | +} |
-
Please register or login to post a comment