Flutter Simple PDF Generating App (original) (raw)

Last Updated : 10 May, 2025

Flutter Community has created several packages to work with PDFs in our apps. In this article, we will be creating a simple PDF-generating app. This application will convert plain text to PDF.

Flutter_Simple-PDF-Generating-App

The packages that we are going to need are listed below with their uses:

Steps to Build a Simple PDF Generating Application

Step 1: Create a new Flutter application

Create a new Flutter application using the command Prompt. To create a new app, write the following command and run it.

flutter create app_name

To know more about it refer this article: Creating a Simple Application in Flutter

Step 2: Adding the Dependency

To add the dependency to the **pubspec.yaml file, add **pdf, path_provider, and **flutter_pdfview as dependencies in the dependencies part of the pubspec.yaml file, as shown below:

Dart `

dependencies: flutter: sdk: flutter pdf: ^3.11.3 path_provider: ^2.1.5 flutter_pdfview: ^1.4.0

`

Now, run the command below in the terminal.

flutter pub get

Step 3: PDF Preview Screen Page

Now that the packages are installed, first we are going to create a PDF preview screen as a new Dart file(**pdf_preview_screen.dart) with the given path as shown below:

**pdf_preview_screen.dart:

Dart `

import 'package:flutter/material.dart'; import 'package:flutter_pdfview/flutter_pdfview.dart';

class PdfPreviewScreen extends StatelessWidget { final String? path;

const PdfPreviewScreen({super.key, this.path});

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

`

In this page, we have created **PDFPreviewScreen as a StatelessWidgetwith the path of the PDF file as the parameter.

Step 4: Main Page

We have imported the necessary packages for creating the desired layout. Here we have imported ****'package:pdf/widgets.dart'** as pw because the material package already has a widget class.

Dart `

import 'dart:io'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:pdf_demo/pdf_preview_screen.dart';

`

This is the **main function, which is called when the app starts:

Dart `

void main() { runApp(MyApp()); }

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'PDF Demo', theme: ThemeData( primarySwatch: Colors.grey, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(), debugShowCheckedModeBanner: false, ); } }

`

The widget package from pdf has different types of widgets for creating the desired layout. **MyHomePage() is a StatelessWidgetthat contains the code for PDF creation. Now we are going to add content to the app. We will be creating a function **writeOnPdf() for this purpose:

Dart `

class MyHomePage extends StatelessWidget { final pdf = pw.Document();

MyHomePage({super.key});

void writeOnPdf() { pdf.addPage(pw.MultiPage( pageFormat: PdfPageFormat.a4, margin: const pw.EdgeInsets.all(32), build: (pw.Context context) { return <pw.Widget>[ pw.Header( level: 0, child: pw.Row( mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, children: <pw.Widget>[ pw.Text('GeeksforGeeks', textScaleFactor: 2), ])), pw.Header(level: 1, text: 'What is Lorem Ipsum?'), pw.Paragraph( text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Paragraph( text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Header(level: 1, text: 'This is Header'), pw.Paragraph( text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Paragraph( text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Padding(padding: const pw.EdgeInsets.all(10)), pw.TableHelper.fromTextArray(context: context, data: const <List>[ ['Year', 'Sample'], ['SN0', 'GFG1'], ['SN1', 'GFG2'], ['SN2', 'GFG3'], ['SN3', 'GFG4'], ]), ]; }, )); }

`

The widgets available in this package are not the same as that available in material package. They are used to structure the layout of the document. Here we have created the document with some header, paragraphs and table to show how the basic structuring can be created.

Dart `

import 'dart:typed_data';

Future savePdf() async { Directory documentDirectory = await getApplicationDocumentsDirectory(); String documentPath = documentDirectory.path; File file = File("$documentPath/example.pdf");

Uint8List pdfData = await pdf.save();

await file.writeAsBytes(pdfData); }

`

The **savePdf() function is used to save the PDF which is later on used to preview the document from the path provided. After writing the above lines of code we have to rerun the app.

The above below code is for the screen which we will get after running the app. It contains an App Bar along with a Raised Button which is used to generate and preview the PDF we have created by writing the above line of code. We pass an async function to onPressed parameter of the button as the file location is needed which returns a future as already stored while saving the file. This is also the end of the MyHomePage class.

Dart `

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.green, foregroundColor: Colors.white, title: const Text("GeeksforGeeks"), ), body: Container( padding: const EdgeInsets.all(10), child: Column( children: [ SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, ), child: const Text( 'Preview PDF', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white), ), onPressed: () async { writeOnPdf(); await savePdf();

              Directory documentDirectory =
                  await getApplicationDocumentsDirectory();

              String documentPath = documentDirectory.path;

              String fullPath = "$documentPath/example.pdf";
              print(fullPath);

              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => PdfPreviewScreen(
                            path: fullPath,
                          )));
            },
          ),
        ),
      ],
    ),
  ),
);

} }

`

To know more about ElevatedButton in Flutter : Flutter – ElevatedButton Widget.

**Complete Source Code

**main.dart:

Dart `

import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_pdfview/flutter_pdfview.dart'; import 'package:geeks_for_geeks/pdf_preview_screen.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw;

void main() { runApp(MyApp()); }

class PdfPreviewScreen extends StatelessWidget { final String? path;

const PdfPreviewScreen({super.key, this.path});

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

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'PDF Demo', theme: ThemeData( primarySwatch: Colors.grey, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(), debugShowCheckedModeBanner: false, ); } }

class MyHomePage extends StatelessWidget { final pdf = pw.Document();

MyHomePage();

Future savePdf() async { try { Directory documentDirectory = await getApplicationDocumentsDirectory(); String documentPath = documentDirectory.path; File file = File("$documentPath/example.pdf");

  Uint8List pdfData = await pdf.save();

  await file.writeAsBytes(pdfData);
} catch (e) {
  debugPrint("E:$e");
}

}

void writeOnPdf() { pdf.addPage(pw.MultiPage( pageFormat: PdfPageFormat.a4, margin: const pw.EdgeInsets.all(32), build: (pw.Context context) { return <pw.Widget>[ pw.Header( level: 0, child: pw.Row( mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, children: <pw.Widget>[ pw.Text('GeeksforGeeks', textScaleFactor: 2), ])), pw.Header(level: 1, text: 'What is Lorem Ipsum?'), pw.Paragraph(text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Paragraph(text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Header(level: 1, text: 'This is Header'), pw.Paragraph(text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Paragraph(text: ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus molestie nunc non blandit massa. Bibendum enim facilisis gravida neque. Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras fermentum. '''), pw.Padding(padding: const pw.EdgeInsets.all(10)), pw.TableHelper.fromTextArray( context: context, data: const <List>[ ['Year', 'Sample'], ['SN0', 'GFG1'], ['SN1', 'GFG2'], ['SN2', 'GFG3'], ['SN3', 'GFG4'], ]), ]; }, )); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("GeeksforGeeks"), backgroundColor: Colors.green, foregroundColor: Colors.white, ), body: Container( padding: const EdgeInsets.all(10), child: Column( children: [ SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, ), child: const Text( 'Preview PDF', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white), ), onPressed: () async { writeOnPdf(); await savePdf();

              Directory documentDirectory =
                  await getApplicationDocumentsDirectory();

              String documentPath = documentDirectory.path;

              String fullPath = "$documentPath/example.pdf";
              print(fullPath);

              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => PdfPreviewScreen(
                            path: fullPath,
                          )));
            },
          ),
        ),
      ],
    ),
  ),
);

} }

`

**Output: