DEV Community

Cover image for Creating Custom PDFs in Flutter
Ayevbeosa Iyamu
Ayevbeosa Iyamu

Posted on

Creating Custom PDFs in Flutter

Introduction

PDFs are among the most widely used formats for creating and sharing documents on the internet, thanks to their numerous advantages. This article aims to explore the process of seamlessly creating PDF documents within mobile applications using Flutter, as well as the various customization options available to enhance their functionality and presentation. By understanding these capabilities, you as a developer can improve the user experience and meet diverse document needs effectively.


Setup

To implement this in Flutter, you need to add the pdf and printing dependencies to the pubspec.yaml file.

The printing package is necessary as it enables customization of the PDF output.

dependencies:
   pdf: ^3.11.1
   printing: ^5.13.3

Enter fullscreen mode Exit fullscreen mode

Before proceeding, it is recommended to create a separate Dart file to handle the PDF creation. This is because the pdf package uses its own set of widgets, which may conflict with Flutter's Material widgets. However, if you're comfortable with managing this in the same file, feel free to disregard this suggestion. You can create an import alias like so,

import 'package:pdf/widgets.dart' as pw;
Enter fullscreen mode Exit fullscreen mode

Next, in the file we created, we add the imports and we declare a function that generates the PDF.

import 'dart:typed_data';

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'package:printing/printing.dart';

Future<Uint8List> generatePdf() async {
  final pdf = Document();
  pdf.addPage(
     Page(
       build: (context) {
        return Column(
          children: [],
        );
      },
    ),
  );
  return pdf.save();
}
Enter fullscreen mode Exit fullscreen mode

In the code above, an instance of Document is created, representing the PDF document. We then add a page to the document (although multiple pages can be added, we will use only one for this example). The Page widget requires a build parameter, where you can define the UI for how the PDF will appear. This UI is created using Flutter widgets, which I think is really cool.

It's important to note that the widgets used in the build method are from package:pdf/widgets.dart. Although their names and functionality are very similar to the widgets in package:flutter/material.dart, they are distinct.

The final line saves the PDF and returns an unsigned 8-bit integer list, which is essentially a representation of the generated PDF.


Using custom fonts

We can add custom fonts in two ways, either to a specific Text widget or to the theme of the Page.

Firstly, the font has to be added to the project in the assets/fonts directory and then added in the assets section of pubspec.yaml.

Next, we would load the font from the assetBundle.


Future<Uint8List> generatePdf() async {

  final customFont1 = await fontFromAssetBundle(
    'assets/fonts/custom_font_1.ttf',
  );
  final customFont1Bold = await fontFromAssetBundle(
    'assets/fonts/custom_font_1.ttf',
  );
  final customFont2 = await fontFromAssetBundle(
    'assets/fonts/custom_font_2.ttf',
  );

  pdf.addPage(
    Page(
      pageTheme: PageTheme(
        theme: ThemeData.withFont(
          base: customFont1,
          bold: customFont1Bold,
        ),
      ),
      build: (context) {
        return Column(
          children: [
            Text(
              'Creating Custom PDFs in Flutter',
              style: TextStyle(
                // Set specific font
                font: customFont2,
              ),
            ),
          ],
        );
      },
    ),
  );

---

}
Enter fullscreen mode Exit fullscreen mode

What is interesting to note here is, asides setting the base font, you can also set the font for bold, italic and boldItalic.


Adding images

This is very similar to what we did for adding fonts. As usual, we first add the image to our assets/images directory and then to the assets section of pubspec.yaml.

Finally, we include it in the widget.

Future<Uint8List> generatePdf() async {

  final myImage = await imageFromAssetBundle(
    'assets/images/my_image.png',
  );

  pdf.addPage(
    Page(
      build: (context) {
        return Column(
          children: [
            Image(myImage, width: 100, height: 100),
          ],
        );
      },
    ),
  );
---
}
Enter fullscreen mode Exit fullscreen mode

If we have svg images in addition to our png/jpeg images, we can add it like so,

import 'package:flutter/services.dart' show rootBundle;

Future<Uint8List> generatePdf() async {

  final mySvgImage = await rootBundle.loadString('assets/svg/my_svg_image.svg');

  pdf.addPage(
    Page(
      build: (context) {
        return Column(
          children: [
            SvgImage(svg: mySvgImage),
          ],
        );
      },
    ),
  );
---
}
Enter fullscreen mode Exit fullscreen mode

Using Colours

For our final customization, we will look at how to set colours for widgets like Text and Container. The pdf package provides the PdfColor class, which offers various options for representing different colors.


// set RGB color
final white = PdfColor(255, 255, 255);
// set from int in 0xAARRGGBB format
final customColour = PdfColor.fromInt(0xff122D97);
// set from hex string 
final red = PdfColor.fromHex('#FF0000');

// Set a container color to red

---
  pdf.addPage(
    Page(
      build: (context) {
        return Column(
          children: [
            Container(color: red),
          ],
        );
      },
    ),
  );
---
Enter fullscreen mode Exit fullscreen mode

With these steps, you can fully customize your PDF document as needed. From structuring the document layout to styling elements with colours and custom widgets, the pdf and printing packages provide a powerful set of tools to create rich and dynamic PDFs directly within Flutter. Whether you're building reports, invoices, or other types of documents, these tools enable you to design high-quality PDFs directly from your Flutter app.

If you found this helpful, like and share and feel free to drop suggestions and feedback.

Top comments (0)