轉:https://segmentfault.com/a/1190000040331855
哈嘍大家好啊。前半年還挺忙的,一直也沒有發文章,有老哥想我了嘛。這兩天發現老有人私信問我 PDF 相關的內容。
那么好,為了我能安心摸魚,我准備出一篇文章來介紹一下如何使用 PDFJS 。
PDF.js 是什么?
PDF.js 由 Mozilla 提供支持。目標是創建一個通用的、基於 Web 標准的平台,用於解析和呈現 PDF。
預覽 PDF
使用 iframe、embed、新窗口打開
測試地址,方案比較簡單,屬於看天吃飯,全靠瀏覽器爸爸賞。
使用方式
<embed src="https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf">
<iframe src="https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf"></iframe>
測試結果
瀏覽器 | 兼容性 | 配圖 |
---|---|---|
Chrome(PC)(Mac) | 支持 | ![]() |
safari(PC)(Mac) | 支持 | ![]() |
Firefox(PC)(Mac) | 支持 | ![]() |
Firefox(PC)(Windows) | 支持 | ![]() |
Edge(PC)(Windows) | 支持 | ![]() |
IE(PC)(Windows) | 不支持 | ![]() |
微信(Android)(vivo x27) | 不支持 | ![]() |
Chrome(Android)(vivo x27) | 不支持 | ![]() |
QQ瀏覽器(Android)(vivo x27) | 不支持 | ![]() |
優點:簡單,支持大部分 PC 瀏覽器(IE 不支持)。跨域資源同樣可以(無需 cors)
缺點:不支持移動端瀏覽器,不支持 IE 等低版本瀏覽器。樣式無法自定義。
pdfjs-view
測試地址,方案兼容性比較好,需要資源同域 或者 cors跨域,可以自定義樣式。
使用方式
-
自己部署一個 pdfjs-view。 (推薦,更穩定)
- 下載項目,然后項目分為兩個版本
/web/viewer-1.html
和/legacy/web/viewer.html
。legacy 支持低版本瀏覽器,使用 es5 編寫,講道理采用這個方案,你肯定也是為了兼容所有瀏覽器。(沒有的話,就gulp generic-legacy
生成一份) - 然后將相關內容復制到你的目錄,上傳 FTP。
- 本質來講他就是一個 HTML 文件,所以你可以針對他進行一些修改,比如說主題顏色、隱藏下載按鈕等等。
- 下載項目,然后項目分為兩個版本
-
使用 CDN 或者官方提供的 pdfjs-view。(不推薦,不穩定,異常CORS)
<iframe src="https://www.lilnong.top/static/project?file=https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf"></iframe>
<iframe src="https://www.lilnong.top/static/project/pdfjs-es5-2.5.207/web/viewer-1.html?file=https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf"></iframe>
測試結果
瀏覽器 | 兼容性 | 兼容性 ES5 版本 | 配圖 |
---|---|---|---|
Chrome(PC)(Mac) | 支持 | 支持 | ![]() |
safari(PC)(Mac) | 支持 | 支持 | ![]() |
Firefox(PC)(Mac) | 支持 | 支持 | ![]() |
Firefox(PC)(Windows) | 支持 | 支持 | ![]() |
Edge(PC)(Windows) | 支持 | 支持 | ![]() |
IE(PC)(Windows) | 不支持 | 支持 | ![]() |
微信(Android)(vivo x27) | 支持 | 支持 | ![]() |
Chrome(Android)(vivo x27) | 支持 | 支持 | ![]() |
QQ瀏覽器(Android)(vivo x27) | 支持 | 支持 | ![]() |
同上,可以看到 IE 都支持,移動端也 OK。
優點:支持大部分瀏覽器(PC、M端都支持)。跨域資源需要 cors。樣式可以自定義。
缺點:需要部署一個 view。
pdfjs-canvas
測試地址,方案比較復雜,需要自己實現一套預覽配套的內容(分頁、放大縮小)。
使用方式
(function() { let el = document.getElementById('canvasWrap'); if (!el) { el = document.createElement('div') el.id = 'canvasWrap' document.body.appendChild(el) } el.innerHTML = '' let winW = document.documentElement.clientWidth // 加載 pdf 資源 let loadingTask = pdfjsLib.getDocument('https://www.lilnong.top/static/pdf/B-4-RxJS%E5%9C%A8React%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-%E9%BE%99%E9%80%B8%E6%A5%A0_.pdf') // PDF 加載完成的回調。 loadingTask.promise.then(function(pdf) { console.log('pdf', pdf) // 可以獲取到總頁數。 let pageNum = pdf.numPages var _pageNum = 1; var renderPageToCanvas = function(pageNum, auto=false) { // 獲取其中的一個頁面 pdf.getPage(pageNum).then(function(page) { // you can now use *page* here _pageNum = pageNum // 獲取原始大小的數據 var viewport = page.getViewport({ scale: 1, }); var scale = (500 / viewport.width).toFixed(2) viewport = page.getViewport({ scale: scale }); var canvas = document.createElement('canvas'); el.appendChild(canvas) var context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // 創建了一個canvas畫板用來存放 var renderContext = { canvasContext: context, viewport: viewport }; page.render(renderContext); if (auto) renderPageToCanvas(pageNum + 1, auto); }); } renderPageToCanvas(_pageNum, true); canvasPrev.onclick = function() { renderPageToCanvas(Math.max(_pageNum - 1, 1)); } canvasNext.onclick = function() { renderPageToCanvas(Math.min(_pageNum + 1, pdf.numPages)); } }, function(reason) { console.error(reason) }) } )()
測試結果
瀏覽器 | 兼容性 | 配圖 |
---|---|---|
Chrome(PC)(Mac) | 支持 | ![]() |
safari(PC)(Mac) | 支持 | ![]() |
Firefox(PC)(Mac) | 支持 | ![]() |
Firefox(PC)(Windows) | 支持 | ![]() |
Edge(PC)(Windows) | 支持 | ![]() |
IE(PC)(Windows) | 不支持 | ![]() |
微信(Android)(vivo x27) | 支持 | ![]() |
Chrome(Android)(vivo x27) | 支持 | ![]() |
QQ瀏覽器(Android)(vivo x27) | 支持 | ![]() |
兼容性也還可以,需要依賴canvas。
下載 PDF
- 下載頭
-
直接打開
- 如果瀏覽器不支持解析 PDF 那么可以觸發下載。
- 如果瀏覽器支持解析 PDF,那么會變成預覽。
- 這個時候我們可以給 a 標簽加上 download 來觸發下載。(需要同域)
總結一下
通過上面的內容我們可以實現前端預覽PDF功能了,我們來總結一下各個方案的特征。
方案 | 移動端 | PC端(高版本瀏覽器) | PC端(IE、低版本瀏覽器) | 跨域 | 復制內容 | 自定義樣式(分頁、下載等等) |
---|---|---|---|---|---|---|
iframe | ❌(平台不支持) | ✅ | ❌(平台不支持) | ✅ | ✅ | ❌ |
embed | ❌(平台不支持) | ✅ | ❌(平台不支持) | ✅(CORS) | ✅ | ❌ |
pdfjs-view | ✅ | ✅ | ❌(ES6 新特性) | ✅(CORS) | ✅ | ✅(基於原有基礎去修改) |
pdfjs-view-es5 | ✅ | ✅ | ✅ | ✅(CORS) | ✅ | ✅(基於原有基礎去修改) |
pdfjs-canvas | ✅ | ✅ | ❌(canvas) | ✅(CORS) | ❌(canvas) | ✅(完全需要自己去實現一整套操作) |
好了,還需要什么內容歡迎留言啊。我給更新到里面。