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
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;
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();
}
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,
),
),
],
);
},
),
);
---
}
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),
],
);
},
),
);
---
}
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),
],
);
},
),
);
---
}
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),
],
);
},
),
);
---
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)