Showing
7 changed files
with
137 additions
and
2 deletions
demo/assets/document.svg
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<svg viewBox="0 0 150 230" | ||
| 3 | + xmlns="http://www.w3.org/2000/svg" | ||
| 4 | + xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 5 | + <defs> | ||
| 6 | + <linearGradient id="gradient-1"> | ||
| 7 | + <stop offset="0" style="stop-color: rgb(255, 255, 255);"/> | ||
| 8 | + <stop offset="1" style="stop-color: rgb(161, 161, 161);"/> | ||
| 9 | + </linearGradient> | ||
| 10 | + <linearGradient id="gradient-1-0" gradientUnits="userSpaceOnUse" x1="119.315" y1="36.313" x2="119.315" y2="216.359" xlink:href="#gradient-1"/> | ||
| 11 | + </defs> | ||
| 12 | + <rect x="-67.203" y="-48.72" width="276.134" height="354.501" style="fill: rgb(93, 32, 205);"/> | ||
| 13 | + <ellipse style="fill: rgb(141, 81, 252);" cx="119.315" cy="126.336" rx="139.238" ry="98.673" transform="matrix(0.93642, 0.35088, -0.35088, 0.93642, -15.610807, -59.255697)"/> | ||
| 14 | + <ellipse style="fill: url(#gradient-1-0);" cx="119.315" cy="126.336" rx="130.398" ry="90.023" transform="matrix(0.952861, 0.303408, -0.303408, 0.952861, -26.924128, -56.954295)"/> | ||
| 15 | +</svg> |
| @@ -28,6 +28,72 @@ Future<Uint8List> generateDocument( | @@ -28,6 +28,72 @@ Future<Uint8List> generateDocument( | ||
| 28 | 28 | ||
| 29 | final font1 = await rootBundle.load('assets/open-sans.ttf'); | 29 | final font1 = await rootBundle.load('assets/open-sans.ttf'); |
| 30 | final font2 = await rootBundle.load('assets/open-sans-bold.ttf'); | 30 | final font2 = await rootBundle.load('assets/open-sans-bold.ttf'); |
| 31 | + final shape = await rootBundle.loadString('assets/document.svg'); | ||
| 32 | + | ||
| 33 | + doc.addPage( | ||
| 34 | + pw.Page( | ||
| 35 | + pageTheme: pw.PageTheme( | ||
| 36 | + pageFormat: format.copyWith(marginBottom: 1.5 * PdfPageFormat.cm), | ||
| 37 | + orientation: pw.PageOrientation.portrait, | ||
| 38 | + buildBackground: (context) => pw.FullPage( | ||
| 39 | + ignoreMargins: true, | ||
| 40 | + child: pw.SvgImage(svg: shape, fit: pw.BoxFit.fill), | ||
| 41 | + ), | ||
| 42 | + ), | ||
| 43 | + build: (context) { | ||
| 44 | + return pw.Column( | ||
| 45 | + children: [ | ||
| 46 | + pw.Spacer(), | ||
| 47 | + pw.RichText( | ||
| 48 | + text: pw.TextSpan(children: [ | ||
| 49 | + pw.TextSpan( | ||
| 50 | + text: DateTime.now().year.toString() + '\n', | ||
| 51 | + style: pw.TextStyle( | ||
| 52 | + fontWeight: pw.FontWeight.bold, | ||
| 53 | + color: PdfColors.grey600, | ||
| 54 | + fontSize: 40, | ||
| 55 | + ), | ||
| 56 | + ), | ||
| 57 | + pw.TextSpan( | ||
| 58 | + text: 'Portable Document Format', | ||
| 59 | + style: pw.TextStyle( | ||
| 60 | + fontWeight: pw.FontWeight.bold, | ||
| 61 | + fontSize: 40, | ||
| 62 | + ), | ||
| 63 | + ), | ||
| 64 | + ])), | ||
| 65 | + pw.Spacer(), | ||
| 66 | + pw.Container( | ||
| 67 | + alignment: pw.Alignment.topRight, | ||
| 68 | + height: 150, | ||
| 69 | + child: pw.PdfLogo(), | ||
| 70 | + ), | ||
| 71 | + pw.Spacer(flex: 2), | ||
| 72 | + ], | ||
| 73 | + ); | ||
| 74 | + }, | ||
| 75 | + ), | ||
| 76 | + ); | ||
| 77 | + | ||
| 78 | + doc.addPage( | ||
| 79 | + pw.Page( | ||
| 80 | + pageFormat: format.copyWith(marginBottom: 1.5 * PdfPageFormat.cm), | ||
| 81 | + orientation: pw.PageOrientation.portrait, | ||
| 82 | + build: (context) { | ||
| 83 | + return pw.Column( | ||
| 84 | + crossAxisAlignment: pw.CrossAxisAlignment.start, | ||
| 85 | + children: [ | ||
| 86 | + pw.Center( | ||
| 87 | + child: pw.Text('Table of content', | ||
| 88 | + style: pw.Theme.of(context).header0), | ||
| 89 | + ), | ||
| 90 | + pw.SizedBox(height: 20), | ||
| 91 | + pw.TableOfContent(), | ||
| 92 | + ], | ||
| 93 | + ); | ||
| 94 | + }, | ||
| 95 | + ), | ||
| 96 | + ); | ||
| 31 | 97 | ||
| 32 | doc.addPage(pw.MultiPage( | 98 | doc.addPage(pw.MultiPage( |
| 33 | theme: pw.ThemeData.withFont( | 99 | theme: pw.ThemeData.withFont( |
| @@ -58,7 +58,9 @@ class PdfOutline extends PdfObjectDict { | @@ -58,7 +58,9 @@ class PdfOutline extends PdfObjectDict { | ||
| 58 | this.color, | 58 | this.color, |
| 59 | this.destMode = PdfOutlineMode.fitPage, | 59 | this.destMode = PdfOutlineMode.fitPage, |
| 60 | this.style = PdfOutlineStyle.normal, | 60 | this.style = PdfOutlineStyle.normal, |
| 61 | + int? page, | ||
| 61 | }) : assert(anchor == null || (dest == null && rect == null)), | 62 | }) : assert(anchor == null || (dest == null && rect == null)), |
| 63 | + _page = page, | ||
| 62 | super(pdfDocument); | 64 | super(pdfDocument); |
| 63 | 65 | ||
| 64 | /// This holds any outlines below us | 66 | /// This holds any outlines below us |
| @@ -73,6 +75,12 @@ class PdfOutline extends PdfObjectDict { | @@ -73,6 +75,12 @@ class PdfOutline extends PdfObjectDict { | ||
| 73 | /// The destination page | 75 | /// The destination page |
| 74 | PdfPage? dest; | 76 | PdfPage? dest; |
| 75 | 77 | ||
| 78 | + /// Page number | ||
| 79 | + int? get page => | ||
| 80 | + _page ?? | ||
| 81 | + (dest != null ? pdfDocument.pdfPageList.pages.indexOf(dest!) + 1 : null); | ||
| 82 | + final int? _page; | ||
| 83 | + | ||
| 76 | /// The region on the destination page | 84 | /// The region on the destination page |
| 77 | final PdfRect? rect; | 85 | final PdfRect? rect; |
| 78 | 86 |
| @@ -255,6 +255,7 @@ class Outline extends Anchor { | @@ -255,6 +255,7 @@ class Outline extends Anchor { | ||
| 255 | anchor: name, | 255 | anchor: name, |
| 256 | color: color, | 256 | color: color, |
| 257 | style: style, | 257 | style: style, |
| 258 | + page: context.pageNumber, | ||
| 258 | ); | 259 | ); |
| 259 | 260 | ||
| 260 | var parent = context.document.outline; | 261 | var parent = context.document.outline; |
| @@ -25,6 +25,7 @@ import 'container.dart'; | @@ -25,6 +25,7 @@ import 'container.dart'; | ||
| 25 | import 'decoration.dart'; | 25 | import 'decoration.dart'; |
| 26 | import 'flex.dart'; | 26 | import 'flex.dart'; |
| 27 | import 'geometry.dart'; | 27 | import 'geometry.dart'; |
| 28 | +import 'multi_page.dart'; | ||
| 28 | import 'text.dart'; | 29 | import 'text.dart'; |
| 29 | import 'text_style.dart'; | 30 | import 'text_style.dart'; |
| 30 | import 'theme.dart'; | 31 | import 'theme.dart'; |
| @@ -132,6 +133,49 @@ class Header extends StatelessWidget { | @@ -132,6 +133,49 @@ class Header extends StatelessWidget { | ||
| 132 | } | 133 | } |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 136 | +class TableOfContent extends StatelessWidget { | ||
| 137 | + Iterable<Widget> _buildToc(PdfOutline o, int l) sync* { | ||
| 138 | + for (final c in o.outlines) { | ||
| 139 | + if (c.title != null) { | ||
| 140 | + yield Padding( | ||
| 141 | + padding: const EdgeInsets.only(bottom: 2), | ||
| 142 | + child: Link( | ||
| 143 | + destination: c.anchor!, | ||
| 144 | + child: Row( | ||
| 145 | + children: [ | ||
| 146 | + SizedBox(width: 10.0 * l), | ||
| 147 | + Text('${c.title}'), | ||
| 148 | + SizedBox(width: 8), | ||
| 149 | + Expanded( | ||
| 150 | + child: Divider( | ||
| 151 | + borderStyle: BorderStyle.dotted, | ||
| 152 | + thickness: 0.2, | ||
| 153 | + )), | ||
| 154 | + SizedBox(width: 8), | ||
| 155 | + Text('${c.page}'), | ||
| 156 | + ], | ||
| 157 | + ), | ||
| 158 | + ), | ||
| 159 | + ); | ||
| 160 | + yield* _buildToc(c, l + 1); | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + @override | ||
| 166 | + Widget build(Context context) { | ||
| 167 | + assert(context.page is! MultiPage, | ||
| 168 | + '$runtimeType will not work with MultiPage'); | ||
| 169 | + | ||
| 170 | + return Column( | ||
| 171 | + crossAxisAlignment: CrossAxisAlignment.start, | ||
| 172 | + children: [ | ||
| 173 | + ..._buildToc(context.document.outline, 0), | ||
| 174 | + ], | ||
| 175 | + ); | ||
| 176 | + } | ||
| 177 | +} | ||
| 178 | + | ||
| 135 | class Paragraph extends StatelessWidget { | 179 | class Paragraph extends StatelessWidget { |
| 136 | Paragraph({ | 180 | Paragraph({ |
| 137 | this.text, | 181 | this.text, |
| @@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl | @@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl | ||
| 4 | homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf | 4 | homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf |
| 5 | repository: https://github.com/DavBfr/dart_pdf | 5 | repository: https://github.com/DavBfr/dart_pdf |
| 6 | issue_tracker: https://github.com/DavBfr/dart_pdf/issues | 6 | issue_tracker: https://github.com/DavBfr/dart_pdf/issues |
| 7 | -version: 3.3.1 | 7 | +version: 3.4.0 |
| 8 | 8 | ||
| 9 | environment: | 9 | environment: |
| 10 | sdk: ">=2.12.0-0 <3.0.0" | 10 | sdk: ">=2.12.0-0 <3.0.0" |
-
Please register or login to post a comment