- 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
)
Android | iOS |
---|---|
-
If using yarn, do:
yarn global add react-native-cli
-
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
. -
In
MyApp
folder, installreact-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
-
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" } ... }
-
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>
-
In your
android\app\src\main\java\com\myapp\MainApplication.java
file, changeApplication
toMultiDexApplication
:- import android.app.Application; + import androidx.multidex.MultiDexApplication; ... - public class MainApplication extends Application implements ReactApplication { + public class MainApplication extends MultiDexApplication implements ReactApplication {
-
Replace
App.js
with what is shown here -
Finally in the root project directory, run
react-native run-android
.
-
Open
Podfile
in theios
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
-
In the
ios
folder, runpod install
. -
(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
. -
Replace
App.js
with what is shown here. -
Finally in the root project directory, run
react-native run-ios
.
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://..."
A component for displaying documents of different types such as PDF, docx, pptx, xlsx and various image formats.
- document
- password
- leadingNavButtonIcon
- onLeadingNavButtonPressed
- showLeadingNavButton
- onDocumentLoaded
- onDocumentError
- disabledElements
- disabledTools
- customHeaders
- readOnly
- annotationAuthor
- continuousAnnotationEditing
- fitMode
- layoutMode
- initialPageNumber
- pageNumber
- topToolbarEnabled
- bottomToolbarEnabled
- pageIndicatorEnabled
- onAnnotationChanged
string, required
string, optional
string, optional
function, optional
bool, optional
function, optional
function, optional
array of string, optional
array of string, optional
object, optional
bool, optional
string, optional
bool, optional
string, optional
string, optional
number, optional
number, optional
function, optional
Perameters:
Name | Type | Description |
---|---|---|
previousPageNumber | int | the previous page number |
pageNumber | int | the current page number |
bool, optional
bool, optional
bool, optional
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'); }}
/>
To set the current tool mode (Config.Tools
constants).
this._viewer.setToolMode(Config.Tools.annotationCreateFreeHand);
To get the current page count of the document.
Returns a Promise.
this._viewer.getPageCount().then((pageCount) => {
console.log('pageCount', pageCount);
});
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);
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);
});
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);
To save the current document.
Returns a Promise.
this._viewer.saveDocument().then(() => {
console.log('saveDocument');
});
See Contributing
See License