The Syncfusion Flutter PDF Library allows users to create and edit PDF documents in a Flutter application. You can also create various PDF conformance documents. In this blog, we will take a brief look at the PDF conformance levels followed by the procedure to create PDF documents with different conformance levels.
PDF/A is an ISO-standardized version of the PDF, specialized for use in the archiving and long-term preservation of electronic documents to preserve text, vector graphics, raster images, and related metadata. This PDF/A conformance comes in different variants. At present our Flutter PDF Library supports creating PDF documents with the following conformance levels:
PDF/A-1
PDF/A-1 was the first archiving standard. It was published in 2005 as ISO 19005-1. It is based on PDF 1.4 and imposes some restrictions regarding the use of color, fonts, annotations, transparencies, and other elements.
PDF/A-2
PDF/A-2 was published in 2011 as ISO 19005-2. It is based on PDF version 1.7, which has been standardized as ISO 32000-1. It makes use of the new features in this version. PDF/A-2 allows JPEG2000 compression, transparent elements, and PDF layers. PDF/A-2 also allows you to embed OpenType fonts and supports PAdES. One important innovation is the container function: PDF/A files can be embedded within a PDF/A-2 document.
PDF/A-3
PDF/A-3 has been available since October 2012. A PDF/A-3 document allows you to embed any format file in a PDF document desired—not just PDF/A documents. For example, a PDF/A-3 file can contain the original file from which it was generated. The PDF/A standard does not regulate the suitability of these embedded files for archiving.
Level B conformance ensures that the visual appearance of a document is preservable long term, that the document will look the same when it is viewed or printed at any time in the future.
In this blog, we are going to cover the creation of the following conformance-level documents programmatically:
With the Syncfusion Flutter PDF Library, you can create a PDF document with PDF/A-1B standard. Here’s the procedure to do so:
Follow the instructions provided in this Getting Started documentation to create a basic Flutter application.
Include the Syncfusion Flutter PDF package dependency in the pubspec.yaml file in your project.
Refer to the following code.
dependencies: syncfusion_flutter_pdf: ^18.4.30-beta
Run the following command to get the required package.
$ flutter pub get |
Import the PDF package into main.dart file using the following code example.
import 'package:syncfusion_flutter_pdf/pdf.dart';
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Choose the conformance level:'), Row( children: [ Row(children: [ Radio( groupValue: _groupValue, onChanged: _changed, value: 0), Text('PDF/A-1B', style: TextStyle(fontSize: 16)) ]), Row(children: [ Radio( groupValue: _groupValue, onChanged: _changed, value: 1), Text('PDF/A-2B', style: TextStyle(fontSize: 16)) ]), Row(children: [ Radio( groupValue: _groupValue, onChanged: _changed, value: 2), Text('PDF/A-3B', style: TextStyle(fontSize: 16)) ]), ], ), FlatButton( child: Text( 'Create PDF', style: TextStyle(color: Colors.white), ), onPressed: _conformancePDF, color: Colors.blue, ) ], ), )); }
//Create a new PDF document with conformance A1B. PdfDocument document = PdfDocument(conformanceLevel: PdfConformanceLevel.a1b); //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))); //Read font file. List<int> fontData = await _readData('Roboto-Regular.ttf'); //Create a PDF true type font. PdfFont contentFont = PdfTrueTypeFont(fontData, 9); PdfFont headerFont = PdfTrueTypeFont(fontData, 30); PdfFont footerFont = PdfTrueTypeFont(fontData, 18); //Generate PDF grid. final PdfGrid grid = _getGrid(contentFont); //Draw the header section by creating text element. final PdfLayoutResult result = _drawHeader(page, pageSize, grid, contentFont, headerFont, footerFont); //Draw grid. _drawGrid(page, grid, result, contentFont); //Add invoice footer. _drawFooter(page, pageSize, contentFont); //Save and dispose the document. final List<int> bytes = document.save(); document.dispose();
PdfLayoutResult _drawHeader(PdfPage page, Size pageSize, PdfGrid grid, PdfFont contentFont, PdfFont headerFont, PdfFont footerFont) { //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', headerFont, 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( '\
//Create PDF grid and return. PdfGrid _getGrid(PdfFont contentFont) { //Create a PDF grid. final PdfGrid grid = PdfGrid(); //Specify the column 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); final PdfPen whitePen = PdfPen(PdfColor.empty, width: 0.5); PdfBorders borders = PdfBorders(); borders.all = PdfPen(PdfColor(142, 179, 219), width: 0.5); ; grid.rows.applyStyle(PdfGridCellStyle(borders: borders)); 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); headerRow.cells[i].style.borders.all = whitePen; } for (int i = 0; i < grid.rows.count; i++) { final PdfGridRow row = grid.rows[i]; if (i % 2 == 0) { row.style.backgroundBrush = PdfSolidBrush(PdfColor(217, 226, 243)); } 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); } } //Set font grid.style.font = contentFont; return grid; } //Create and 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; total += double.parse(value); } return total; }
Draw the table in the PDF document.
void _drawGrid( PdfPage page, PdfGrid grid, PdfLayoutResult result, PdfFont contentFont) { Rect totalPriceCellBounds; Rect quantityCellBounds; //Invoke the beginCellLayout event. grid.beginCellLayout = (Object sender, PdfGridBeginCellLayoutArgs args) { final PdfGrid grid = sender; 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', contentFont, bounds: Rect.fromLTWH( quantityCellBounds.left, result.bounds.bottom + 10, quantityCellBounds.width, quantityCellBounds.height)); page.graphics.drawString(_getTotalAmount(grid).toString(), contentFont, bounds: Rect.fromLTWH( totalPriceCellBounds.left, result.bounds.bottom + 10, totalPriceCellBounds.width, totalPriceCellBounds.height)); }
void _drawFooter(PdfPage page, Size pageSize, PdfFont contentFont) { 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, contentFont, format: PdfStringFormat(alignment: PdfTextAlignment.right), bounds: Rect.fromLTWH(pageSize.width - 30, pageSize.height - 70, 0, 0)); }
# To add assets to your application, add an assets section, like this. assets: - assets/Roboto-Regular.ttf
Future<List<int>> _readData(String name) async { final ByteData data = await rootBundle.load('assets/$name'); return data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); }
By executing the code example, the PDF/A-1B conformance document will be created like in the following screenshot.
Just modify the PdfConformanceLevel to a2b during the PdfDocument object initialization to create a PDF document with the PDF/A-2B conformance level. The following code illustrates this.
//Create a new PDF document with conformance A2B. PdfDocument document = PdfDocument(conformanceLevel: PdfConformanceLevel.a2b);
By executing the previous code, a PDF document with PDF/A-2B conformance level will be created.
PDF/A-3B conformance supports attachments to the PDF document. Modify the PdfConformanceLevel to a3b during the PdfDocument object initialization to create a PDF document with a PDF/A-3B conformance level. The following code illustrates this along with including an attachment to the PDF document.
//Create a new PDF document with conformance A3B. PdfDocument document = PdfDocument(conformanceLevel: PdfConformanceLevel.a3b); //Add attachment to the PDF document. String text = 'Adventure Works Cycles, the fictitious company on which ...'; document.attachments.add(PdfAttachment( 'AdventureCycle.txt', utf8.encode(text), description: 'Adventure Works Cycles', mimeType: 'application/txt'));
By executing this code, you will get an output PDF document like the following screenshots.
You can check out the complete sample in this GitHub repository to create PDF conformance documents.
In this blog post, we have learned the procedure to create PDF documents at various conformance levels using our Syncfusion PDF Flutter Library.
Take a moment to peruse our documentation, where you’ll find other options and features, all with accompanying code examples.
If you have any questions about these features, please let us know in the comments below. You can also contact us through our support forum, Direct-Trac, or feedback portal. We are happy to assist you!
If you liked this article, we think you would also like the following articles about PDF Library: