Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Editable PDF in Flutter

Displaying data in PDF view prevents graphic integrity. Irrespective of the platform the user can get a similar view. PDFs are secure, compact multidimensional, and easy to store. Most of the applications today are using custom PDF to create invoices, user profiles, resumes, etc. In this blog, we will learn how to create a custom pdf view in the flutter.


Packages used :

pdf | Dart Package
This library is divided into two parts: a low-level Pdf creation library that takes care of the pdf bits generation. a…pub.dev

flutter_full_pdf_viewer | Flutter Package
Android and iOS working pdf viewer! Add this to your package’s pubspec.yaml file: dependencies…pub.dev

path_provider | Flutter Package
A Flutter plugin for finding commonly used locations on the filesystem. Supports iOS, Android, Linux and MacOS. Not all…pub.dev

pubspec.yaml file :

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.0
pdf: ^3.0.1
flutter_full_pdf_viewer: ^1.0.6
path_provider: ^2.0.1

Create a Pdf Page :

final Document pdf = Document();
pdf.addPage(
Page(
build: (context) => Center(
child: Text('Hello World!'),
),

);

PDF is a Document , it uses addPage property to add a page in the PDF. Here we have created a Centered “Hello World” text in PDF.

Creating a Custom Page :

pdf.addPage(
Page(
orientation: PageOrientation.natural,
build: (context) => Column(
children: [
divider(500),
spaceDivider(5),
Text(
title,
style: TextStyle(fontSize: 40, color: PdfColors.grey),
),
spaceDivider(5),
divider(500),
spaceDivider(60),
Row(
children: [
Text(
"Aeologic Technologies",
textAlign: TextAlign.left,
style: textStyle1(),
),
],
),
spaceDivider(30),
textRow(["Vendor:", "Ship To:"], textStyle1()),
textRow(["Shop11", "Aeo Tech"], textStyle2()),
textRow(["Address", "Address"], textStyle2()),
textRow(["Address", "Address"], textStyle2()),
textRow(["Address", "Address"], textStyle2()),
spaceDivider(30),
Container(
color: PdfColors.white,
child: Table(
border: TableBorder.all(color: PdfColors.black),
children: [
tableRow(
["No.", "Name", "Qut.", "Price", "Amount"], textStyle1()),
tableRow(["1", "APPLE", "3", "20", "60"], textStyle2()),
tableRow(["2", "POP CORN", "20", "10", "200"], textStyle2()),
tableRow(["3", "MANGO", "2", "15", "30"], textStyle2()),
],
),
),
spaceDivider(30),
divider(500),
spaceDivider(30),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 250,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
textRow(["Sub Total", "290"], textStyle2()),
textRow(["Discount", "90"], textStyle2()),
divider(500),
textRow(["Grand Total", "200"], textStyle2()),
divider(500),
],
),
),
],
),
],
),
),
);

Storing the PDF using path_provider package :

final String dir = (await getApplicationDocumentsDirectory()).path;
final String path = '$dir/customPDF.pdf';
final File file = File(path);
await file.writeAsBytes((await pdf.save()));

getApplicationDocumentsDirectory() is a method to get the path of the app directory, we will create a File with ‘$dir/customPDF.pdf’ name and then we will save pdf inside the file using writeAsBytes method.

Full file :

import 'package:flutter/material.dart' as material;
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'dart:io';
import 'main.dart';

orderPdfView(context, String title) async {
final Document pdf = Document();
pdf.addPage(
Page(
orientation: PageOrientation.natural,
build: (context) => Column(
children: [
divider(500),
spaceDivider(5),
Text(
title,
style: TextStyle(fontSize: 40, color: PdfColors.grey),
),
spaceDivider(5),
divider(500),
spaceDivider(60),
Row(
children: [
Text(
"Aeologic Technologies",
textAlign: TextAlign.left,
style: textStyle1(),
),
],
),
spaceDivider(30),
textRow(["Vendor:", "Ship To:"], textStyle1()),
textRow(["Shop11", "Aeo Tech"], textStyle2()),
textRow(["Address", "Address"], textStyle2()),
textRow(["Address", "Address"], textStyle2()),
textRow(["Address", "Address"], textStyle2()),
spaceDivider(30),
Container(
color: PdfColors.white,
child: Table(
border: TableBorder.all(color: PdfColors.black),
children: [
tableRow(
["No.", "Name", "Qut.", "Price", "Amount"], textStyle1()),
tableRow(["1", "APPLE", "3", "20", "60"], textStyle2()),
tableRow(["2", "POP CORN", "20", "10", "200"], textStyle2()),
tableRow(["3", "MANGO", "2", "15", "30"], textStyle2()),
],
),
),
spaceDivider(30),
divider(500),
spaceDivider(30),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 250,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
textRow(["Sub Total", "290"], textStyle2()),
textRow(["Discount", "90"], textStyle2()),
divider(500),
textRow(["Grand Total", "200"], textStyle2()),
divider(500),
],
),
),
],
),
],
),
),
);

final String dir = (await getApplicationDocumentsDirectory()).path;
final String path = '$dir/report.pdf';
final File file = File(path);
await file.writeAsBytes((await pdf.save()));
material.Navigator.of(context).push(
material.MaterialPageRoute(
builder: (_) => PdfViewer(path: path),
),
);
}

Widget divider(double width) {
return Container(
height: 3,
width: width,
decoration: BoxDecoration(
color: PdfColors.grey,
),
);
}

tableRow(List<String> attributes, TextStyle textStyle) {
return TableRow(
children: attributes
.map(
(e) => Text(
" " + e,
style: textStyle,
),
)
.toList(),
);
}

Widget textRow(List<String> titleList, TextStyle textStyle) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: titleList
.map(
(e) => Text(
e,
style: textStyle,
),
)
.toList(),
);
}

TextStyle textStyle1() {
return TextStyle(
color: PdfColors.grey800,
fontSize: 22,
fontWeight: FontWeight.bold,
);
}

TextStyle textStyle2() {
return TextStyle(
color: PdfColors.grey,
fontSize: 22,
);
}

Widget spaceDivider(double height) {
return SizedBox(height: height);
}

PdfViewer :

class PdfViewer extends StatelessWidget {
final String path;
PdfViewer({this.path});

@override
Widget build(BuildContext context) {
return PDFViewerScaffold(
path: path,
);
}
}

PDFViewerScaffold is a widget used to view the pdf.

main.dart file :

import 'package:flutter/material.dart';
import 'package:flutter_full_pdf_viewer/full_pdf_viewer_scaffold.dart';
import 'package:flutter_pdf_create/review.dart';

void main() {
runApp(MaterialApp(
theme: ThemeData(textTheme: TextTheme()),
home: MyPage(),
));
}

class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: MaterialButton(
color: Colors.blue,
child: Text("Generate Pdf"),
onPressed: () {
orderPdfView(context, "Purchase Order");
},
),
),
);
}
}

class PdfViewer extends StatelessWidget {
final String path;
PdfViewer({this.path});

@override
Widget build(BuildContext context) {
return PDFViewerScaffold(
path: path,
);
}
}

Demo Module:


Thanks for reading this article ❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

If we got something wrong? Let me know in the comments. we would love to improve.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter-related queries.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!.

Leave comment

Your email address will not be published. Required fields are marked with *.