pdf_render 0.57.0

Introduction #

pdf_render is a PDF renderer implementation that supports iOS (>= 8.0) and Android (>= API Level 21). It provides you with intermediate PDF rendering APIs and also easy-to-use Flutter Widgets.

Widgets #

Note on iOS Simulator #

Althouth the plugin uses Flutter's Texture to realize fast rendering of PDF pages, it does not work correctly in iOS Simulator and the plugin will fallback to compatibility rendering mode.

Please use the physical device to test the actual behavior.

Single page view #

The following fragment illustrates the easiest way to render only one page of a PDF document using PdfDocumentLoader. It is suitable for showing PDF thumbnail.

  /// render at 100 dpi
  static const scale = 100.0 / 72.0;

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Pdf_render example app'),
        ),
        backgroundColor: Colors.grey,
        body: Center(
          child: PdfDocumentLoader(
            assetName: 'assets/hello.pdf',
            pageNumber: 1,
            calculateSize: (pageWidth, pageHeight, aspectRatio) => Size(pageWidth * scale, pageHeight * scale)
          )
        )
      ),
    );
  }

Of course, PdfDocumentLoader accepts one of filePath, assetName, or data to load PDF document from a file, or other sources.

Multipage view using ListView.builder #

Using PdfDocumentLoader in combination with PdfPageView, you can show multiple pages of a PDF document. In the following fragment, ListView.builder is utilized to realize scrollable PDF document viewer.

  /// render at 100 dpi
  static const scale = 100.0 / 72.0;
  static const margin = 4.0;
  static const padding = 1.0;
  static const wmargin = (margin + padding) * 2;

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Pdf_render example app'),
        ),
        backgroundColor: Colors.grey,
        body: Center(
          child: PdfDocumentLoader(
            assetName: 'assets/hello.pdf',
            documentBuilder: (context, pdfDocument, pageCount) => LayoutBuilder(
              builder: (context, constraints) => ListView.builder(
                itemCount: pageCount,
                itemBuilder: (context, index) => Container(
                  margin: EdgeInsets.all(margin),
                  padding: EdgeInsets.all(padding),
                  color: Colors.black12,
                  child: PdfPageView(
                    pdfDocument: pdfDocument,
                    pageNumber: index + 1,
                    // calculateSize is used to calculate the rendering page size
                    calculateSize: (pageWidth, pageHeight, aspectRatio) =>
                      Size(
                        constraints.maxWidth - wmargin,
                        (constraints.maxWidth - wmargin) / aspectRatio)
                  )
                )
              )
            ),
          )
        )
      ),
    );
  }

PDF rendering APIs #

The following fragment illustrates overall usage of PdfDocument:

import 'package:pdf_render/pdf_render.dart';

...

/// Open the document using either openFile, openAsset, or openData.
PdfDocument doc = await PdfDocument.openAsset('assets/hello.pdf');

// Get the number of pages in the PDF file
int pageCount = doc.pageCount;

// The first page is 1
PdfPage page = await doc.getPage(1);

// For the render function's return, see explanation below.
PdfPageImage pageImage = await page.render();

// PDFDocument must be disposed as soon as possible.
doc.dispose();

And then, you can use PdfPageImage to get the actual RGBA image in dart.ui.Image.

To embed the image in the widget tree, you can use RawImage:

@override
Widget build(BuildContext context) {
  return Center(
    child: Container(
      padding: EdgeInsets.all(10.0),
      color: Colors.grey,
      child: Center(
        child: RawImage(image: pageImage.image, fit: BoxFit.contain))
    )
  );
}

PdfDocument.openXXX #

On PdfDocument class, there are three functions to open PDF from a real file, an asset file, or a memory data.

// from an asset file
PdfDocument docFromFile = await PdfDocument.openAsset('assets/hello.pdf');

// from a file
PdfDocument docFromAsset = await PdfDocument.openFile('/somewhere/in/real/file/system/file.pdf');

// from PDF memory image on Uint8List
PdfDocument docFromData = await PdfDocument.openData(data);

PdfDocument members #

class PdfDocument {
  final int docId; // For internal purpose
  final int pageCount; // Number of pages in the document
  final int verMajor; // PDF major version
  final int verMinor; // PDF minor version
  final bool isEncrypted; // Whether the file is encrypted or not
  final bool allowsCopying; // Whether the file allows you to copy the texts
  final bool allowsPrinting; // Whether the file allows you to print the document

  // Get a page by page number (page number starts at 1)
  Future<PdfPage> getPage(int pageNumber);

  // Dispose the instance.
  void dispose();
}

PdfPage members #

class PdfPage {
  final int docId; // For internal purpose
  final int pageNumber; // Page number (page number starts at 1)
  final int rotationAngle; // Rotation angle; one of 0, 90, 180, 270
  final double width; // Page width in points; pixel size on 72-dpi
  final double height; // Page height in points; pixel size on 72-dpi

  // render sub-region of the PDF page.
  Future<PdfPageImage> render({
    int x = 0, int y = 0,
    int width = 0, int height = 0,
    double fullWidth = 0.0, double fullHeight = 0.0 });

render function extracts a sub-region (x,y) - (x + width, y + height) from scaled fullWidth x fullHeight PDF page image. All the coordinates are in pixels.

The following fragment renders the page at 300 dpi:

const scale = 300.0 / 72.0;
const fullWidth = page.width * scale;
const fullHeight = page.height * scale;
var rendered = page.render(
  x: 0,
  y: 0,
  width: fullWidth.toInt(),
  height: fullHeight.toInt(),
  fullWidth: fullWidth,
  fullHeight: fullHeight);

PdfPageImage members #

/// Page number. The first page is 1.
final int pageNumber;
/// Left X coordinate of the rendered area in pixels.
final int x;
/// Top Y coordinate of the rendered area in pixels.
final int y;
/// Width of the rendered area in pixels.
final int width;
/// Height of the rendered area in pixels.
final int height;
/// Full width of the rendered page image in pixels.
final int fullWidth;
/// Full height of the rendered page image in pixels.
final int fullHeight;
/// PDF page width in points (width in pixels at 72 dpi).
final double pageWidth;
/// PDF page height in points (height in pixels at 72 dpi).
final double pageHeight;
/// Rendered image in dart:ui.Image
final Image image;

PdfPageImageTexture members #

The class is very experimental and subject to change

The class is used to interact with Flutter's Texture class to realize faster rendering comparing to PdfPageImage/RawImage combination.

class PdfPageImageTexture {
  final PdfDocument pdfDocument;
  final int pageNumber;
  final int texId;

  bool operator ==(Object other);
  int get hashCode;

  /// Create a new Flutter [Texture]. The object should be released by calling [dispose] method after use it.
  static Future<PdfPageImageTexture> create({@required PdfDocument pdfDocument, @required int pageNumber});

  /// Release the object.
  Future<void> dispose();

  /// Update texture's sub-rectangle ([destX],[destY],[width],[height]) with the sub-rectangle ([srcX],[srcY],[width],[height]) of the PDF page scaled to [fullWidth] x [fullHeight] size.
  /// If [backgroundFill] is true, the sub-rectangle is filled with white before rendering the page content.
  /// The method can also resize the texture if you specify [texWidth] and [texHeight].
  Future<void> updateRect({int destX = 0, int destY = 0, int width, int height, int srcX = 0, int srcY = 0, int texWidth, int texHeight, double fullWidth, double fullHeight, bool backgroundFill = true});
}

Future plans #

0.57.0 #

  • On iOS Simulator, the plugin now uses compatibility rendering mode; to test the actual behavior, please use physical devices.

0.56.0 #

  • Woops, backgroundFill must be true for default.

0.55.0 #

  • Now render like functions treat null and 0 almost identical.

0.54.0 #

  • PdfPage.render method does not handle w=0,h=0 case (Changes on 0.51.0 breaks compatibility with older versions).

0.53.0 #

  • Introduces PdfPageFit to specify PDF page size fit rule easier.

0.51.0 #

  • PdfPage.render method does not handle w=0,h=0 case.

0.49.0 #

  • Just update documents. Also introduces PdfPageImageTexture class that is used internally to interact with Flutter's Texture class.

0.46.0 #

  • PdfPageView uses Texture rather than RawImage.

0.37.0 #

  • Introducing PdfDocumentLoader and PdfPageView that eases PDF view.

0.33.0 #

  • FIXED: disposing PdfDocument may cause ArrayIndexOutOfBoundsException. (Android)

0.29.0 #

  • Minor build configuration changes.

0.27.0 #

  • Add backgroundFill option to render method.

0.23.0 #

  • First version that supports Android.

0.1.0 #

  • First release.

example/README.md

pdf_render_example #

Demonstrates how to use the pdf_render plugin.

Getting Started #

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Use this package as a library

1. Depend on it

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


dependencies:
  pdf_render: ^0.57.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:pdf_render/pdf_render.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
76
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
88
Learn more about scoring.

We analyzed this package on Sep 13, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.0
  • pana: 0.12.21
  • Flutter: 1.9.1+hotfix.2

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health suggestions

Format lib/pdf_render.dart.

Run flutter format to format lib/pdf_render.dart.

Format lib/pdf_render_widgets.dart.

Run flutter format to format lib/pdf_render_widgets.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
device_info ^0.4.0+2 0.4.0+2
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.7
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8