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

  • 相关阅读:
    关于求 p_i != i and p_i != i+1 的方案数的思考过程
    poj 3041 Asteroids 二分图最小覆盖点
    poj 1325 Machine Schedule 最小顶点覆盖
    poj 1011 Sticks 减枝搜索
    poj 1469 COURSES 最大匹配
    zoj 1516 Uncle Tom's Inherited Land 最大独立边集合(最大匹配)
    Path Cover (路径覆盖)
    hdu 3530 SubSequence TwoPoint单调队列维护最值
    zoj 1654 Place the Rebots 最大独立集转换成二分图最大独立边(最大匹配)
    poj 1466 Girls and Boys 二分图最大独立子集
  • 原文地址:https://www.cnblogs.com/perferect/p/12662042.html
Copyright © 2011-2022 走看看