zoukankan      html  css  js  c++  java
  • Vue-base64移动端PDF展示

      作为一个后端开发,写前端的一些功能也是头大,好在网友强大,网上资源比较多;做一个移动端PDF预览的功能,本来可以通过window.open(),打开的,但是没办法,做后台的小伙伴,传给前端的数据是base64位,我只能按照后台给的数据进行处理了;

      方法一:

      最原始的方式:通过canvas将字节流转成图片,方法简单,别人的代码直接抄过来就能用;但是缺点也同样严重,图片展示清晰度很低

          代码如下

       1.安装依赖    

    npm install   pdfjs-dist
    

         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
    npm install   pdfjs-dist  //之前漏写了,一定要添加这个依赖,要不然会报错
    

    第二步: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展示就用第二种吧!

  • 相关阅读:
    自定义注解标签验证
    redis-服务器配置-主从
    POJ-2195 Going Home(最小费用最大流模板)
    POJ-1087 A Plug for UNIX
    HDU-3625 Examining the Rooms (第一类斯特林数)
    网络流入门
    CodeForces-1082G Increasing Frequency
    python学习之模块-模块(三)
    python学习之模块-模块(二)
    python学习之模块-模块(一)
  • 原文地址:https://www.cnblogs.com/perferect/p/12662042.html
Copyright © 2011-2022 走看看