Tutorials

How to Build a Flutter PDF Viewer?

By ComPDFKit | Tue. 10 Dec. 2024
PDF SDKFlutter

Flutter is an open-source UI software development kit crafted by Google, allowing developers to build cross-platform applications from a single codebase. It supports web browsers, Fuchsia, Android, iOS, Linux, macOS, and Windows.

 

In this guide, we will help you create a cross-platform Flutter PDF Viewer using flutter_pdfview and compdfkit_flutter to ensure your user can view PDF documents on Android or iOS seamlessly and efficiently. By the conclusion, you'll discover the extensive capabilities of ComPDFKit for Flutter, extending well beyond simple PDF viewing within your Flutter applications. Try integrating ComPDFKit for Flutter to empower your applications with advanced PDF manipulation.

 

build-flutter-pdf-viewer

 

Windows   Web   Android   iOS   Mac   Server   React Native   Flutter   Electron
30-day Free

 

 

How to Choose the Right PDF Package for Flutter

 

Selecting a PDF library for Flutter requires evaluating both your needs and the library's quality. 

 

Open-source libraries like flutter_pdfview that offering PDFview widget on Android/iOS, native_pdf_view for cross-platform rendering, and advance_pdf_viewer for PDF handling are ideal for simple applications, but consider the following when choosing one:

 

  • Puv points: Reflects quality, including null safety and Dart compliance.
  • Popularity: Indicates adoption by developers.
  • Update Frequency: Suggests active maintenance.
  • Publisher Verification: Adds credibility.

 

According to the above indicators, flutter_pdfview stands out for its comprehensive examples and ease of integration.

 

If you need advanced PDF features like annotations, forms, or signatures, a commercial PDF library is a better choice. Popular options for Flutter include compdfkit_flutter, Nutrient (PSPDFKit) PDF SDK, and Apryse PDF SDK.

 

Why choose compdfkit_flutter?

 

  • Flexible Pricing: 30-day free trial and community licenses for individual developers, startups, and nonprofits.
  • Comprehensive Support: 24/5 email and chat services ensure smooth project development.
  • Technical Assistance: Unlimited bug reports and remote support for quick, expert solutions.

 

free-trial-license

 

Windows   Web   Android   iOS   Mac   Server   React Native   Flutter   Electron
30-day Free

 

 

Create a Flutter PDF Reader with flutter_pdfview

 

The flutter_pdfview package enables developers to display PDF documents seamlessly in Flutter applications on Android and iOS. It offers essential features like page navigation and zoom, ensuring smooth PDF rendering and interaction.

 

Initial Setup

 

First of all, be sure you have the latest Flutter version installed. Type the following in your terminal app:

 

flutter upgrade

 

Then, create a new Flutter project:

 

flutter create --org com.compdfkit.flutter example

 

Integration of flutter_pdfview

 

1. Open the “pubspec.yaml” file in the “example” folder. Add the flutter_pdfview  dependency.

 

dependencies:
  flutter:
    sdk: flutter
  flutter_pdfview: ^1.3.2

 

2. Next, we will need to use the path_provider package as a dependency to access local storage on Android. Our sample application will copy a PDF document from the assets folder to local storage, and open it. To add the path_provider package as a dependency, enter the following code:

 

dependencies:
  flutter:
    sdk: flutter
  flutter_pdfview: ^1.3.2
  path_provider: ^2.1.1

 

3. Add the PDF documents you want to display in the project.

 

- Create a PDF directory.
mkdir pdfs
         - Copy your example document into the newly created PDF directory and name it PDF_Document.pdf.

         

4. Specify the assets directory in “pubspec.yaml”.

 

flutter:
  assets:
    - pdfs/

  

5. Now it’s time to download the dependencies. From the terminal, run:

 

flutter pub get

 

6. Once the process finishes, navigate to the “lib” folder and open “main.dart”. Then, replace its contents with the following code:

 

import 'dart:async';
import 'dart:io';

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
 @override
 _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State {
 String pathPDF = "";

 @override
 void initState() {
   super.initState();
   fromAsset('pdfs/PDF_Document.pdf', 'sample.pdf').then((f) {
     setState(() {
       pathPDF = f.path;
     });
   });
 }

 Future fromAsset(String asset, String filename) async {
   Completer completer = Completer();
   try {
     var dir = await getApplicationDocumentsDirectory();
     File file = File("${dir.path}/$filename");
     var data = await rootBundle.load(asset);
     var bytes = data.buffer.asUint8List();
     await file.writeAsBytes(bytes, flush: true);
     completer.complete(file);
   } catch (e) {
     throw Exception('Error parsing asset file!');
   }

   return completer.future;
 }

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(body: Builder(
       builder: (BuildContext context) {
         return Center(
             child: Column(
               mainAxisAlignment: MainAxisAlignment.center,
                 children: [
                   ElevatedButton(
                     child: const Text('Open Document'),
                     onPressed: () {
                       if (pathPDF.isNotEmpty) {
                         Navigator.push(
                           context,
                           MaterialPageRoute(
                             builder: (context) => PDFPage(path: pathPDF),
                           ),
                         );
                       }
                     },
                   )
                 ]));

       },
     )),
   );
 }
}

class PDFPage extends StatefulWidget {
 final String? path;

 const PDFPage({Key? key, this.path}) : super(key: key);

 @override
 _PDFPageState createState() => _PDFPageState();
}

class _PDFPageState extends State with WidgetsBindingObserver {
 final Completer _controller =
 Completer();
 int? pages = 0;
 int? currentPage = 0;
 bool isReady = false;
 String errorMessage = '';

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(title: const Text("Document")),
     body: Stack(
       children: [
         PDFView(
           filePath: widget.path,
           onRender: (_pages) {
             setState(() {
               pages = _pages;
               isReady = true;
             });
           },
           onError: (error) {
             setState(() {
               errorMessage = error.toString();
             });
             print(error.toString());
           },
           onPageError: (page, error) {
             setState(() {
               errorMessage = '$page: ${error.toString()}';
             });
             print('$page: ${error.toString()}');
           },
           onViewCreated: (PDFViewController pdfViewController) {
             _controller.complete(pdfViewController);
           },
         ),
         errorMessage.isEmpty
             ? !isReady
             ? const Center(
           child: CircularProgressIndicator(),
         )
             : Container()
             : Center(
           child: Text(errorMessage),
         )
       ],
     ),
   );
 }
}

 

7. Start your Android emulator, or connect a device. 

 

8. Run the app:

 

flutter run

 

3. FAQ

 

Q1: What features does flutter_pdfview offer?

 

A: flutter_pdfview provides a rendering PDF widget in Flutter apps. It supports basic features like pinch-to-zoom and page navigation.

 

Q2: What if I encounter issues?

 

A: Consult its GitHub repository when you need troubleshooting. For complex requirements, please consider other solutions like ComPDFKit, which offer extra features and support.

 

Q3: Can I customize the PDF viewer?

 

A: flutter_pdfview supports basic customization like zooming and scrolling. For advanced features, integration with ComPDFKit will be a better choice.

 

 

Build a Flutter PDF Viewer with compdfkit_flutter

 

ComPDFKit for Flutter is a comprehensive SDK that allows you to quickly add powerful PDF features to your Android and iOS Flutter apps.

 

Video Guide: Fast Build PDF Viewer by Integrating ComPDFKit

 

 

Windows   Web   Android   iOS   Mac   Server   React Native   Flutter   Electron
30-day Free

 

Requirements

 

Android

 

1. Please install the following required packages:

  • The latest stable version of Flutter
  • The latest stable version of Android Studio
  • The Android NDK
  • An Android Virtual Device

 

2. Operating Environment Requirements:

  • A minSdkVersion of 21 or higher.
  • A compileSdkVersion of 33 or higher.
  • A targetSdkVersion of 33 or higher.
  • Android ABI(s): x86, x86_64, armeabi-v7a, arm64-v8a.

 

iOS

 

1. Please install the following required packages:

  • The latest stable version of Flutter
  • The latest stable version of Xcode
  • The latest stable version of CocoaPods. Follow the CocoaPods installation guide to install it.

 

2. Operating Environment Requirements:

  • The iOS 12.0 or higher.
  • The Xcode 12.0 or newer for Objective-C or Swift

 

First of all, to be sure you have the latest Flutter version installed, type the following in your terminal app:

 

flutter upgrade

 

Initial Setup

 

1. Create a Flutter project called example with the flutter CLI:

 

flutter create --org com.compdfkit.flutter example

 

2. In the terminal app, change the location of the current working directory to your project:

 

cd example
Integration of compdfkit_flutter

 

For Android

 

1. open “example/android/app/src/main/AndroidManifest.xml”. Add openPDStorage Permission. 

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.compdfkit.flutter.example">

+    <uses-permission android:name="android.permission.INTERNET"/>

    <!-- Required to read and write documents from device storage -->

+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

<application

+      android:requestLegacyExternalStorage="true">

    </application>   

</manifest>

 

2. Open the app’s Gradle build file “android/app/build.gradle”:

 

open android/app/build.gradle

 

3. Modify the minimum SDK version, All this is done inside the android section:

 

 android {
     defaultConfig {
-        minSdkVersion flutter.minSdkVersion
+        minSdkVersion 21
         ...
     }
 }

 

4. Add the ComPDFKit dependency in pubspec.yaml.

 

 dependencies:
   flutter:
     sdk: flutter
+  compdfkit_flutter: ^1.11.0

 

- From the terminal app, run the following command to get all the packages:

 

flutter pub get

 

 - Open “lib/main.dart” and replace the entire content with the following code. And fill in the license provided to you in the ComPDFKit.init method, this simple example will load a PDF document from the local device file system.

 

import 'dart:io';

import 'package:compdfkit_flutter/compdfkit.dart';
import 'package:compdfkit_flutter/cpdf_configuration.dart';

import 'package:flutter/material.dart';

const String DOCUMENT_PATH = 'pdfs/PDF_Document.pdf';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State createState() => _MyAppState();
}

class _MyAppState extends State {
  @override
  void initState() {
    super.initState();
    _init();
  }

  void _init() async {
    // Please replace it with your ComPDFKit license
    ComPDFKit.init('your compdfkit key');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: SafeArea(
              child: Center(
        child: ElevatedButton(
            onPressed: () async {
              showDocument(context);
            },
            child: const Text(
              'Open Document',
              style: TextStyle(color: Colors.white),
            )),
      ))),
    );
  }

  void showDocument(BuildContext context) async {
    final bytes = await DefaultAssetBundle.of(context).load(DOCUMENT_PATH);
    final list = bytes.buffer.asUint8List();
    final tempDir = await ComPDFKit.getTemporaryDirectory();
    var pdfsDir = Directory('${tempDir.path}/pdfs');
    pdfsDir.createSync(recursive: true);

    final tempDocumentPath = '${tempDir.path}/$DOCUMENT_PATH';
    final file = File(tempDocumentPath);
    if (!file.existsSync()) {
      file.create(recursive: true);
      file.writeAsBytesSync(list);
    }
    var configuration = CPDFConfiguration();
    // How to disable functionality:
    // setting the default display mode when opening
    //      configuration.modeConfig = const ModeConfig(initialViewMode: CPreviewMode.annotations);
    // top toolbar configuration:
    // android:
    //      configuration.toolbarConfig = const ToolbarConfig(androidAvailableActions: [
    //           ToolbarAction.thumbnail, ToolbarAction.bota, 
    //           ToolbarAction.search, ToolbarAction.menu
    //      ],
    //      availableMenus: [
    //        ToolbarMenuAction.viewSettings, ToolbarMenuAction.documentInfo, ToolbarMenuAction.security,
    //      ]);
    // iOS:
    //      configuration.toolbarConfig = const ToolbarConfig(
    //			// ios top toolbar left buttons
    //			iosLeftBarAvailableActions: [
    //          ToolbarAction.back, ToolbarAction.thumbnail
    //      ],
    //			// ios top toolbar right buttons
    //      iosRightBarAvailableActions: [
    //        ToolbarAction.bota, ToolbarAction.search, ToolbarAction.menu
    //      ],
    //      availableMenus: [
    //        ToolbarMenuAction.viewSettings, ToolbarMenuAction.documentInfo, ToolbarMenuAction.security,
    //      ]);
    // readerview configuration
    //      configuration.readerViewConfig = const ReaderViewConfig(linkHighlight: true, formFieldHighlight: true);
    ComPDFKit.openDocument(tempDocumentPath,
        password: '', configuration: configuration);
  }
}

 

5. Add the PDF documents you want to display in the project

 

- Create a pdfs directory

 

mkdir pdfs

 

- Copy your example document into the newly created pdfs directory and name it PDF_Document.pdf.

 

6. Specify the assets directory in “pubspec.yaml”.

 

flutter:
+  assets:
+    - pdfs/

 

For iOS

 

1. Add the ComPDFKit dependency in pubspec.yaml.

 

dependencies:
   flutter:
     sdk: flutter
+  compdfkit_flutter: ^1.11.0

 

2. From the terminal app, run the following command to get all the packages:

 

flutter pub get

 

3. Open your project’s Podfile in a text editor:

 

open ios/Podfile

 

4. Update the platform to iOS 11 and add the ComPDFKit Podspec:

 

- platform :ios, '9.0'
+ platform :ios, '11.0' 
 ...
 target 'Runner' do
   use_frameworks!
   use_modular_headers!`

   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+  pod 'ComPDFKit_Tools', podspec:'https://www.compdf.com/download/ios/cocoapods/xcframeworks/compdfkit_tools/1.11.0.podspec'
+  pod 'ComPDFKit', podspec:'https://www.compdf.com/download/ios/cocoapods/xcframeworks/compdfkit/1.11.0.podspec'

 end

 

5. Go to the “example/ios” folder and run the pod install command:

 

pod install

 

6. Open “lib/main.dart” and replace the entire content with the following code. And fill in the license provided to you in the ComPDFKit.init method, this simple example will load a PDF document from the local device file system.

 

import 'dart:io';

import 'package:compdfkit_flutter/compdfkit.dart';
import 'package:compdfkit_flutter/cpdf_configuration.dart';

import 'package:flutter/material.dart';

const String DOCUMENT_PATH = 'pdfs/PDF_Document.pdf';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State createState() => _MyAppState();
}

class _MyAppState extends State {
  @override
  void initState() {
    super.initState();
    _init();
  }

  void _init() async {
    // Please replace it with your ComPDFKit license
    ComPDFKit.init('your compdfkit key');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: SafeArea(
              child: Center(
        child: ElevatedButton(
            onPressed: () async {
              showDocument(context);
            },
            child: const Text(
              'Open Document',
              style: TextStyle(color: Colors.white),
            )),
      ))),
    );
  }

  void showDocument(BuildContext context) async {
    final bytes = await DefaultAssetBundle.of(context).load(DOCUMENT_PATH);
    final list = bytes.buffer.asUint8List();
    final tempDir = await ComPDFKit.getTemporaryDirectory();
    var pdfsDir = Directory('${tempDir.path}/pdfs');
    pdfsDir.createSync(recursive: true);

    final tempDocumentPath = '${tempDir.path}/$DOCUMENT_PATH';
    final file = File(tempDocumentPath);
    if (!file.existsSync()) {
      file.create(recursive: true);
      file.writeAsBytesSync(list);
    }
    var configuration = CPDFConfiguration();
    // How to disable functionality:
    // setting the default display mode when opening
    //      configuration.modeConfig = const ModeConfig(initialViewMode: CPreviewMode.annotations);
    // top toolbar configuration:
    // android:
    //      configuration.toolbarConfig = const ToolbarConfig(androidAvailableActions: [
    //           ToolbarAction.thumbnail, ToolbarAction.bota, 
    //           ToolbarAction.search, ToolbarAction.menu
    //      ],
    //      availableMenus: [
    //        ToolbarMenuAction.viewSettings, ToolbarMenuAction.documentInfo, ToolbarMenuAction.security,
    //      ]);
    // iOS:
    //      configuration.toolbarConfig = const ToolbarConfig(iosLeftBarAvailableActions: [
    //          ToolbarAction.back, ToolbarAction.thumbnail
    //      ],
    //      iosRightBarAvailableActions: [
    //        ToolbarAction.bota, ToolbarAction.search, ToolbarAction.menu
    //      ],
    //      availableMenus: [
    //        ToolbarMenuAction.viewSettings, ToolbarMenuAction.documentInfo, ToolbarMenuAction.security,
    //      ]);
    // readerview configuration:
    //      configuration.readerViewConfig = const ReaderViewConfig(linkHighlight: true, formFieldHighlight: true);
    ComPDFKit.openDocument(tempDocumentPath,
        password: '', configuration: configuration);
  }
}

 

7. Add the PDF documents you want to display in the project

 

- Create a pdfs directory
mkdir pdfs
         - Copy your example document into the newly created pdfs directory and name it PDF_Document.pdf.

 

8. Specify the assets directory in “pubspec.yaml”.

 

 flutter:
+  assets:
+    - pdfs/

 

9. To protect user privacy: To protect user privacy, before accessing the sensitive privacy data, you need to find the "Info\" configuration in your iOS 10.0 or higher iOS project and configure the relevant privacy terms as shown in the following picture.

 

 

NSCameraUsageDescription
Your consent is required before you could access the function.

NSMicrophoneUsageDescription
Your consent is required before you could access the function.

NSPhotoLibraryAddUsageDescription
Your consent is required before you could access the function.

NSPhotoLibraryUsageDescription
Your consent is required before you could access the function.

 

Run the Flutter PDF Viewer

 

1. Start your Android or iOS emulator, or connect a device.

 

2. Run the app:

 

flutter run

 

 

Windows   Web   Android   iOS   Mac   Server   React Native   Flutter   Electron
30-day Free

 

Troubleshooting

 

1. SSL network request to download the 'ComPDFKit' library failed when cocopods downloaded the iOS third-party library

 

If SSL network requests fail to download the ComPDFKit library when you run pod install, replace the third-party platform download address link of the ComPDFKit library and execute pod install.

 

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
- platform :ios, '10.0'
+ platform :ios, '12.0'
install! 'cocoapods', :deterministic_uuids => false

target 'PDFView_RN' do
  config = use_native_modules!

  # Flags change depending on the env values.
  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    # to enable hermes on iOS, change `false` to `true` and then install pods
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'PDFView_RNTests' do
    inherit! :complete
    # Pods for testing
  end

+  pod 'ComPDFKit', :git => 'https://github.com/ComPDFKit/compdfkit-pdf-sdk-ios-swift.git', :tag => '2.1.3'
+  pod 'ComPDFKit_Tools', :git => 'https://github.com/ComPDFKit/compdfkit-pdf-sdk-ios-swift.git', :tag => '2.1.3'

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable the next line.
  use_flipper!()

  post_install do |installer|
    react_native_post_install(installer)
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end
end

 

The Benefits By Integrating ComPDFKit

 

Compared to flutter_pdfview, ComPDFKit for Flutter offers notable advantages:

  • Advanced features like annotations, editing, forms, OCR, and signatures.
  • Fully customizable UI for a superior user experience.
  • Regular updates, feature enhancements, and responsive support with unlimited bug tracking and remote assistance.
  • Proprietary technology ensuring high reliability and continuous innovation.

 

These capabilities make ComPDFKit a more comprehensive choice for building robust PDF viewers in Flutter applications.

 

 

Conclusion

 

This article has given you a detailed guide on how to integrate flutter_pdfview and ComPDFKit for Flutter. ComPDFKit for Flutter provides you with more PDF processing features beyond reading PDFs.

 

If you want to try ComPDFKit for Flutter or have any questions, please feel free to contact the ComPDFKit team. We are always happy to hear from you and help you.

 

Windows   Web   Android   iOS   Mac   Server   React Native   Flutter   Electron
30-day Free