Vue.js +pdf.js 處理響應pdf文件流數據,前端轉圖片預覽不可下載


使用場景及原因

  • 實際業務中,一些說明書或協議僅支持用戶在線預覽,為避免用戶自行下載,並進行修改,引發糾紛,特將文件已文件流的形式,傳給前端並轉為圖片顯示,此時可能會有人問,為什么不直接在后端轉圖片,前端直接展示呢?那是因為當系統用戶數量較高時,高並發會時服務器有很大的壓力,可能會導致系統壓測不能通過,前端轉圖片,可以將處理壓力分攤至每個客戶端。
  • 本次操作為Vue.js + pdf.js
  • 本案例是本人寫的一個小demo,有問題的同學,或運行不了,歡迎評論區留言探討
  • 因個人需求不同,並未做打包處理,可自行單獨下載文件,下載地址:
  1. qs :https://pan.baidu.com/s/1061b1m4TU9wodKD9pUnA3w | x9z6
  2. axios :https://pan.baidu.com/s/19OAkzPSqMKyxTayc5uO6IA | 1pmt
  3. vue :https://pan.baidu.com/s/1mPArC55yCjlgN0Xt8abKkQ | 5eyk
  4. pdf :https://pan.baidu.com/s/1gnUkYSpKa0M08wm6k8oScw | addd ( 負責API解析)
  5. pdf.worker : https://pan.baidu.com/s/1LWPD88CE9EQ9ieSv4k6smA | wbi2 ( pdf.worker 需要放在pdf.js 相同的目錄—— 負責核心解析 )
  6. polyfill :https://pan.baidu.com/s/122iutoH-P5jDWLKtRiAPQg | g3tq
      <div id="app" v-cloak>
          <p><a @click="showAgreementBook">預覽產品說明書</a></p>
          <div class="pdfList"></div>
      </div>

      <!--由於axios默認發送請求時,數據格式是Request Payload,並非我們常用的Form Data格式,后端未必能正常獲取到,所以在發送之前,需要使用qs模塊對其進行處理。-->
      <script src="js/lib/qs-6.5.1.min.js"></script>  
      <script src="js/lib/axios-0.19.2.min.js"></script>
      <script src="js/lib/vue-2.6.11.min.js"></script>
      <script src="js/lib/pdf.js"></script>
      <!-- HTML中直接引入vue.js 文件,IE下顯示不正常,而且還報錯:**[Vue warn]: Error in v-on handler: "ReferenceError: “Promise”未定義"**-->
      <script src="js/lib/polyfill.min.js"></script>
      <!-- <script src = "https://polyfill.io/v2/polyfill.min.js"></script> -->
      <script>
      var app = new Vue({
        el: "#app",
        data: {
          insBookData: '', // 協議說明書文件流
        },
        mounted:funciton(){
            this.instructionBook('MC002')
        },
        methods: {
          // 獲取協議說明書文件流
          instructionBook: function (code) { 
            var _this = this
            axios({    
              method: 'post',
              url: 'XXXX',
              data: Qs.stringify({prodCd: code}),
              headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }
            }).then(function (res) {
              _this.insBookData = 'data:application/pdf;base64,' + res.data.ITReq
            })
           },
           // base64 轉blob ,用作處理IE兼容
           dataURItoBlob: function (base64Data) {
             var byteString;
             if (base64Data.split(',')[0].indexOf('base64') >= 0)
               byteString = atob(base64Data.split(',')[1]); //base64 解碼
             else 
               byteString = unescape(base64Data.split(',')[1]);               
             var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]; //mime類型 -- image/png
             var ia = new Uint8Array(byteString.length); //創建視圖
             for (var i = 0; i < byteString.length; i++) {
               ia[i] = byteString.charCodeAt(i);
             }
             var blob = new Blob([ia], {
               type: mimeString
             });
             return blob;
           },
           // 點擊按鈕 預覽操作
           showAgreementBook: function () {
              // for IE
              if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                var blob = this.dataURItoBlob(this.insBookData)
                window.navigator.msSaveOrOpenBlob(blob);
              } else {
                var pdfList = document.querySelector('.pdfList')
                pdfList.innerHTML = ''
                var loadingTask = pdfjsLib.getDocument(this.insBookData);
                loadingTask.promise.then(function (pdf) {
                  var pages = pdf.numPages  // 獲取pdf文件頁數
                  for (var i = 1; i <= pages; i++) {
                    pdf.getPage(i).then(function (page) {
                      var scale = 1.3;
                      var viewport = page.getViewport({scale: scale});
                      var canvas = document.createElement('canvas')  // 生成canvas畫布
                      var context = canvas.getContext('2d');
                      canvas.height = viewport.height;
                      canvas.width = viewport.width;
                      var renderContext = {
                        canvasContext: context,
                        viewport: viewport
                      }
                      pdfList.appendChild(canvas)   // 追加canvas元素至頁面中
                      page.render(renderContext);   // 渲染
                   });
                 }
               });
             }
           } 
         }
        });
      </script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM