fillable_pdf_form 1.0.0

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 49

Plugin to fill/retrieve PDF fields

This plugin allows to fill fields from PDF documents and export the result in a new file. The plugin is also able to extract all the fields' content of a given PDF.

Demo

Compatibility

On Android, the plugin is using the iTextPDF v5 library and is compatible with all Android versions (API 16+).

On iOS, the plugin is using PDFKit and is thus limited to iOS 11.

Getting started

How it works

This plugin has two features :

  • Read the content of a PDF file and extract all the fields with their values
  • Fill the fields of a PDF and export the result in a new file (always in the filesystem)

Source

The Dart API allows you to pick a file from :

  • the Flutter project resources,
  • the app resources (Android/iOS),
  • or the filesystem

Android permissions

On Android, please add the following permissions to your AndroidManifest.xml:

// Only required if you want to read the content of PDF stored in the filesystem
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

// Only required if you want to create a PDF in the filesystem
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Your Flutter application

Firstly, please import the plugin:

import 'package:fillable_pdf_form/fillable_pdf_form.dart';

Then please follow the example to use the right method.

1.0.0 - 27th August

  • Initial release

example/lib/main.dart

import 'dart:async';

import 'package:fillable_pdf_form/fillable_pdf_form.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'ui_utils.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fill PDF fields Plugin example'),
        ),
        body: PageBody(),
      ),
    );
  }
}

class PageBody extends StatefulWidget {
  @override
  _PageBodyState createState() => _PageBodyState();
}

class _PageBodyState extends State<PageBody> {
  DocumentSource source;

  @override
  void initState() {
    super.initState();

    source = DocumentSource.flutter;
    if (!mounted) {
      return;
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return DocumentSourceData(source,
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              DropdownButton<DocumentSource>(
                items: <DropdownMenuItem<DocumentSource>>[
                  DropdownMenuItem<DocumentSource>(
                      child: Text('Flutter'), value: DocumentSource.flutter),
                  DropdownMenuItem<DocumentSource>(
                      child: Text('Platform assets'),
                      value: DocumentSource.platform),
                  DropdownMenuItem<DocumentSource>(
                      child: Text('Device storage'),
                      value: DocumentSource.storage)
                ],
                value: source,
                onChanged: (DocumentSource value) {
                  setState(() {
                    source = value;
                  });
                },
              ),
              SizedBox(height: 75.0),
              PDFExtractorButtonWidget(
                  text: 'Open empty PDF', fileName: 'pdf_example_empty.pdf'),
              SizedBox(height: 10.0),
              PDFExtractorButtonWidget(
                  text: 'Open filled PDF', fileName: 'pdf_example_filled.pdf'),
              SizedBox(height: 10.0),
              PDFGeneratorButtonWidget(
                  text: 'Fill PDF', fileName: 'pdf_example_empty.pdf'),
            ],
          ),
        ));
  }
}

class DocumentSourceData extends InheritedWidget {
  final DocumentSource source;

  DocumentSourceData(this.source, {Key key, Widget child})
      : super(key: key, child: child);

  @override
  bool updateShouldNotify(DocumentSourceData oldWidget) {
    return oldWidget.source != source;
  }

  static DocumentSourceData of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(DocumentSourceData);
  }
}

enum DocumentSource { flutter, platform, storage }

class PDFExtractorButtonWidget extends StatefulWidget {
  final String text;
  final String fileName;

  PDFExtractorButtonWidget({@required this.text, @required this.fileName});

  @override
  State<StatefulWidget> createState() => _PDFExtractorButtonWidgetState();
}

class _PDFExtractorButtonWidgetState extends State<PDFExtractorButtonWidget> {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
        child: Text(widget.text),
        onPressed: () {
          _openPDF(widget.fileName);
        });
  }

  void _openPDF(String filePath) async {
    Future<Map<String, String>> future;

    switch (DocumentSourceData.of(context).source) {
      case DocumentSource.flutter:
        future = FillablePdfForm.extractPDFFieldsFromFlutterFile(
            file: 'res/$filePath');
        break;
      case DocumentSource.platform:
        future =
            FillablePdfForm.extractPDFFieldsFromApplicationFile(file: filePath);
        break;
      case DocumentSource.storage:
        future = FillablePdfForm.extractPDFFieldsFromFile(
            androidFilePath: '/sdcard/$filePath',
            iOSFilePath: filePath,
            requestReadStoragePermission: false);
        break;
    }

    future.then((map) => extractMapValues(map)).then((fields) {
      showDialogWith(context, 'Content of the PDF', fields);
    }).catchError((err) {
      if (err is PlatformException) {
        showDialogWith(context, 'Error!', err.message);
      } else {
        showDialogWith(context, 'Error!', err?.toString());
      }
    });
  }

  String extractMapValues(Map map) {
    StringBuffer buffer = StringBuffer();
    for (String key in map.keys) {
      buffer
        ..write(key)
        ..write(' : "')
        ..write(map[key])
        ..writeln('"');
    }
    return buffer.toString();
  }
}

class PDFGeneratorButtonWidget extends StatefulWidget {
  final String text;
  final String fileName;

  PDFGeneratorButtonWidget({@required this.text, @required this.fileName});

  @override
  State<StatefulWidget> createState() => _PDFGeneratorButtonWidgetState();
}

class _PDFGeneratorButtonWidgetState extends State<PDFGeneratorButtonWidget> {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
        child: Text(widget.text),
        onPressed: () {
          _fillPDF(widget.fileName);
        });
  }

  void _fillPDF(String fileName) async {
    Future<int> future;

    String androidDestination = '/sdcard/output.pdf';
    String iOSDestination = 'output.pdf';
    Map<String, String> content = {};

    content['Given Name Text Box'] = 'Last name';
    content['Family Name Text Box'] = 'First name';

    switch (DocumentSourceData.of(context).source) {
      case DocumentSource.flutter:
        future = FillablePdfForm.fillPDFFieldsFromFlutterFile(
            pdfFileToFill: 'res/$fileName',
            androidDestination: androidDestination,
            iOSDestination: iOSDestination,
            fieldsContent: content);
        break;
      case DocumentSource.platform:
        future = FillablePdfForm.fillPDFFieldsFromApplicationFile(
            pdfFileToFill: fileName,
            androidDestination: androidDestination,
            iOSDestination: iOSDestination,
            fieldsContent: content);
        break;
      case DocumentSource.storage:
        future = FillablePdfForm.fillPDFFieldsFromFile(
            pdfFileToFill: '/sdcard/$fileName',
            requestWriteStoragePermission: true,
            androidDestination: androidDestination,
            iOSDestination: iOSDestination,
            fieldsContent: content);
        break;
    }

    future.then((fieldsFilled) {
      showDialogWith(context, 'PDF Filled!', '$fieldsFilled fields filled');
    }).catchError((err) {
      if (err is PlatformException) {
        showDialogWith(context, 'Error!', err.message);
      } else {
        showDialogWith(context, 'Error!', err?.toString());
      }
    });
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  fillable_pdf_form: ^1.0.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:fillable_pdf_form/fillable_pdf_form.dart';
  
Version Uploaded Documentation Archive
1.0.0 Aug 27, 2018 Go to the documentation of fillable_pdf_form 1.0.0 Download fillable_pdf_form 1.0.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
25
Health:
Code health derived from static analysis. [more]
56
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
49
Learn more about scoring.

We analyzed this package on Nov 19, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.6
  • Flutter: 0.11.3

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health issues and suggestions

Fix lib/fillable_pdf_form.dart. (-43.75 points)

Analysis of lib/fillable_pdf_form.dart failed with 2 errors:

line 55 col 11: A value of type 'Future<PermissionStatus>' can't be assigned to a variable of type 'Future<bool>'.

line 148 col 11: A value of type 'Future<PermissionStatus>' can't be assigned to a variable of type 'Future<bool>'.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.28.0 <3.0.0
flutter 0.0.0
meta ^1.1.6 1.1.6
simple_permissions ^0.1.5 0.1.9
Transitive dependencies
collection 1.14.11
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8