web-dev-qa-db-ja.com

PDF in React Native

PDFネイティブでReactを表示するためのサンプルコードを提供してください。 iOSおよびAndroid。

これは私が試したものです:

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

^これにより、「モジュールを解決できません」というエラーが表示され、死の赤い画面が表示されます。

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

^これにより、WebViewに「ページの読み込みエラー」メッセージが表示されます。 「要求されたURLはこのサーバーで見つかりませんでした」

IOSはUIWebViewでPDFを表示できることを知っています。 Androidでも同じことができると思います。ソースがどのように指定されているかには、私が欠落している何かがなければなりません。

14
Axeva

さて、将来の世代のために、この問題をどのように解決したかを以下に示します。

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>
  }
}

プロジェクトのAndroid/app/src/main/assets/pdfフォルダーに実際のPDFを置くだけです。

元の答え:

iOS

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

秘Theは、My.pdfをXcodeのプロジェクトに含め、ビルドターゲットに追加する必要があることです。

それをReact Nativeプロジェクトフォルダにコピーするだけでは十分ではありません。Xcodeプロジェクト自体の一部である必要がありました。

Android

Android= 5.0(Lollipop)までネイティブPDFビューアーを提供しなかったようです。これを回避するには、3つのキーを使用する必要がありましたテクニック:

  1. APKバンドルからPDFを引き出して、アプリのfilesフォルダーに保存します。このSOこの:

Android:「アセット」フォルダーからSDカードにファイルをコピーする方法

ファイルを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を取得しました。これは現在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} />
    }
    

がんばろう!

23
Axeva

この問題の簡単な解決策は、<WebView>source/uriこれに:

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

戻りの開始ビュータグにstyle={{flex:1}}を追加するだけで問題ありません。