推薦閱讀
準(zhǔn)備工作
- 創(chuàng)建 react 項(xiàng)目:
create-react-app
- 在項(xiàng)目中添加 pdf.js 依賴
npm install pdfjs-dist || yarn add pdfjs-dist
使用 pdfjs-dist
關(guān)鍵的兩個文件
- pdf.js
- pdf.worker.js
如何使用
import pdfjs from 'pdfjs-dist';
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
這兩個文件包含了獲取、解析和展示PDF文檔的方法,但是解析和渲染PDF需要較長的時間,可能會阻塞其它JS代碼的運(yùn)行。
為解決該問題,pdf.js依賴了HTML5引入的Web Workers——通過從主線程中移除大量CPU操作(如解析和渲染)來提升性能。
PDF.js的API都會返回一個Promise,使得我們可以優(yōu)雅的處理異步操作。但是文檔甚少,只能查找源碼,瀏覽 github
++題外話:在看別人寫的pdf渲染的項(xiàng)目使用 pdfjs-dist 的時候 這么寫的++
pdfjs.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.js');
通過 required 引入 pdf.worker 但是使用 create-react-app 創(chuàng)建的 react 項(xiàng)目在使用的時候不能夠直接使用 required,如果這么使用會報(bào)這個錯
[圖片上傳失敗...(https://pic2.zhimg.com/80/v2-75bac6b27ae24f93cfc519c24f2c8e9f_1440w.jpg)]
查看源碼就能夠定位到問題原因:他的接受的必須是字符串
# 位置 pdf.js/src/display/worker_options.js Lines 27 to 34 in 4fe9260
/**
* A string containing the path and filename of the worker file.
*
* NOTE: The `workerSrc` option should always be set, in order to prevent any
* issues when using the PDF.js library.
* @var {string}
*/
GlobalWorkerOptions.workerSrc =
同樣的可以使用 CND 的方式解決這個問題
pdfjs.GlobalWorkerOptions.workerSrc = "https://cdn.bootcss.com/pdf.js/2.2.228/pdf.worker.js";
渲染
- 創(chuàng)建 canvas 以便于渲染pdf
const canvasRef = useRef(null)
<canvas
ref={canvasRef}
width={window.innerWidth}
height={window.innerHeight}
/>
- 添加渲染PDF的 js 代碼
# 讀取 PDF 文件
const loadingTask = pdfjs.getDocument(url);
# 獲得到 PDF 對象
const pdf = await loadingTask.promise;
const firstPageNumber = 1;
# 讀取到頁面信息
const page = await pdf.getPage(firstPageNumber);
# 設(shè)置頁面縮放
const scale = 1;
const viewport = page.getViewport({scale: scale});
# 以下寫法清晰度更高
# const devicePixelRatio = window.devicePixelRatio;
# const viewport = page.getViewport({scale: scale * devicePixelRatio});
// Prepare canvas using PDF page dimensions
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
const renderContext = {
canvasContext: context,
viewport: viewport
};
const renderTask = page.render(renderContext);
這樣PDF就渲染到剛才我們寫的canvas中,但是這段代碼只能渲染第一頁,通過改變 firstPageNumber 渲染不同的頁面。
getDocument():用于異步獲取PDf文檔,發(fā)送多個Ajax請求以塊的形式下載文檔。它返回一個Promise,該P(yáng)romise的成功回調(diào)傳遞一個對象,該對象包含PDF文檔的信息,該回調(diào)中的代碼將在完成PDf文檔獲取時執(zhí)行。
getPage():用于獲取PDF文檔中的各個頁面。
getViewport():針對提供的展示比例,返回PDf文檔的頁面尺寸。
render():渲染PDF。
這也寫只能滿足簡單的翻頁需求,如果增加別的需求,放大縮小,文本復(fù)制,就不能改滿足。我們下節(jié)來編寫如何能夠==文本復(fù)制==。