推薦閱讀
準備工作
- 創(chuàng)建 react 項目:
create-react-app
- 在項目中添加 pdf.js 依賴
npm install pdfjs-dist || yarn add pdfjs-dist
使用 pdfjs-dist
關鍵的兩個文件
- 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代碼的運行。
為解決該問題箱歧,pdf.js依賴了HTML5引入的Web Workers——通過從主線程中移除大量CPU操作(如解析和渲染)來提升性能矾飞。
PDF.js的API都會返回一個Promise,使得我們可以優(yōu)雅的處理異步操作呀邢。但是文檔甚少洒沦,只能查找源碼,瀏覽 github
++題外話:在看別人寫的pdf渲染的項目使用 pdfjs-dist 的時候 這么寫的++
pdfjs.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.js');
通過 required 引入 pdf.worker 但是使用 create-react-app 創(chuàng)建的 react 項目在使用的時候不能夠直接使用 required,如果這么使用會報這個錯
[圖片上傳失敗...(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);
# 設置頁面縮放
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巷蚪,該Promise的成功回調(diào)傳遞一個對象,該對象包含PDF文檔的信息濒翻,該回調(diào)中的代碼將在完成PDf文檔獲取時執(zhí)行屁柏。
getPage():用于獲取PDF文檔中的各個頁面。
getViewport():針對提供的展示比例肴焊,返回PDf文檔的頁面尺寸前联。
render():渲染PDF。
這也寫只能滿足簡單的翻頁需求娶眷,如果增加別的需求似嗤,放大縮小,文本復制届宠,就不能改滿足烁落。我們下節(jié)來編寫如何能夠==文本復制==。