【React-PDF】埋め込みPDFを最後までスクロールしないとチェックできない処理作成

react

reactで埋め込みPDFのonScrollを実装している中躓いたためまとめます。

新しいプロジェクトを作成し、実際に作りながら振り返ります。

<環境>

"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-pdf": "^6.0.0-beta.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"


スポンサーリンク

PDFを埋め込む

react-pdfライブラリを下記コマンドでインストールする。

npm install react-pdf --save

表示するための記述を書く

import {Document, Page,pdfjs} from 'react-pdf'
import {useState} from 'react'
import samplePDF from './pdf/sample.pdf' 
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

function App() {
  const [numPages, setNumPages] = useState(null);

  function onDocumentLoadSuccess({ numPages }) {
    setNumPages(numPages);
  }

  return (
    <div className='react-pdf'>
      <h1 style={{textAlign:"center"}}>pdf表示</h1>
      <p style={{textAlign:"center"}}>PDFを最後までスクロールすることによりチェックボックスが活性化されます・</p>
      <div className='pdf' style={{width:"80%",margin:"0 auto", height:400,overflow:"scroll"}}>
       <Document 
       file={samplePDF}
       onLoadSuccess={onDocumentLoadSuccess}>
         {Array.from(
        new Array(numPages),
        (el, index) => (
          <Page
            key={`page_${index + 1}`}
            pageNumber={index + 1}
           />
         ),
       )}
       </Document>
    </div>
    </div>
  );
}
export default App;

※以下の記述を書かないと、表示する際に「Failed to load PDF file.」というエラーが発生してしまうと思います。

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

<Document>のfileプロパティには表示したいPDFのパスを書きます。base64にエンコードされたPDFも以下のように記述することで表示できるはずです。

 <Document 
       file="data:application/pdf;base64, 'base64エンコードデータ'"
       onLoadSuccess={onDocumentLoadSuccess}>

<Document>のonLoadSuccessプロパティは、PDF ファイルの読み込みに成功した時に実行されページ数を取ってくることが可能になります。

その他react-pdfの使い方に関しては以下を参考になります。

https://github.com/wojtekmaj/react-pdf/wiki

react-pdf gitHubページ

これでPDFが表示されます。

※PDFの埋め込みは他にもhtml5のiframe,object,embedタグで行うことができますが、これらを用いる場合だと高さの取得ができませんでした。

最後までスクロールされた場合、チェックボックスを活性化

全体のコード

import {Document, Page,pdfjs} from 'react-pdf'
import {useState} from 'react'
import samplePDF from './pdf/sample.pdf' 


pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

function App() {
  const [numPages, setNumPages] = useState(null);
  const [checkFlg, setCheckFlg] = useState(false)

  function onDocumentLoadSuccess({ numPages }) {
    setNumPages(numPages);
  }
  const handleScroll = (event) =>{
   if (event.target.scrollTop > event.currentTarget.children[0].clientHeight -400){
    //event.target.scrollTop→どのくらいスクロールされたか 
    //event.currentTarget.children[0].clientHeight→react-pdfで生成される要素の高さ。 400→元々の高さ。
      setCheckFlg(true)
   }
} 
  
  return (
   <>
    <div className='react-pdf'>
      <h1 style={{textAlign:"center"}}>pdf表示</h1>
      <p style={{textAlign:"center"}}>PDFを最後までスクロールすることによりチェックボックスが活性化されます・</p>
      <div className='pdf' style={{width:"80%",margin:"0 auto", height:400,overflow:"scroll"}} onScroll={handleScroll}>
       <Document 
       file={samplePDF}
       onLoadSuccess={onDocumentLoadSuccess}>
          {Array.from(
         new Array(numPages),
         (el, index) => (
           <Page
             key={`page_${index + 1}`}
             pageNumber={index + 1}
           />
         ),
       )}
      </Document>
     </div>
    </div>
    <div style={{textAlign:"center"}}>
      <span>ボタン</span>
      {checkFlg? <input id='check' type="checkbox"/>: <input id='check' type="checkbox" disabled/>}
    </div>
   </>
  );
}

export default App;

スクロールされたときにonScrollイベントを発生させ、最後までスクロールされた場合にcheckFlgをtrueにしてその値をstateで保持することによって、チェックボックスを活性しました。

チェックボックスの活性・非活性が分かりづらいと思いますが、できたものの画像を載せます。

画面が最後までスクロールされていないとき。

最後までスクロールされたとき。

この記事が見ていただいた方の役に立てれば幸いです。

コメント

タイトルとURLをコピーしました