DEV Community

Cover image for Easily Create PDF Files Using Syncfusion PDF Library for Flutter
Suresh Mohan for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

Easily Create PDF Files Using Syncfusion PDF Library for Flutter

We are happy to introduce our new PDF Library for the Flutter platform in our 2020 Volume 1 release. This library allows you to create PDF files programmatically. You can create PDF files with formatted text, images, shapes, tables, links, headers and footers, bookmarks, and more.

The PDF Library for Flutter is supported in both Flutter mobile and web applications. The creation of PDF files using this library follows the most popular PDF 1.7 (ISO 32000-1) and latest PDF 2.0 (ISO 32000-2) specifications.

The beta version of the Syncfusion Flutter PDF package is available in pub.dev.

With this beta version, you can create your PDF files with these elements:

  • Multi-page PDF document
  • Unicode and RTL text
  • Lists
  • Images
  • Headers and footers
  • Tables
  • Graphical shapes
  • Bookmarks
  • Hyperlinks

Flutter PDF Library

Create a multi-page PDF document

You can easily create a multi-page PDF document from scratch using the Syncfusion Flutter PDF Library. You can choose either the standard page size or a custom one when you add a new page. Also, you can set the orientation of the PDF pages.

Please refer to this UG link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-document

Pages of the same PDF file with different orientations
Pages of the same PDF file with different orientations

Unicode and RTL text

You can draw unicode and RTL text in PDF documents using TrueType font (.ttf).

In right-to-left script, writing starts from the right side of the PDF page and continues to the left. The most commonly used RTL scripts are Arabic, Persian, and Urdu. Bidirectional text contains both right-to-left and left-to-right formats. For instance, a line may contain both Arabic and English text. As you might imagine, there are several possibilities when dealing with bidirectional text. Arabic text is written from right-to-left, but numbers are written left-to-right.

Please refer to the UG link to write RTL in a PDF using the PDF Flutter Library.

https://help.syncfusion.com/flutter/pdf/working-with-text#drawing-rightf-to-left-text

Syncfusion Flutter PDF Library also supports the following font types to add a text in a PDF document.

  1. Standard font (14 standard PDF fonts)
  2. Chinese, Japanese, and Korean (CJK) fonts

Bidirectional content in a PDF document
Bidirectional content in a PDF document

Lists

You can create both lists (ordered lists) and bulleted lists (unordered lists) using the Syncfusion Flutter PDF package. This package provides support to create an ordered list using numbers, alphabet characters, and Roman numerals and unordered lists with various built-in styles, custom images, and templates.

Please refer to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-lists

Ordered and unordered lists in the PDF content
Ordered and unordered lists in the PDF content

Inserting images

You can insert images of PNG and JPEG formats into PDF document. You can also manipulate the image properties with rotation, cropping, scaling, and transparency.

Please refer to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-images

Images added to the PDF page
Images added to the PDF page

Adding headers and footers

Headers and footers are the top and bottom sections of a document, respectively, and they are considered separate sections from the main document. These are used to hold details such as the page number, title, footnotes, and date and time.

The PDF Library lets you add headers and footers with the following content:

  • Text
  • Images
  • Shapes
  • Page numbers
  • Date and times

You can also add section-based headers and footers to a PDF. You can add the headers and footers to top, bottom, left, and right page sections. Also, you can customize headers and footers for even and odd pages.

Please refer to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-headers-and-footers Header and Footer in PDF

Tables

A table is an arrangement of data in rows and columns. Using this package, we can create a table in a PDF document. The PDF table can be created by filling in the data from data sources or by adding rows and columns manually for unbound data. It is designed for high performance with advanced customization, styling, and formatting.

Please refer to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-tables

A table added to the PDF file
A table added to the PDF file

Graphical shapes

Using this package, you can add various shapes in a PDF file: rectangles, lines, ellipses, pathes, arcs, Bezier curves, pies, and polygon.

Please to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-shapes

Different shapes added to a PDF document
Different shapes added to a PDF document

Bookmarks

Bookmarks are used to navigate interactively from one part of the document to another. You can create bookmarks and customize the title font, color, size, and more.

Please to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-bookmarks

Bookmark added to a PDF file
Bookmark added to a PDF file

Hyperlinks

Add hyperlinks in a PDF file to navigate to external webpages.

Please to the following link for more information.

https://help.syncfusion.com/flutter/pdf/working-with-hyperlinks

A hyperlink in a PDF file
A hyperlink in a PDF file

Create PDFs in your Flutter app

This section explains how to create a simple PDF invoice using the Syncfusion Flutter PDF package.

  1. Add the Syncfusion Flutter PDF dependency in your pub sec file.
dependencies:
  syncfusion_flutter_pdf: ^18.1.42-beta
  1. Run the following commands to get the required packages.
$ flutter pub get
  1. Import the following package into your Dart code.
import 'package:syncfusion\_flutter\_pdf/pdf.dart';
  1. Add a button widget as a child of your container widget.
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text(widget.title),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          FlatButton(
            child: Text(
              'Generate PDF',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: _createPDF,
            color: Colors.blue,
          )
        ],
      ),
    ),
  );
}

Include the following code in the button click event to create a PDF file.

Future<void> _createPDF() async {
  //Create a PDF document.
  final PdfDocument document = PdfDocument();
  //Add page to the PDF
  final PdfPage page = document.pages.add();
  //Get page client size
  final Size pageSize = page.getClientSize();
  //Draw rectangle
  page.graphics.drawRectangle(
      bounds: Rect.fromLTWH(0, 0, pageSize.width, pageSize.height),
      pen: PdfPen(PdfColor(142, 170, 219, 255)));
  //Generate PDF grid.
  final PdfGrid grid = getGrid();
  //Draw the header section by creating text element
  final PdfLayoutResult result = drawHeader(page, pageSize, grid);
  //Draw grid
  drawGrid(page, grid, result);
  //Add invoice footer
  drawFooter(page, pageSize);
  //Save and launch the document
  final List<int> bytes = document.save();
  //Dispose the document.
  document.dispose();
  //Save and launch file.
  SaveFilehelper.saveAndOpenFile(bytes);
}

Adding a header and buyer information

Creating a PDF from scratch using Syncfusion PDF Library is easy and there are several ways to place elements in a document. In this example, we’ll place the invoice title and buyer’s information on the left, and the amount, invoice number, and date on the right.

The following code example is used to create the invoice header with the basic information.

PdfLayoutResult drawHeader(PdfPage page, Size pageSize, PdfGrid grid) {
  //Draw rectangle
  page.graphics.drawRectangle(
      brush: PdfSolidBrush(PdfColor(91, 126, 215, 255)),
      bounds: Rect.fromLTWH(0, 0, pageSize.width - 115, 90));
  //Draw string
  page.graphics.drawString(
      'INVOICE', PdfStandardFont(PdfFontFamily.helvetica, 30),
      brush: PdfBrushes.white,
      bounds: Rect.fromLTWH(25, 0, pageSize.width - 115, 90),
      format: PdfStringFormat(lineAlignment: PdfVerticalAlignment.middle));

  page.graphics.drawRectangle(
      bounds: Rect.fromLTWH(400, 0, pageSize.width - 400, 90),
      brush: PdfSolidBrush(PdfColor(65, 104, 205)));

  page.graphics.drawString('\$' + getTotalAmount(grid).toString(),
      PdfStandardFont(PdfFontFamily.helvetica, 18),
      bounds: Rect.fromLTWH(400, 0, pageSize.width - 400, 100),
      brush: PdfBrushes.white,
      format: PdfStringFormat(
          alignment: PdfTextAlignment.center,
          lineAlignment: PdfVerticalAlignment.middle));

  final PdfFont contentFont = PdfStandardFont(PdfFontFamily.helvetica, 9);
  //Draw string
  page.graphics.drawString('Amount', contentFont,
      brush: PdfBrushes.white,
      bounds: Rect.fromLTWH(400, 0, pageSize.width - 400, 33),
      format: PdfStringFormat(
          alignment: PdfTextAlignment.center,
          lineAlignment: PdfVerticalAlignment.bottom));
  //Create data format and convert it to text.
  final DateFormat format = DateFormat.yMMMMd('en_US');
  final String invoiceNumber = 'Invoice Number: 2058557939\r\n\r\nDate: ' +
      format.format(DateTime.now());
  final Size contentSize = contentFont.measureString(invoiceNumber);
  const String address =
      'Bill To: \r\n\r\nAbraham Swearegin, \r\n\r\nUnited States, California, San Mateo, \r\n\r\n9920 BridgePointe Parkway, \r\n\r\n9365550136';

  PdfTextElement(text: invoiceNumber, font: contentFont).draw(
      page: page,
      bounds: Rect.fromLTWH(pageSize.width - (contentSize.width + 30), 120,
          contentSize.width + 30, pageSize.height - 120));

  return PdfTextElement(text: address, font: contentFont).draw(
      page: page,
      bounds: Rect.fromLTWH(30, 120,
          pageSize.width - (contentSize.width + 30), pageSize.height - 120));
}

Invoice header in PDF file
Invoice header in PDF file

Adding invoice (table) data

Add the invoice data in a tabular format with five columns using Syncfusion PDF tables.

//Create PDF grid and return
PdfGrid getGrid() {
  //Create a PDF grid
  final PdfGrid grid = PdfGrid();
  //Secify the columns count to the grid.
  grid.columns.add(count: 5);
  //Create the header row of the grid.
  final PdfGridRow headerRow = grid.headers.add(1)[0];
  //Set style
  headerRow.style.backgroundBrush = PdfSolidBrush(PdfColor(68, 114, 196));
  headerRow.style.textBrush = PdfBrushes.white;
  headerRow.cells[0].value = 'Product Id';
  headerRow.cells[0].stringFormat.alignment = PdfTextAlignment.center;
  headerRow.cells[1].value = 'Product Name';
  headerRow.cells[2].value = 'Price';
  headerRow.cells[3].value = 'Quantity';
  headerRow.cells[4].value = 'Total';
  addProducts('CA-1098', 'AWC Logo Cap', 8.99, 2, 17.98, grid);
  addProducts('LJ-0192', 'Long-Sleeve Logo Jersey,M', 49.99, 3, 149.97, grid);
  addProducts('So-B909-M', 'Mountain Bike Socks,M', 9.5, 2, 19, grid);
  addProducts('LJ-0192', 'Long-Sleeve Logo Jersey,M', 49.99, 4, 199.96, grid);
  addProducts('FK-5136', 'ML Fork', 175.49, 6, 1052.94, grid);
  addProducts('HL-U509', 'Sports-100 Helmet,Black', 34.99, 1, 34.99, grid);
  //Apply the grid built-in style.
  grid.applyBuiltInStyle(PdfGridBuiltInStyle.listTable4Accent5);
  grid.columns[1].width = 200;
  for (int i = 0; i < headerRow.cells.count; i++) {
    headerRow.cells[i].style.cellPadding =
        PdfPaddings(bottom: 5, left: 5, right: 5, top: 5);
  }
  for (int i = 0; i < grid.rows.count; i++) {
    final PdfGridRow row = grid.rows[i];
    for (int j = 0; j < row.cells.count; j++) {
      final PdfGridCell cell = row.cells[j];
      if (j == 0) {
        cell.stringFormat.alignment = PdfTextAlignment.center;
      }
      cell.style.cellPadding =
          PdfPaddings(bottom: 5, left: 5, right: 5, top: 5);
    }
  }
  return grid;
}

//Create row for the grid.
void addProducts(String productId, String productName, double price,
    int quantity, double total, PdfGrid grid) {
  PdfGridRow row = grid.rows.add();
  row.cells[0].value = productId;
  row.cells[1].value = productName;
  row.cells[2].value = price.toString();
  row.cells[3].value = quantity.toString();
  row.cells[4].value = total.toString();
}

Draw the table into the PDF document

void drawGrid(PdfPage page, PdfGrid grid, PdfLayoutResult result) {
  Rect totalPriceCellBounds;
  Rect quantityCellBounds;
  //Invoke the beginCellLayout event.
  grid.beginCellLayout = (Object sender, PdfGridBeginCellLayoutArgs args) {
    final PdfGrid grid = sender as PdfGrid;
    if (args.cellIndex == grid.columns.count - 1) {
      totalPriceCellBounds = args.bounds;
    } else if (args.cellIndex == grid.columns.count - 2) {
      quantityCellBounds = args.bounds;
    }
  };
  //Draw the PDF grid and get the result.
  result = grid.draw(
      page: page, bounds: Rect.fromLTWH(0, result.bounds.bottom + 40, 0, 0));

  //Draw grand total.
  page.graphics.drawString('Grand Total',
      PdfStandardFont(PdfFontFamily.helvetica, 9, style: PdfFontStyle.bold),
      bounds: Rect.fromLTWH(
          quantityCellBounds.left,
          result.bounds.bottom + 10,
          quantityCellBounds.width,
          quantityCellBounds.height));
  page.graphics.drawString(getTotalAmount(grid).toString(),
      PdfStandardFont(PdfFontFamily.helvetica, 9, style: PdfFontStyle.bold),
      bounds: Rect.fromLTWH(
          totalPriceCellBounds.left,
          result.bounds.bottom + 10,
          totalPriceCellBounds.width,
          totalPriceCellBounds.height));
}

PDF invoice main content

Adding seller information

Finally, create the footer of the invoice with dashed lines and add the address of the seller. With this, we have successfully created a rich-looking PDF invoice using the Syncfusion Flutter PDF Library.

void drawFooter(PdfPage page, Size pageSize) {
  final PdfPen linePen =
      PdfPen(PdfColor(142, 170, 219, 255), dashStyle: PdfDashStyle.custom);
  linePen.dashPattern = <double>[3, 3];
  //Draw line
  page.graphics.drawLine(linePen, Offset(0, pageSize.height - 100),
      Offset(pageSize.width, pageSize.height - 100));

  const String footerContent =
      '800 Interchange Blvd.\r\n\r\nSuite 2501, Austin, TX 78721\r\n\r\nAny Questions? support@adventure-works.com';

  //Added 30 as a margin for the layout.
  page.graphics.drawString(
      footerContent, PdfStandardFont(PdfFontFamily.helvetica, 9),
      format: PdfStringFormat(alignment: PdfTextAlignment.right),
      bounds: Rect.fromLTWH(pageSize.width - 30, pageSize.height - 70, 0, 0));
}

Complete PDF Invoice

The complete sample can be downloaded from create_pdf_file.

Conclusion

In this blog post, we walked through our new Syncfusion Flutter PDF package and its features, which are available from the 2020 Volume 1 release. Try this package and share your feedback in the comment section.

You can see a Syncfusion Flutter app with many examples in this GitHub location. Additionally, take a look at our demo app in the Google Play Store or App Store.

If you want an in-depth learning experience on how to create a complete Flutter app, be sure to read Flutter Succinctly by Ed Freitas. It’s part of Syncfusion’s library of free technical ebooks.

Also, if you need a new widget for the Flutter framework, please let us know in the comments section. You can also contact us through our support forum, Direct-Trac, or feedback portal. We are always happy to assist you!

The post Easily Create PDF Files Using Syncfusion PDF Library for Flutter appeared first on Syncfusion Blogs.

Top comments (0)