2、前端頁面如何優(yōu)雅的顯示PDF(上):渲染頁面

推薦閱讀

準備工作

  1. 創(chuàng)建 react 項目:
create-react-app
  1. 在項目中添加 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";

渲染

  1. 創(chuàng)建 canvas 以便于渲染pdf
const canvasRef = useRef(null)

<canvas
    ref={canvasRef}
    width={window.innerWidth}
    height={window.innerHeight}
/>
  1. 添加渲染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é)來編寫如何能夠==文本復制==。

源碼地址:https://github.com/LiuSandy/react-pdf-render

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豌注,一起剝皮案震驚了整個濱河市伤塌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轧铁,老刑警劉巖每聪,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異齿风,居然都是意外死亡药薯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門救斑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來童本,“玉大人,你說我怎么就攤上這事脸候∏钣椋” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵运沦,是天一觀的道長泵额。 經(jīng)常有香客問我,道長携添,這世上最難降的妖魔是什么梯刚? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮薪寓,結果婚禮上亡资,老公的妹妹穿的比我還像新娘。我一直安慰自己向叉,他們只是感情好锥腻,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著母谎,像睡著了一般瘦黑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奇唤,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天幸斥,我揣著相機與錄音,去河邊找鬼咬扇。 笑死甲葬,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的懈贺。 我是一名探鬼主播经窖,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼梭灿!你這毒婦竟也來了画侣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤堡妒,失蹤者是張志新(化名)和其女友劉穎配乱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皮迟,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡搬泥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了万栅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佑钾。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖烦粒,靈堂內(nèi)的尸體忽然破棺而出休溶,到底是詐尸還是另有隱情,我是刑警寧澤扰她,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布兽掰,位于F島的核電站,受9級特大地震影響徒役,放射性物質(zhì)發(fā)生泄漏孽尽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一忧勿、第九天 我趴在偏房一處隱蔽的房頂上張望杉女。 院中可真熱鬧瞻讽,春花似錦、人聲如沸熏挎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坎拐。三九已至烦磁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哼勇,已是汗流浹背都伪。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留积担,地道東北人陨晶。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像磅轻,于是被迫代替她去往敵國和親珍逸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容