React 中使用 pdf.js 將 pdf 轉換成圖片


pdf.js 主要用於在網頁上展示 pdf 文檔,是一個用戶解析和渲染 pdf 文件的開源庫。本文主要介紹如何在 react 中使用 pdf.js 解析 pdf 文件,並最終轉換成圖片形式。

一、 安裝 pdf.js 庫文件

要在 react 中使用 pdf.js,首先需要安裝對應的依賴。對此 pdf.js 提供了 pdfjs-dist 庫,我們可以通過 npm 進行下載.

npm install pdfjs-dist --save

二、 在組件中使用。

在 pdf.js 的 issues 中找到 pdf.js 在 react 中的使用方法,參考 issue:Using pdf.js in React】 

1. 引入 pdf.js 文件

2. 編寫文件上傳組件

3. 編寫上傳屬性和方法

4. pdf 解析

5. canvas 設置

6. 生成圖片

從上面的代碼可以看出,由 pdf 生成圖片主要需要經歷以下幾個過程:

上傳 pdf 文件 -> 解析 pdf -> 生成 canvas 對象 -> 轉換成圖片 -> (插入頁面或導出文件)

三、在項目中查看效果

導入后查看

 

完整的 jsx 代碼如下:

  1 import React from 'react';
  2 import { Modal } from 'antd'
  3 import * as PDFJS from "pdfjs-dist";
  4 import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
  5 
  6 const Dragger = Upload.Dragger;
  7 
  8 PDFJS.GlobalWorkerOptions.workerSrc = pdfjsWorker;
  9 
 10 export default class ImportPdf extends React.Component {
 11     state = {
 12         pdf: '',
 13     }
 14 
 15     openPage(pdfFile, pageNumber, context) {
 16         var scale = 2;
 17         pdfFile.getPage(pageNumber).then(function (page) {
 18             // reference canvas via context
 19             const viewport = page.getViewport(scale);
 20             var canvas = context.canvas;
 21             canvas.width = viewport.width;
 22             canvas.height = viewport.height;
 23             canvas.style.width = "100%";
 24             canvas.style.height = "100%";
 25             var renderContext = {
 26                 canvasContext: context,
 27                 viewport: viewport
 28             };
 29             page.render(renderContext);
 30         });
 31         return;
 32     }
 33 
 34     exportImg(self) {
 35         // 將 canvas 導出成 img
 36         $('#pdf-container canvas').each(function (index, ele) {
 37             var canvas = document.getElementById("pageNum" + (index + 1));
 38             // 將 canvas 轉成 base64 格式的圖片
 39             let base64ImgSrc = canvas.toDataURL("image/png")
 40             const img = document.createElement("img")
 41             img.setAttribute('class', 'pdf-img');
 42             img.src = base64ImgSrc
 43             img.style.width = '100%';
 44             // 將圖片掛載到 dom 中
 45             $('#pdf-container').append(img);
 46         });
 47     }
 48 
 49     readPdf(file) { 
 50         // pdf.js無法直接打開本地文件,所以利用FileReader轉換
 51         const reader = new FileReader();
 52         reader.readAsArrayBuffer(file);
 53         reader.onload = function (e) {
 54             const typedarray = new Uint8Array(this.result);
 55             const loadingTask = PDFJS.getDocument(typedarray);
 56             loadingTask.promise.then(function (pdf) {
 57                 if (pdf) {
 58                     // pdf 總頁數
 59                     const pageNum = pdf.numPages;
 60                     for (let i = 1; i <= pageNum; i++) {
 61                         // 生成每頁 pdf 的 canvas
 62                         const canvas = document.createElement('canvas');
 63                         canvas.id = "pageNum" + i;
 64                         // 將 canvas 添加到 dom 中
 65                         $('#pdf-container').append(canvas);
 66                         const context = canvas.getContext('2d');
 67                         self.openPage(pdf, i, context);
 68                     }
 69                     setTimeout(() => {
 70                         self.exportImg(self)
 71                     }, 1000);
 72                 }
 73             }).catch(function (reason) {
 74                 console.error("Error: " + reason);
 75             });
 76         };
 77     }
 78 
 79     render() {
 80         const self = this;
 81         const uploadProps = {
 82             name: 'file',
 83             accept: '.pdf',
 84             action: '',
 85             onChange(info) {
 86                 const status = info.file.status;
 87                 if (status != 'done') {
 88                     self.setState({ loading: true });
 89                 }
 90                 if (status !== 'uploading') {
 91                     console.log(info.file, info.fileList);
 92                 }
 93                 if (status === 'done') {
 94                     self.setState({ loading: false });
 95                     message.success(`${info.file.name} 導入成功`);
 96                     // 解析 pdf 文件
 97                     self.readPdf(info.file.originFileObj);
 98                 } else if (status === 'error') {
 99                     console.log(`${info.file.name} 導入失敗`);
100                 }
101             },
102         };
103         return (
104             <Modal
105                 title="導入pdf"
106                 width={480}
107                 className="import-pdf-modal"
108                 footer={null}
109             >
110                 <Spin tip="導入中" spinning={this.state.loading}>
111                     <Dragger {...uploadProps} id="document">
112                         <p className="ant-upload-drag-icon">
113                             <Icon type="inbox" />
114                         </p>
115                         <p className="ant-upload-text">點擊或將文件拖拽到這里上傳</p>
116                         <p className="ant-upload-hint">支持擴展名:.pdf</p>
117                         <div id='pdf-container' style={{ height: 0, overflow: 'hidden' }}></div>
118                     </Dragger>
119                 </Spin>
120             </Modal>
121         )
122     }
123 }

 

【參考】

pdf.js

Is there a pre-built version PDF.js available?

pdf2img

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM