Skip to content

A convenience wrapper for building react native apps with PDFTron mobile SDK.

License

Notifications You must be signed in to change notification settings

SMARTDATASYSTEMSLLC/pdftron-react-native

 
 

Repository files navigation

PDFTron React Native Wrapper

Prerequisites

  • No license key is required for trial. However, a valid commercial license key is required after trial.
  • npm or yarn
  • PDFTron SDK >= 6.10.0
  • react-native >= 0.60.0 (for versions before 0.60.0, use branch rn553)

Preview

Android iOS
demo demo

Installation

  1. If using yarn, do: yarn global add react-native-cli

  2. First, follow the official getting started guide on setting up the React Native environment, setting up the iOS environment, setting up the Android environment, and creating a React Native project, the following steps will assume your app is created through react-native init MyApp.

  3. In MyApp folder, install react-native-pdftron by calling:

    yarn add github:PDFTron/pdftron-react-native
    yarn add @react-native-community/cli --dev
    yarn add @react-native-community/cli-platform-android --dev
    yarn add @react-native-community/cli-platform-ios --dev
    yarn install

    or

    npm install github:PDFTron/pdftron-react-native --save
    npm install @react-native-community/cli --save-dev
    npm install @react-native-community/cli-platform-android --save-dev
    npm install @react-native-community/cli-platform-ios --save-dev

Android

  1. Add the following in your android/app/build.gradle file:

    android {
        compileSdkVersion rootProject.ext.compileSdkVersion
    
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    
        defaultConfig {
            applicationId "com.reactnativesample"
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            versionCode 1
            versionName "1.0"
    +       multiDexEnabled true
        }
    
        dependencies {
    +       implementation "androidx.multidex:multidex:2.0.1"
        }
    
        ...
    }
  2. Add the following to your android/app/src/main/AndroidManifest.xml file:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.myapp">
    
      <application
        ...
    +   android:largeHeap="true"
    +   android:usesCleartextTraffic="true">
    
        <activity
          android:name=".MainActivity"
          android:label="@string/app_name"
          android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    -     android:windowSoftInputMode="adjustResize"
    +     android:windowSoftInputMode="adjustPan"
    +     android:theme="@style/CustomAppTheme">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
      </application>
    </manifest>
  3. In your android\app\src\main\java\com\myapp\MainApplication.java file, change Application to MultiDexApplication:

    - import android.app.Application;
    + import androidx.multidex.MultiDexApplication;
    ...
    - public class MainApplication extends Application implements ReactApplication {
    + public class MainApplication extends MultiDexApplication implements ReactApplication {
  4. Replace App.js with what is shown here

  5. Finally in the root project directory, run react-native run-android.

iOS

  1. Open Podfile in the ios folder, add:

    target 'MyApp' do
        use_frameworks!
        pod 'PDFNet', podspec: 'https://www.pdftron.com/downloads/ios/cocoapods/pdfnet/latest.podspec'
        pod 'RNPdftron', :path => '../node_modules/react-native-pdftron'
    end
    
  2. In the ios folder, run pod install.

  3. (Optional) If you need a close button icon, you will need to add the PNG resources to MyApp as well, i.e. ic_close_black_24px.

  4. Replace App.js with what is shown here.

  5. Finally in the root project directory, run react-native run-ios.

Usage

Replace App.js with the following:

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  PermissionsAndroid,
  BackHandler,
  NativeModules,
  Alert
} from 'react-native';

import { DocumentView, RNPdftron } from 'react-native-pdftron';

type Props = {};
export default class App extends Component<Props> {

  constructor(props) {
    super(props);

    this.state = {
      permissionGranted: Platform.OS === 'ios' ? true : false
    };

    RNPdftron.initialize("Insert commercial license key here after purchase");
    RNPdftron.enableJavaScript(true);
  }

  componentDidMount() {
    if (Platform.OS === 'android') {
      this.requestStoragePermission();
    }
  }

  async requestStoragePermission() {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        this.setState({
          permissionGranted: true
        });
        console.log("Storage permission granted");
      } else {
        this.setState({
          permissionGranted: false
        });
        console.log("Storage permission denied");
      }
    } catch (err) {
      console.warn(err);
    }
  }

  onLeadingNavButtonPressed = () => {
    console.log('leading nav button pressed');
    if (Platform.OS === 'ios') {
      Alert.alert(
        'App',
        'onLeadingNavButtonPressed',
        [
          {text: 'OK', onPress: () => console.log('OK Pressed')},
        ],
        { cancelable: true }
      )
    } else {
      BackHandler.exitApp();
    }
  }

  render() {
    if (!this.state.permissionGranted) {
      return (
        <View style={styles.container}>
          <Text>
            Storage permission required.
          </Text>
        </View>
      )
    }

    const path = "https://pdftron.s3.amazonaws.com/downloads/pl/PDFTRON_mobile_about.pdf";

    return (
      <DocumentView
        document={path}
        showLeadingNavButton={true}
        leadingNavButtonIcon={Platform.OS === 'ios' ? 'ic_close_black_24px.png' : 'ic_arrow_back_white_24dp'}
        onLeadingNavButtonPressed={this.onLeadingNavButtonPressed}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});
  • (iOS) For app bundle file path:
document="sample"
  • (Android) For local storage file path:
document="file:///storage/emulated/0/Download/sample.pdf"
  • (Android) For raw resource path (include file extension):
document="android.resource://mypackagename/raw/sample.pdf"
  • (Android) For content Uri:
document="content://..."

Components

DocumentView

A component for displaying documents of different types such as PDF, docx, pptx, xlsx and various image formats.

Props

document

string, required

password

string, optional

leadingNavButtonIcon

string, optional

onLeadingNavButtonPressed

function, optional

showLeadingNavButton

bool, optional

onDocumentLoaded

function, optional

onDocumentError

function, optional

disabledElements

array of string, optional

disabledTools

array of string, optional

customHeaders

object, optional

readOnly

bool, optional

annotationAuthor

string, optional

continuousAnnotationEditing

bool, optional

fitMode

string, optional

layoutMode

string, optional

initialPageNumber

number, optional

pageNumber

number, optional

onPageChanged

function, optional

Perameters:

Name Type Description
previousPageNumber int the previous page number
pageNumber int the current page number
topToolbarEnabled

bool, optional

bottomToolbarEnabled

bool, optional

pageIndicatorEnabled

bool, optional

onAnnotationChanged

function, optional

Perameters:

Name Type Description
action string the action that occurred (add, delete, modify)
annotations array array of annotation data in the format {id: string, pageNumber: int}

Example:

import { DocumentView, Config } from 'react-native-pdftron';
<DocumentView
  ref={(c) => this._viewer = c}
  document={path}
  showLeadingNavButton={true}
  leadingNavButtonIcon={Platform.OS === 'ios' ? 'ic_close_black_24px.png' : 'ic_arrow_back_white_24dp'}
  onLeadingNavButtonPressed={() => {}}
  onDocumentLoaded={() => {}}
  onDocumentError={() => {}}
  disabledElements={[Config.Buttons.searchButton, Config.Buttons.shareButton]}
  disabledTools={[Config.Tools.annotationCreateLine, Config.Tools.annotationCreateRectangle]}
  customHeaders={{Foo: bar}}
  initialPageNumber={11}
  readOnly={false}
  annotationAuthor={'PDFTron'}
  continuousAnnotationEditing={true}
  fitMode={Config.FitMode.FitPage}
  layoutMode={Config.LayoutMode.Continuous}
  onPageChanged={({previousPageNumber, pageNumber}) => { console.log('page changed'); }}
  onAnnotationChanged={({action, annotations}) => { console.log('annotations changed'); }}
/>

Methods

setToolMode

To set the current tool mode (Config.Tools constants).

this._viewer.setToolMode(Config.Tools.annotationCreateFreeHand);
getPageCount

To get the current page count of the document.

Returns a Promise.

this._viewer.getPageCount().then((pageCount) => {
  console.log('pageCount', pageCount);
});
importAnnotations

To import XFDF string to the current document.

Returns a Promise.

const xfdf = '<?xml version="1.0" encoding="UTF-8"?>\n<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">...</xfdf>';
this._viewer.importAnnotations(xfdf);
exportAnnotations

To extract XFDF from the current document.

Perameters:

Name Type Description
options object key: annotList, type: array

Returns a Promise.

this._viewer.exportAnnotations().then((xfdf) => {
  console.log('xfdf', xfdf);
});

With options:

// annotList is an array of annotation data in the format {id: string, pageNumber: int}
this._viewer.exportAnnotations({annotList: annotations}).then((xfdf) => {
  console.log('xfdf for annotations', xfdf);
});
flattenAnnotations

To flatten the forms and (optionally) annotations in the current document. The formsOnly parameter controls whether only forms are flattened.

Returns a Promise.

// flatten forms and annotations in the current document.
this._viewer.flattenAnnotations(false);
saveDocument

To save the current document.

Returns a Promise.

this._viewer.saveDocument().then(() => {
  console.log('saveDocument');
});

Contributing

See Contributing

License

See License

About

A convenience wrapper for building react native apps with PDFTron mobile SDK.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Objective-C 44.0%
  • Java 41.1%
  • JavaScript 10.4%
  • Ruby 3.0%
  • Python 1.5%