• <button id="eiyoe"><acronym id="eiyoe"></acronym></button>
    <em id="eiyoe"></em>

  • <rp id="eiyoe"><acronym id="eiyoe"><input id="eiyoe"></input></acronym></rp>
      查看: 284|回復: 0
      上一主題 下一主題

      使用PDF.js渲染canvas實現預覽pdf的效果示例

      79910

      主題

      0

      好友

      積分

      離線 發信

      跳轉到指定樓層
      樓主
      發表于 2021-07-25 21:05 | 只看該作者 | 倒序瀏覽

      一、PDF.js的下載

      從官網直接下載即可,地址:http://mozilla.github.io/pdf.js/getting_started/#download

      建議下載穩定版本,如下圖所示:

      在這里插入圖片描述

      下載完成后將壓縮包解壓放在項目下,按照正常引入方式引入即可。

      二、使用PDF.js

      1.vue使用

      第一步安裝:

      npm install --save pdfjs-dist
      

      第二步引入:

      import PDFJS from 'pdfjs-dist'

      第三步就是在頁面使用即可,下面演示export default中的代碼:

      export default {
       data () {
        return {
         pdfDoc: null,
         pageNum: 1,
         pageRendering: false,
         pageNumPending: null,
         scale: 0.9
        }
       },
       methods: {
        showPDF (url) {
         let _this = this
         PDFJS.getDocument(url).then(function (pdf) {
          _this.pdfDoc = pdf
          _this.renderPage(1)
         })
        },
        renderPage (num) {
         this.pageRendering = true
         let _this = this
         this.pdfDoc.getPage(num).then(function (page) {
          var viewport = page.getViewport(_this.scale)
          let canvas = document.getElementById('the-canvas')
          canvas.height = viewport.height
          canvas.width = viewport.width
      
          // Render PDF page into canvas context
          var renderContext = {
           canvasContext: canvas.getContext('2d'),
           viewport: viewport
          }
          var renderTask = page.render(renderContext)
        
          // Wait for rendering to finish
          renderTask.promise.then(function () {
           _this.pageRendering = false
           if (_this.pageNumPending !== null) {
            // New page rendering is pending
            this.renderPage(_this.pageNumPending)
            _this.pageNumPending = null
           }
          })
         })
        },
        queueRenderPage (num) {
         if (this.pageRendering) {
          this.pageNumPending = num
         } else {
          this.renderPage(num)
         }
        },
        onPrevPage () {
         if (this.pageNum <= 1) {
          return
         }
         this.pageNum--
         this.queueRenderPage(this.pageNum)
        },
        onNextPage () {
         if (this.pageNum >= this.pdfDoc.numPages) {
          return
         }
         this.pageNum++
         this.queueRenderPage(this.pageNum)
        }
       }
      }
      

      2.HTML(5)使用

      第一步正常下載后解壓放入項目中;

      第二步在項目的頁面引入即可,項目結構如下圖:

      在這里插入圖片描述

      由于是公司項目,我將項目名遮住,大家自行取名即可,我在此處將PDF.js放入了js目錄下,大家也可以直接放在項目的根目錄下。

      引入如下代碼:

      <script type='text/javascript' src='js/PDF.js/build/pdf.js'></script>
      

      第三步即可在js中使用。

      ① 引入單頁的pdf:

      var url = sessionStorage.sencondExperience_filePath;
      pdfjsLib.workerSrc = 'PDF.js/build/pdf.worker.js';
      pdfjsLib.getDocument(url).then(function getPdfHelloWorld(pdf) {
      	pdf.getPage(1).then(function getPageHelloWorld(page) {
      		var scale = 1;
      		var viewport = page.getViewport(scale);
      		var canvas = document.getElementById('the-canvas');
      		var context = canvas.getContext('2d');
      		canvas.height = viewport.height;
      		canvas.width = viewport.width;
      		var renderContext = {
      			canvasContext: context,
      			viewport: viewport
      		};
      		page.render(renderContext);
      	});
      });
      

      需要注意的是pdfjsLib.workerSrc中,如果換成是PDFJS.workerSrc會報錯:PDFJS is notdefined。有博客說在其之前加上PDFJS.disableWorker = true;會避免出錯,但我嘗試了錯誤依然存在。使用pdfjsLib.workerSrc不會出錯?。?!

      ②引入多頁的pdf:

      方法一:在html中設置好pdf頁數對應的canvas,然后使用js一頁一頁的去渲染canvas。

      html:

      <canvas id="the-canvas01"></canvas>
      <canvas id="the-canvas02"></canvas>
      <canvas id="the-canvas03"></canvas>
      

      js:

      var url = sessionStorage.third_filePath;
      pdfjsLib.workerSrc = 'PDF.js/build/pdf.worker.js';
      pdfjsLib.getDocument(url).then(function getPdfHelloWorld(pdf) {
      	pdf.getPage(1).then(function getPageHelloWorld(page) {
      		var scale = 1;
      		var viewport = page.getViewport(scale);
      		var canvas = document.getElementById('the-canvas01');
      		var context = canvas.getContext('2d');
      		canvas.height = viewport.height;
      		canvas.width = viewport.width;
      		var renderContext = {
      			canvasContext: context,
      			viewport: viewport
      		};
      		page.render(renderContext);
      	});
      	pdf.getPage(2).then(function getPageHelloWorld(page) {
      		var scale = 1;
      		var viewport = page.getViewport(scale);
      		var canvas = document.getElementById('the-canvas02');
      		var context = canvas.getContext('2d');
      		canvas.height = viewport.height;
      		canvas.width = viewport.width;
      		var renderContext = {
      			canvasContext: context,
      			viewport: viewport
      		};
      		page.render(renderContext);
      	});
      	pdf.getPage(3).then(function getPageHelloWorld(page) {
      		var scale = 1;
      		var viewport = page.getViewport(scale);
      		var canvas = document.getElementById('the-canvas03');
      		var context = canvas.getContext('2d');
      		canvas.height = viewport.height;
      		canvas.width = viewport.width;
      		var renderContext = {
      			canvasContext: context,
      			viewport: viewport
      		};
      		page.render(renderContext);
      	});
      });
      

      可想而知,這種方法對于頁面較少的pdfHIA比較合適,但是若是頁數很多或者是不知道pdf的頁數的情況,這種方法顯然不適合了,由此推薦方法二。

      方法二:只需要定義好在需要渲染的位置,再根據pdf的頁數去動態渲染canvas。

      html

      < div id="canvas"></ div>
      

      js

      //PDF轉成圖片
      var url = sessionStorage.other_filePath;
      pdfjsLib.workerSrc = 'PDF.js/build/pdf.worker.js';
      //創建
      function createPdfContainer(id, className) {
          var pdfContainer = document.getElementById('canvas');
          var canvasNew = document.createElement('canvas');
          $("canvas").on("click",function() {
      		var url = sessionStorage.other_filePath;
      		window.open(url);
          })
          canvasNew.id = id;
          canvasNew.className = className;
          pdfContainer.appendChild(canvasNew);
      };
      
      //渲染pdf
      //建議給定pdf寬度
      function renderPDF(pdf, i, id) {
          pdf.getPage(i).then(function (page) {
      
              var scale = 0.62;
              var viewport = page.getViewport(scale);
      
              //
              //  準備用于渲染的 canvas 元素
              //
      
              var canvas = document.getElementById(id);
              var context = canvas.getContext('2d');
              canvas.height = viewport.height;
              canvas.width = document.documentElement.clientWidth;
      
              //
              // 將 PDF 頁面渲染到 canvas 上下文中
              //
              var renderContext = {
                  canvasContext: context,
                  viewport: viewport
              };
              page.render(renderContext);
          });
      };
      //創建和pdf頁數等同的canvas數
      function createSeriesCanvas(num, template) {
          var id = '';
          for (var j = 1; j <= num; j++) {
              id = template + j;
              createPdfContainer(id, 'pdfClass');
          }
      }
      //讀取pdf文件,并加載到頁面中
      function loadPDF(fileURL) {
          pdfjsLib.getDocument(fileURL).then(function (pdf) {
              //用 promise 獲取頁面
              var id = '';
              var idTemplate = 'cw-pdf-';
              var pageNum = pdf.numPages;
              //根據頁碼創建畫布
              createSeriesCanvas(pageNum, idTemplate);
              //將pdf渲染到畫布上去
              for (var i = 1; i <= pageNum; i++) {
                  id = idTemplate + i;
                  renderPDF(pdf, i, id);
              }
          });
      }
      loadPDF(url)
      

      三、報錯

      1.Uncaught TypeError: Cannot read property ‘getContext’ of null

      這個錯誤是因為在html中需要先寫好<canvas>標簽,定義好id,不能使用div或其他標簽。

      在html中:

      <canvas id="my-canvas"></canvas>

      2.Uncaught (in promise) UnknownErrorException {name: “UnknownErrorException”, message: “Failed to fetch”, details: “UnknownErrorException: Failed to fetch”}

      這個意思是未能捕獲未知錯誤。我在此處出錯的原因主要是后臺給的pdf路徑有問題導致的,換一個正確的即可~~

      3.Uncaught (in promise) InvalidPDFException {name: “InvalidPDFException”, message: “Invalid PDF structure”}

      這個意思是說無效的PDF格式的結構,其實就是代碼中渲染pdf時的結構出現錯誤導致的,我是因為直接對pdf的頁數:pdf.numPages循環,再去
      渲染在canvas導致出錯。錯誤代碼如下:

      for(const i in pdf.numPages){
      	pdf.getPage(i).then(function getPageHelloWorld(page) {
      		var scale = 1;
      		var viewport = page.getViewport(scale);
      		var id = i > 9 ? 'the-canvas' + i : 'the-canvas0' + i;
      		var canvas = document.getElementById(id);
      		var context = canvas.getContext('2d');
      		canvas.height = viewport.height;
      		canvas.width = viewport.width;
      		var renderContext = {
      			canvasContext: context,
      			viewport: viewport
      		};
      		page.render(renderContext);
      	});
      }
      

      此時將id打印才明白所有id都為 the-canvas15,出現這個錯誤主要還是js功底不夠扎實導致......所以不能這樣簡單的循環渲染,正確的解決
      方法請看上面的講解?。?!

      由此關于PDF.js的使用總結就到這了,有什么問題請留言撒~~

      到此這篇關于使用PDF.js渲染canvas實現預覽pdf的效果示例的文章就介紹到這了,更多相關PDF.js渲染canvas內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持腳本之家!

      來源:http://www.jb51.net/html5/771927.html