6

I have been trying to open a pdf file using react native, but every library that I try generates an error. I tried the code below:

import React, { Component } from 'react';
import Pdf from 'react-native-pdf';

class OpenBGReport extends Component {
  render() {
    const source = {uri:'http://samples.leanpub.com/thereactnativebook-sample.pdf',cache:true};

    return (
      <View style={styles.container}>
        <Pdf
                    source={source}
                    onLoadComplete={(numberOfPages,filePath)=>{
                        console.log(`number of pages: ${numberOfPages}`);
                    }}
                    onPageChanged={(page,numberOfPages)=>{
                        console.log(`current page: ${page}`);
                    }}
                    onError={(error)=>{
                        console.log(error);
                    }}
                    style={styles.pdf}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'flex-start',
        alignItems: 'center',
        marginTop: 25,
    },
    pdf: {
        flex:1,
        width:Dimensions.get('window').width,
        height:Dimensions.get('window').height,
    }
});

export default OpenBGReport;

However, after installing react-native-pdf, my project stop working and returns: null is not an object (evaluating 'rnfetchblob.documentdir')

What is the best way to open and display a pdf from a URL in react native?

Thanks

myTest532 myTest532
  • 2,091
  • 3
  • 35
  • 78

4 Answers4

13

Expo doesn't support installing native modules and react-native-pdf is a native module. Possible solutions:

  1. If you really want to use native modules, you should use react-native-cli or eject expo project. You can find a more detailed answer in the repository FAQ section (https://github.com/wonday/react-native-pdf#faq).

  2. You can always open PDF files in the phone browser by using react-native's Linking API.

  3. There is a package to display PDF files in expo projects (https://github.com/xcarpentier/rn-pdf-reader-js). Never used the package, and it also seems very sketchy as it supports only the Android platform, and on iOS, you would need to use WebView to display pdf. Also, it doesn't have a lot of downloads on npm and the project itself is prettry stale.

Kacper Wiszczuk
  • 1,809
  • 11
  • 14
4

You can use <WebView/> from "react-native-webview" (https://github.com/react-native-webview/react-native-webview) I tested this one on ios with expo, and it's work!

<WebView 
originWhitelist={['*']} 
source={{uri: uri}}

url can be a web link or path to your file local ('file:///...')

Tima
  • 41
  • 2
2

The best way I found to handle PDF files with Expo is to use buffer to turn them into base64 files, store them in the FileSystem and Share them:

  import { Buffer } from "buffer";
  import * as FileSystem from "expo-file-system";
  import * as Sharing from "expo-sharing";

  res = await // fetch PDF

  const buff = Buffer.from(res, "base64");
  const base64 = buff.toString("base64");

  const fileUri =
    FileSystem.documentDirectory + `${encodeURI("name-of-the-pdf")}.pdf`;


  await FileSystem.writeAsStringAsync(fileUri, base64, {
    encoding: FileSystem.EncodingType.Base64,
  });


  Sharing.shareAsync(res);

Note: You need to install buffer, expo-file-system and expo-sharing

0

I solved the issue by opening the PDF in the users web browser.

import React from 'react';
import { Button, Linking } from 'react-native';

const PermitViewer = ({ downloadUrl }) => {
  const handlePress = async () => {
    const supported = await Linking.canOpenURL(downloadUrl);

    if (supported) {
      await Linking.openURL(downloadUrl);
    } else {
      console.log(`Don't know how to open this URL: ${downloadUrl}`);
    }
  };

  return <Button title="Open PDF" onPress={handlePress} />;
};

export default PermitViewer;
Joeboulton
  • 138
  • 8