在React Native中查看PDF

时间:2016-03-09 18:15:26

标签: pdf webview react-native

有人可以提供在React Native中显示PDF的示例代码吗? iOS和Android。

这是我尝试过的:

  render: function() {
    return <WebView
      source={require('./my.pdf')}
      />
  }

^这导致死亡的红色屏幕“无法解决模块”错误。

  render: function() {
    return <WebView
      source={{uri: 'my.pdf'}}
      />
  }

^这会在WebView中显示“Error Loading Page”消息。 “在此服务器上找不到请求的URL”

我知道iOS能够在UIWebView中显示PDF。我认为Android可以做同样的事情。必须有一些关于我如何指定来源的东西。

4 个答案:

答案 0 :(得分:22)

好的,对于后代,我在这里解决了这个问题:

2017年9月13日更新:

有一个新的NPM模块可以使整个过程更加轻松。我建议使用它而不是我原来的答案:

react-native-pdf

安装后,渲染PDF就像这样简单:

export default class YourClass extends Component {
  constructor(props) {
    super(props);
    this.pdf = null;
  }

  render() {
    let yourPDFURI = {uri:'bundle-assets://pdf/YourPDF.pdf', cache: true};

    return <View style={{flex: 1}}>
      <Pdf ref={(pdf)=>{this.pdf = pdf;}}
        source={yourPDFURI}
        style={{flex: 1}}
        onError={(error)=>{console.log(error);}} />
    </View>
  }
}

只需将实际的pdf放在项目的android/app/src/main/assets/pdf文件夹中即可。

原始答案:

<强>的iOS

render: function() {
  return <WebView source={{uri: 'My.pdf'}}/>
}

诀窍在于,您需要将My.pdf包含在Xcode的项目中,并确保将其添加到您的构建目标中。

将其复制到React Native项目文件夹中是不够的。它必须是Xcode项目本身的一部分。

<强>的Android

似乎Android直到5.0(Lollipop)才提供原生PDF查看器。为了解决这个问题,我必须使用三种关键技术:

  1. 从我的APK包中提取PDF并将其存储在我的应用的files文件夹中。这个答案非常有助于实现这一目标:
  2. Android: How to copy files from 'assets' folder to sdcard?

    我稍微调整了代码,以便文件不会转到sdcard,而是转到我应用的files文件夹。这是我添加到MainActivity.java

    的内容
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
    
      AssetManager assetManager = getAssets();
      String[] files = null;
    
      try {
          files = assetManager.list("pdf");
      } catch (IOException e) {
          Log.e("tag", "Failed to get asset file list.", e);
      }
    
      if (files != null) for (String filename : files) {
          InputStream in = null;
          OutputStream out = null;
    
          try {
            in = assetManager.open("pdf/" + filename);
    
            File outFile = new File(getFilesDir(), filename);
            out = new FileOutputStream(outFile);
            copyFile(in, out);
            Log.e("tag", "Copy was a success: " + outFile.getPath());
          } catch(IOException e) {
            Log.e("tag", "Failed to copy asset file: " + "pdf/" + filename, e);
          }
          finally {
              if (in != null) {
                  try {
                      in.close();
                  } catch (IOException e) {
                      // NOOP
                  }
              }
              if (out != null) {
                  try {
                      out.close();
                  } catch (IOException e) {
                      // NOOP
                  }
              }
          }
      }
    }
    
    private void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1){
          out.write(buffer, 0, read);
        }
    }
    

    我还确保我的PDF位于assets/pdf

    下的android/app/src/main文件夹中
    1. 然后我使用react-native-fs包来获取我的PDF的绝对URL,该URL现在位于files文件夹中:

      var RNFS = require('react-native-fs');
      var absolutePath = RNFS.DocumentDirectoryPath + '/My.pdf';
      
    2. 完成所有这些后,我使用react-native-pdf-view实际加载并显示PDF:

      import PDFView from 'react-native-pdf-view';
      
      render: function() {
        var absolutePath = RNFS.DocumentDirectoryPath + '/My.pdf';
      
        return <PDFView
          ref={(pdf)=>{this.pdfView = pdf;}}
          src={absolutePath}
          style={ActharStyles.fullCover} />
      }
      
    3. 祝你好运!

答案 1 :(得分:4)

此问题的简单解决方案是为此设置<WebView> source/uri

https://drive.google.com/viewerng/viewer?embedded=true&url={your pdf url}’

答案 2 :(得分:0)

只需在退货的开头查看标记中添加style={{flex:1}},就可以了。

答案 3 :(得分:0)

Amazon S3 预签名 URL 包含包含“?”的查询字符串和“&”混淆了外部 URL。

因此,您必须先对 S3 预签名 URL 进行编码,然后才能将其传递给 Google 文档查看器。

像这样:

var encodedUrl = encodeURIComponent(presigned_url);

var iFrameUrl = 'https://docs.google.com/gview?url=' + encodingUrl;