Blogブログ

ReactでPDF表示する方法

こんにちは。エンジニアの砂町です。

本日はreactで、PDFを埋め込んで表示する方法についてです。
今回は以下の2種類の方法と挙動の違いについてお話しします。

  • Google Docs Viewer
  • react-pdf

※今回ブラウザの環境は、前回までご紹介していたLIFFブラウザ(iOSとAndroid)でのお話になります。今からお話しする問題点は、Chromeなどのブラウザ環境では起きない場合もあります。
LaravelでLINE Message API使ってみた
ReactでLIFF(LINE Login)使ってみた

実装したい機能概要

今回実装したいPDFの表示方法は、

  • LIFFアプリなのでiOS、Androidへの使用が可能
  • 複数ページに跨るのPDFを縦長のスクロールで表示
  • ピッチイン・ピッチアウトでの拡大・縮小が可能

といった要件です。

Google Docs Viewer

まずは下記の実装例をご覧ください。

 export const testComponent = () => {
    const encodeUrl = '表示したいPDFのURLをエンコードしたもの';
    const url = `https://docs.google.com/viewer?url=${encodeUrl}&embedded=true`;
    return(
        <iframe width="100%" height="100%" src={url} ></iframe>
    )
}

まず表示したいPDFのURLをエンコードして、Google Docs Viewerのurlのパラメータに渡してあげます。
高さと横幅を指定した「iframe」でにこのURLを指定したら表示可能です。
Google Docs ViewerではPDFのURLを指定すると、Google Docs Viewer側でPDFを自動で縦長表示してくれます。
またピッチイン・ピッチアウトによる拡大・縮小の制御も自動で行ってくれます。
問題点としては画面が白くなったまま、うまく表示できない時があるということです。

react-pdf

下記の実装例をご覧ください。

export const testComponent = () => {
    const [totalPages, setTotalPages] = useState(0);

    const onLoadSuccess = ({numPages})=>{
        setTotalPages(numPages);
    }

    /**
     * 1ページずつ表示する
     */
    const pdfContents = [];
    for(let i=0; i<totalPages; i++){
        const d = (
            <Page key={i}
                pageNumber={i+1} 
                width={300}
            />
        );
        pdfContents.push(d);
    }

    return (
            <div style={{
                width: "100%",
                height: "100%",
                overflow: 'scroll',
                paddingTop: '32px'
            }}>
                <Document
                    file='PDFのURL'
                    onLoadSuccess={onLoadSuccess}
                >
                    {pdfContents}
                </Document>
            </div>
    );
}

react-pdf はURLを指定しただけでは、Google Docs Viewerのように縦長スクロール表示はできません。
そのため全体のページを取得して、ループさせて縦に並べています。
またピッチイン・ピッチアウトでの拡大・縮小はこの実装ではできません。
react-zoom-pan-pinchというライブラリを用いることで可能ですが、その場合縦長のスクロールと併用させることはうまく動作しませんでした。
ページネーションなどを用いて1枚ずつPDFを表示すればピッチイン・ピッチアウトでの拡大・縮小を行うことが可能です。

まとめ

PDF周りを色々調べてみたのですが、なかなか思ったような動きをするのが難しいなと思いました。
今回はスマホでの使用が前提だったので、最初の想定より考慮する点が多くなりました。
もっとスマートな実装方法がありましたらぜひ教えてください!

砂町

執筆者

Developer

砂町