Vue-base64移動端PDF展示


  作為一個后端開發,寫前端的一些功能也是頭大,好在網友強大,網上資源比較多;做一個移動端PDF預覽的功能,本來可以通過window.open(),打開的,但是沒辦法,做后台的小伙伴,傳給前端的數據是base64位,我只能按照后台給的數據進行處理了;

  方法一:

  最原始的方式:通過canvas將字節流轉成圖片,方法簡單,別人的代碼直接抄過來就能用;但是缺點也同樣嚴重,圖片展示清晰度很低

      代碼如下

   1.安裝依賴    

 

npm install   pdfjs-dist@2.2.228
npm install   pdfjs@2.3.5

     2.template代碼:

<template>    
 <div style="background-color:white;height:100%;"> 
    <div class="v-viewbtns">
        <div style="position:relative">
            <button @click="scaleAdd">+</button>
            <button @click="scaleReduce">-</button>
        </div>
    </div>
    <div class="pdfList"  style="position:relative;overflow:auto;">
    </div> 
 </div>     
</template>

 

 3.js代碼

 

import PDFJS from 'pdfjs-dist';
import {getters} from '@/lib/store';
import {Dialog} from 'vant';


export default {
    data(){
      return {
            pdfDataList : '',
            scale:100,
        }
    },
    created() {
        PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min.js');
    },
    mounted(){
        this.getPdfList(); //在這里調用pdf的方法       
    },
      methods:{
        getPdfList(){
            //這里是我用來請求后台返回給我返回base64格式的文件發的ajax請求
            this.$toast.loading('加載中');
            this.$axios.post(url, params)
            .then(res => {
                 if(res.data){
                     this.getPageNum(res);           
                     var data = res.data;
                      this.pdfDataList = data ; //接收傳回來的數據
                      this.showPdf();    //調用生成PDF
                 }else{
                     this.loading = false;
                     Dialog.alert({
                         message:res.message
                     }).then(()=>{
                          this.$router.go(-1);
                     });
                 }
                 this.$toast.hide();              
            }); 
        },
        async showPdf(){
                let pdfList = document.querySelector('.pdfList') //通過querySelector選擇DOM節點,使用document.getElementById()也一樣
                let base64 = this.pdfDataList.fileValue //獲得bas464編碼
                let decodedBase64 = atob(base64) //使用瀏覽器自帶的方法解碼
                let pdf = await  PDFJS.getDocument({data: decodedBase64}) //返回一個pdf對象
                let pages = pdf.numPages //聲明一個pages變量等於當前pdf文件的頁數
                for (let i = 1; i <= pages; i++) { //循環頁數
                    let canvas = document.createElement('canvas') ;
                    let page = await pdf.getPage(i) //調用getPage方法傳入當前循環的頁數,返回一個page對象
                    let scale = 0.5;//縮放倍數,1表示原始大小
                    let width = document.body.clientWidth ;//窗口的寬度 
                    let viewport = page.getViewport(scale); 
                    let context = canvas.getContext('2d'); //創建繪制canvas的對象
                    canvas.height = viewport.height; //定義canvas高和寬
                    canvas.width = viewport.width;
                    let renderContext = {
                        canvasContext: context,
                        viewport: viewport
                    };
                    await page.render(renderContext)
                    canvas.className = 'canvas' //給canvas節點定義一個class名,這里我取名為canvas
                    pdfList.appendChild(canvas) //插入到pdfList節點的最后
                }
            }
            this.loading = false ;
        },
        scaleAdd() {
            if(this.scale == 300) return ;
            this.scale += 10;      
            this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
        },
        scaleReduce() {
            this.scale += -10;
            this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
        }
    },
}

 

 

   方法一真的是相當簡單了,,代碼都是差不多一樣,具體情況根據自己的業務需求改改就行了,但是這種方式處理問題也嚴重,就是pdf不清晰,縮放之后更嚴重。當然,為啥會很模糊,我當然是不知道的了。。。

 

  第二種方式更簡單惹:使用vue的依賴PDFJS

       第一步:安裝依賴

 

 

npm install  vue-pdf@4.0.8
npm install   pdfjs-dist@2.2.228
npm install   pdfjs@2.3.5

 

 

第二步:template頁面

export default {
    data(){
      return {
            pdfSrc:'',
            scale:100,
            numPages:0
        }
    },
    components:{
        pdf
    },
    created() {

          PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min.js');

      },

    mounted(){
        this.getPdfList();        
    },
      methods:{
        getPdfList(){
            //這里是我用來請求后台返回給我返回base64格式的文件發的ajax請求
            this.$toast.loading('加載中');
            this.$axios.post(url, params)
            .then(res => {              
                 if(res.data){
                     this.getPageNum(res);                
                 }else{
                     this.loading = false;
                     Dialog.alert({
                         message:res.message
                     }).then(()=>{
                          this.$router.go(-1);
                     });
                 }
                 this.$toast.hide();              
            }); 
        },
        async getPageNum(res){//這里注意一下哈,因為傳過來的base64位文件流,所以肯定不知道page是多少了,當然是要先獲取一下頁數啦
            var decodedBase64 = atob(res.data.DocumentData)
            var pdf = await PDFJS.getDocument({data: decodedBase64}) //返回一個pdf對象
            this.numPages = pdf.numPages ;
            this.pdfSrc = `data:application/pdf;base64,${res.data.DocumentData}`;
        },
        scaleAdd() {
            if(this.scale == 300) return ;
            this.scale += 10;
            for(var i in this.$refs.pdf){
                this.$refs.pdf[i].$el.style.width = parseInt(this.scale) + "%";
            }        
        },
        scaleReduce() {
            if (this.scale == 100) {
                return;
            }
            this.scale += -10;
            for(var i in this.$refs.pdf){
                this.$refs.pdf[i].$el.style.width = parseInt(this.scale) + "%";
            }    
        }
    },
}

  

    以上就是兩種處理的方法,闊以看的出來,第二種方式明顯代碼更少一點,並且第二種,完美的保留了文件的清晰度;所以以后遇到base64位PDF展示就用第二種吧!

 


免責聲明!

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



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