Flutter PDF Library is a feature-rich and high-performance library that enables users to add robust PDF functionalities to Flutter applications and create PDF reports programmatically with formatted text, images, tables, links, lists, headers and footers, bookmarks, and more. This library also offers the functionality to read, edit, and secure PDF documents without Adobe dependencies.
All the elements in a typical PDF document like text, formatting, images, shapes, and tables are accessible through a comprehensive set of APIs.
Create PDF documents from scratch and save them to a stream with just a few lines of code. Existing documents can also be opened and manipulated.
Create multipage PDF documents with formatted text, images, tables, shapes, headers and footers, and more.
Draw Unicode and RTL text using supported TrueType fonts.
Add bookmarks to a PDF document to navigate interactively from one part of the document to another. Bookmarks can also be edited and deleted.
Add hyperlinks to a PDF document to navigate to webpages or any other external content.
Add document-based or section-based headers and footers to a PDF document. Add dynamic fields to headers and footers like page numbers, page count, and date-time.
Convert image formats such as PNG and JPEG to PDF.
Create stunning PDF tables with advanced customization, formatting, and styling.
Add various shapes such as rectangles, lines, polygons, arcs, ellipses, paths, pies, and Bezier curves.
Create ordered lists using numbers, the alphabet, and Roman numerals. Create unordered lists using various built-in styles, custom images, and templates.
Include lines, squares, rectangles, polygons, and ellipses in PDF pages to create schematic drawings or mark important materials with the shapes. The shapes can be moved, resize, removed, or edited.
Existing documents can be watermarked with text or images.
The text in a PDF document can be extracted and saved to a file. It can be extracted with details like bounds, font name, font size, and font color.
Find a text segment in a PDF document and return its bounds, font name, font style, and more.
Essential PDF supports both AES (128-bit, 256-bit, 256-bit revision-6) and RC4 (40-bit, 128-bit) encryption algorithms as per the ISO 32000 standards and PDF 2.0 security to protect documents from unauthorized access.
Add, extract, and delete attachments from a PDF document. The attachments can be of any file format.
Create, modify, fill, and flatten AcroForms in a PDF document.
Documents can be digitally signed using x509 certificates (.pfx files with a private key). Also, customize appearance, digest algorithms, and cryptography standards.
Easily get started with the Flutter PDF Library using a few simple lines of Dart code example as demonstrated below. Also explore our Flutter PDF Library Example that shows you how to render and configure the PDF Library in Flutter.
///Package imports
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
///PDF import
import 'package:syncfusion_flutter_pdf/pdf.dart';
///Local imports
import '../../model/sample_view.dart';
import 'helper/save_file_mobile.dart'
if (dart.library.html) 'helper/save_file_web.dart';
/// Render PDF of invoice
class InvoicePdf extends SampleView {
/// Render pdf of invoice
const InvoicePdf(Key key) : super(key: key);
@override
_InvoicePdfState createState() => _InvoicePdfState();
}
class _InvoicePdfState extends SampleViewState {
_InvoicePdfState();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: model.cardThemeColor,
body: Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'The PDF package is a non-UI and reusable flutter library to create PDF reports programmatically with formatted text, images, tables, links, list, header and footer, and more.\r\n\r\nThis sample showcase how to create a simple invoice report using PDF grid with built-in styles.',
style: TextStyle(fontSize: 16, color: model.textColor)),
const SizedBox(height: 20, width: 30),
Align(
alignment: Alignment.center,
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
model.backgroundColor),
padding: model.isMobile
? null
: MaterialStateProperty.all(
const EdgeInsets.symmetric(
vertical: 15, horizontal: 15)),
),
onPressed: _generatePDF,
child: const Text('Generate PDF',
style: TextStyle(color: Colors.white)),
))
],
),
),
),
);
}
Future<void> _generatePDF() 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 dispose the document.
final List<int> bytes = document.save();
document.dispose();
//Launch file.
await FileSaveHelper.saveAndLaunchFile(bytes, 'Invoice.pdf');
}
//Draw the invoice header
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(r'$' + _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))!;
}
//Draws the grid
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));
}
//Draw the invoice footer data.
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));
}
//Create PDF grid and return
PdfGrid _getGrid() {
//Create a PDF grid
final PdfGrid grid = PdfGrid();
//Set 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);
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) {
final 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();
}
//Get the total amount.
double _getTotalAmount(PdfGrid grid) {
double total = 0;
for (int i = 0; i < grid.rows.count; i++) {
final String value =
grid.rows[i].cells[grid.columns.count - 1].value as String;
total += double.parse(value);
}
return total;
}
}
Document and Page Features | Flutter Mobile | Flutter Web |
---|---|---|
Create PDF documents from scratch or modify an existing document. | ||
Save the PDF document to a stream. | ||
Open existing PDF documents from a stream. | ||
Open existing PDF documents from the base64 string. | ||
Portrait and landscape orientations. | ||
Page layers. | ||
Headers and footers. | ||
PDF standards conformance such as PDF/A-1B, PDF/A-2B, and PDF/A-3B. | ||
Standard and custom page sizes. | ||
Document properties. | ||
Security | ||
Add digital signatures using x509 certificates. | ||
Encrypt/decrypt PDFs using 40-bit and 128-bit RC4 algorithms. | ||
Encrypt/decrypt PDFs using 128-bit and 256-bit AES algorithms. | ||
Encrypt/decrypt PDFs using 256-bit AES algorithm with revision 6. | ||
PDF contents | ||
Automatic fields such as page number and date can be applied for specific pages or the entire document. | ||
Add single, multiline, and multipage text with TrueType fonts. | ||
Align text in RTL format for languages such as Arabic, Hebrew, etc. | ||
Apply text formatting including colors, alignments, line and character spacing, etc. | ||
Embed JPEG and PNG images. | ||
Paginate images across multiple pages. | ||
Add watermarks to a document using text or images. | ||
Create richly formatted tables that can span multiple pages. | ||
Add geometrical shapes like lines, rectangles, paths, and curves to the page graphics. | ||
Apply pen and brush for graphic elements such as text, shapes, etc. | ||
Insert hyperlinks that can navigate to a webpage, remote file, or even to a different region in the same document. | ||
Fonts | ||
14 types of standard or base fonts. | ||
CJK (Chinese, Japanese, and Korean) fonts. | ||
Unicode TrueType fonts. | ||
Tables | ||
Import data from different data sources. | ||
Add row, column, cell, and table formatting. | ||
Add row headers that can be repeated on all the pages. | ||
Paginate tables across multiple pages to handle horizontal overflow. | ||
Merge rows and columns. | ||
Create nested tables that span many pages. | ||
Interactive Elements | ||
Add an annotation with associated notes. | ||
Create or modify bookmarks for easier navigation. | ||
Flatten all the annotations or specific annotations in a document. | ||
Embed files as attachments. | ||
Annotation Types | ||
Document link annotation. | ||
URI annotation. | ||
Ellipse annotation. | ||
Rectangle annotation. | ||
Polygon annotation. | ||
Line annotation. | ||
Form | ||
Create and modify forms. | ||
Support for form fields like push button field, checkbox field, radio button field, text box field, list field, and combo box field. | ||
Remove or reposition form fields. | ||
Flatten the entire form or specific fields in the documents. | ||
Action Types | ||
Form action. | ||
JavaScript action. | ||
Reset action. | ||
Submit action. | ||
URI action. |
Greatness—it’s one thing to say you have it, but it means more when others recognize it. Syncfusion is proud to hold the following industry awards.