David PHAM-VAN

Add TableOfContent Widget

  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(
1 # Changelog 1 # Changelog
2 2
3 -## 3.3.1 3 +## 3.4.0
4 4
5 - Fix Text.softWrap behavior 5 - Fix Text.softWrap behavior
  6 +- Add TableOfContent Widget
6 7
7 ## 3.3.0 8 ## 3.3.0
8 9
@@ -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"