PDFs (Portable Document Format) are the quintessential scheme for sharing formatted texts in a file; they're easy to interpret and don't require proprietary software like Microsoft Word files do. Since PDFs are a ready-made format that cannot be modified (although they can be modified with some specific programs) like an image, they are an excellent way to share documents and must not be missing from mobile and desktop applications of any kind in general, and in Flutter, we are in luck as they can be used very easily.
Managing PDF files is a common necessity in modern applications: reports, invoices, contracts, manuals, receipts, and more. In Flutter, this scenario is divided into two major areas:
- PDF Viewing (PDF Viewer)
- Dynamic PDF Generation
What Will You Learn in This Guide?
- How to view PDFs in Flutter using different packages.
- Real comparison based on developer feedback.
- How to generate dynamic PDFs (invoices, reports, lists).
- How to display an interactive "PDF Preview".
- How to download, share, or print a PDF.
- Best practices, recommendations, and common problems.
- Real code tested with the `pdf` and `printing` packages.
⭐ Introduction: Why PDF in Flutter?
Flutter offers a great advantage: the ability to work with documents on any platform (Android, iOS, Web, Desktop). This allows for the creation of enterprise apps, e-commerce, ERPs, point-of-sale systems, or management apps, where the PDF is central.
But one thing is true:
- Not all PDF packages work equally well.
- And many developers don't know that some packages might become paid in the future.
Flutter does not include native support for reading or generating PDFs, but it does have a solid ecosystem thanks to third-party packages.
There are two main scenarios:
1️⃣ PDF Viewing
Displaying local, remote, or app-generated PDF files.
2️⃣ PDF Generation
Creating PDF documents from scratch using code.
In this guide, we cover both.
That is why this article compiles real developer experiences, use cases, and practical recommendations for you to make informed decisions.
Part 1 — Best Free PDF Viewer for Flutter (According to the Community)
A frequent question in the Flutter community is:
“What is the best free PDF viewer for Flutter?”
One user experienced issues with `flutter_pdfview` (`_pdfview`) and found that it required more steps to display a PDF from assets. They then tried `pdfrx` and it worked "on the first try" with a single line of code.
The discussion reveals several important things.
- 1. `flutter_pdfview` (`_pdfview`)
✔ Advantages - Very popular on pub.dev
- Works well on many devices
- Active community
❌ Reported Disadvantages
- "file not found" when loading PDF from assets
- Requires copying the PDF to a temporary directory before opening it
- More code for a simple case
Rendering issues on low-end Android models
Some users report unexpected crashes
To display a PDF from assets, you end up writing more than 20 extra lines just to temporarily copy the file.
For many, this is "too much work to open a PDF".
2. `pdfrx` (Community Recommended Choice)
✔ Advantages
- Multi-platform (Android, iOS, Web, Desktop)
- Loads PDF from assets with a single line
- Faster than `_pdfview` on most devices
- Same authorship as `pdf_render`, a library with years of history
- Excellent initial experience: works without complications
❌ Disadvantages
- Fewer downloads than `_pdfview` (because it's newer)
- Its community is still growing
- ⚠ Important user question:
- "Could it become paid in the future?"
- Community Answer:
- Technically any free package could change its terms of use
- But nothing indicates that `pdfrx` will do so
- The general recommendation was: if it works well for you, stick with it
3. Syncfusion PDF Viewer
- ✔ Pro
- It is the most complete on the market
- Many enterprise features
❌ Very serious Cons (explained by an expert user)
- It is NOT open-source
- Commercial license
- If your company has more than 5 developers, you must pay an expensive license
- This also affects those who use your code
Therefore, many developers recommend avoiding Syncfusion if you want to keep your project 100% free.
4. Other mentioned packages
- nutrient.io → very advanced, but oriented towards premium solutions
- UPDF → recommended as an external tool, not as a Flutter package
Conclusion of Part 1
Best PDF Viewer in Flutter (2025): `pdfrx`
- Easy
- Fast
- Multi-platform
- Fewer errors
- Ideal for Flutter Web + Mobile
Part 2 — Dynamic PDF Generation in Flutter (with `pdf` and `printing`)
In this article, I will show you everything you need to know to handle PDF in Flutter:
the best free viewers, the most reliable packages, the real risks of using libraries, and how to generate professional PDFs using `pdf` and `printing`.
Additionally, we include complete code, comparisons, warnings about licenses, and a clear guide to choosing the best solution for your project.
1. Initial Setup
Before starting development, we must configure the plugin or pub in our project:
`pubspec.yaml`
dependencies:
flutter:
sdk: flutter
pdf:
printing:
http:- `pdf`: This library allows us to create and edit PDFs in Flutter.
- `printing`: Allows us to preview, share, and print the PDFs generated from our application.
2. Creating an Invoice Model
Suppose you want to generate invoices for your customers, which is the most common approach for wanting to share and generate PDFs in Flutter. First, create a data model to represent an invoice. You can include relevant information such as the customer's name, the invoice items, and the total amount due. This model can be anything based on your needs, such as a post/publication.
3. Designing the Interface
Design a user interface where users can enter the invoice details. Use widgets like `TextFormField`, `ListView`, and `RaisedButton` to capture the necessary information. This step is optional since the data might be static or come from a database or similar, so it is not critical for PDF creation and depends on your or the project's needs.
4. Generating the PDF
This step is essential, and the PDF must be generated, which is the important factor in this post. So, once you have the invoice data, we will generate the PDF with the previous packages, using the previously installed `pdf` library. We create a special widget that allows generating the PDF document through a widget tree; you can use any type of visual Flutter widget for this task to generate text, images, tables, etc.:
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
// ...
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (context) {
return pw.Center(
child: pw.Text('Factura para Cliente X'),
);
},
),
);5. Preview and Sharing
With the PDF generated, it's time to use the `printing` library to preview the PDF before saving it or sending it to the customer. You can display it in a `PdfPreview` or even send it via email directly from your application:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
final response = await http.get('http://example.com/sample.pdf');
final pdfData = response.bodyBytes;
await Printing.layoutPdf(onLayout: (PdfPageFormat format) async => pdfData);
},
child: Text('Show PDF'),
),
),
),
);
}
}Generate a PDF from API data
Step 2 — Fetch the data (REST API)
Future<List<Map<String, dynamic>>> fetchData() async {
try {
final response = await http.get(Uri.parse(
'http://192.168.1.100:8080/selectOrderItem?orderId=1',
));
if (response.statusCode == 200 || response.statusCode == 202) {
final List<dynamic> jsonData = json.decode(response.body);
return List<Map<String, dynamic>>.from(jsonData);
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}Step 3 — Build the PDF (complete structure)
Here comes the most visual part.
The PDF is built as a widget tree, just like in Flutter, but using `pw.`:
- `pw.Text()`
- `pw.Column()`
- `pw.Table()`
- `pw.Row()`
- `pw.Image()`
Includes:
header with logo
supplier table
purchase table
product details table
Your code represents a professional document ideal for businesses.
Step 4 — Preview the PDF within Flutter
void showPdfPreview(pw.Document pdf) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('PDF Preview'),
content: Container(
width: double.maxFinite,
height: 400,
child: PdfPreview(
build: (format) => pdf.save(),
allowPrinting: false,
allowSharing: true,
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Close'),
),
],
),
);
}This works on:
- Flutter Web
- Android
- iOS
- Desktop
Step 5 — Integrate it into the UI
ElevatedButton(
onPressed: () async {
final pdf = await generatePdfReport(data);
showPdfPreview(pdf);
},
child: Text("Show Report"),
),️ Generate PDF Other Examples
This block is based on your original extended and premium structured content.
- We will create a PDF with:
- Header + logo
- Main data (client, supplier, date...)
- Dynamic table
Totals
Complete Example:
Future<pw.Document> generatePdfReport(int index) async {
final pdf = pw.Document();
final netImage = await networkImage(
'https://i.postimg.cc/02xHkDLd/preview.jpg',
);
final selectedPurchase = purHomeList[index];
final detailList = await Rest.getData(
'getPurchaseDetails?poNo=${selectedPurchase['po_no']}',
);
pdf.addPage(
pw.Page(
build: (context) => pw.Container(
padding: const pw.EdgeInsets.all(12),
decoration: pw.BoxDecoration(
border: pw.Border.all(color: PdfColors.black),
),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
// Header
pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text("NAVINOMIX PVT LTD",
style: pw.TextStyle(
fontSize: 18,
fontWeight: pw.FontWeight.bold)),
pw.Text("Kings Landing 7609 Mckinley Ave"),
pw.Text("Los Angeles, California"),
pw.Text("Contact: +91-9663627343"),
pw.Text("info@navinprince.com"),
pw.Text("www.navinomix.com"),
],
),
pw.Image(netImage, width: 70, height: 100),
],
),
pw.SizedBox(height: 20),
// Purchase Information Table
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(
child: infoTable(selectedPurchase),
),
pw.SizedBox(width: 10),
pw.Expanded(
child: infoRightTable(selectedPurchase),
),
],
),
pw.SizedBox(height: 20),
// Items Table
detailTable(detailList),
],
),
),
),
);
return pdf;
}(Auxiliary functions "infoTable" and "detailTable" can be modularized for clean code.)
Step 3 — Show a PDF Preview
A gem of the `printing` package:
void showPdfPreview(pw.Document pdf) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('PDF Preview'),
content: Container(
width: double.infinity,
height: 450,
child: PdfPreview(
build: (format) => pdf.save(),
allowPrinting: true,
allowSharing: true,
),
),
),
);
}Allows for:
- Viewing the PDF
- Zooming in
- Sharing it
- Printing it
▶️ Step 4 — Integrate it into the interface
ElevatedButton(
onPressed: () async {
final pdf = await generatePdfReport(0);
showPdfPreview(pdf);
},
child: Text("Generar & Mostrar PDF"),
)
I agree to receive announcements of interest about this Blog.
Discover how to work with PDFs in Flutter step by step: viewing, generating, previewing, sharing, and the best packages like pdfrx, pdf, printing, and more. Learn to open PDF files from assets, network, and local storage, and create professional reports, invoices, and dynamic documents with real-world examples and ready-to-use code. The ultimate guide to PDFs in Flutter.