VUE 前端PDF分页预览、下载

一、安装PDF插件依赖

// pdf预览
npm install vue-pdf --save

// pdf下载
npm install downloadjs

二、完整示例

<template>
  <div id="container">
    <!-- 上一页、下一页-->
    <div class="right-btn">
      <!-- 输入页码-->
      <div class="pageNum">
        <input v-model.number="currentPage" type="number" class="inputNumber" @input="inputEvent()"/>&nbsp;/&nbsp;{{ pageCount}}
      </div>
      <div @click="changePdfPage('first')" class="turn">首页</div>
      <!-- 在按钮不符合条件时禁用-->
      <div @click="changePdfPage('pre')" class="turn-btn" :style="currentPage === 1 ? 'cursor: not-allowed;' : ''">上一页</div>
      <div @click="changePdfPage('next')" class="turn-btn" :style="currentPage === pageCount ? 'cursor: not-allowed;' : ''">下一页</div>
      <div @click="changePdfPage('last')"class="turn">尾页</div>
      <div @click="dowmloadPdf()"class="turn">下载</div>
    </div>
    <div class="pdfArea">
      <!--// 不要改动这里的方法和属性,下次用到复制就直接可以用 -->
      <pdf :src="src" ref="pdf"
        v-show="loadedRatio === 1" :page="currentPage"
        @num-pages="pageCount = $event"
        @progress="loadedRatio = $event"
        @page-loaded="currentPage = $event"
        @loaded="loadPdfHandler"
        @link-clicked="currentPage = $event"
        style="display: inline-block; width: 100%"
        id="pdfID">
      </pdf>
    </div>
    <!-- 加载未完成时,展示进度条组件并计算进度-->
    <div class="progress" v-if="loadedRatio != 1">
      <el-progress type="circle" :width="70" color="#53a7ff" :percentage="Math.floor(loadedRatio*100) ? Math.floor(loadedRatio*100) : 0"></el-progress><br/>
      <!-- 加载提示语-->
      <span>{{ remindShow}}</span>
    </div>
  </div>
</template>

<script>
  import pdf from "vue-pdf";
  import download from 'downloadjs'
  export default {
    name: 'vuepdf',
    components:{
      pdf,
    },
    data() {
      return{
        // ----- loading -----
        remindText: {
          loading:"加载文件中,文件较大请耐心等待...",
          refresh:"若卡住不动,可刷新页面重新加载...",
        },
        remindShow: "加载文件中,文件较大请耐心等待...",
        intervalID:"",
        // ----- vuepdf -----
        // src静态路径: /static/xxx.pdf// src服务器路径: 'http://.../xxx.pdf'
        src:"",
        blob:"",
        // 当前页数
        currentPage:0,
        // 总页数
        pageCount:0,
        // 加载进度
        loadedRatio:0,
      }
    },
    created(){
      // 页面加载,拿到路由中的url复制给data中的src
      const data = this.$route.query.data
      // 获取pdf地址
      this.$axios.getImage(data.resPathPDF).then(response=>{
        this.src=response;
        console.log(this.src);
      })
      console.log(this.src);
      // 获取pdf blob对象,responseType: 'blob'
      this.$axios.getDownload(data.resPathPDF).then(res=>{
        this.blob = new Blob([res],{type: 'application/pdf'});
        console.log(this.blob);
      })
    },
    mounted() {
      // // 更改 loading 文字
      this.intervalID = setInterval(() => {
          this.remindShow===this.remindText.refresh ? (this.remindShow=this.remindText.loading) : (this.remindShow=this.remindText.refresh);
        },
        4000
      )
    },
    methods:{
      // 下载
      dowmloadPdf() {
        download(this.blob, 'pdf测试',  'application/pdf')
      },
      // 页面回到顶部
      toTop() {
        document.getElementById("container").scrollTop=0;
      },
      // 输入页码时校验
      inputEvent() {
        if (this.currentPage>this.pageCount) {
          // 1. 大于max
          this.currentPage = this.pageCount;
        } else if (this.currentPage<1) {
          // 2. 小于min
          this.currentPage = 1;
        }
      },
      // 切换页数
      changePdfPage(val) {
        if(val==="pre"&&this.currentPage>1) {
          // 切换后页面回到顶部
          this.currentPage--;
          this.toTop();
        } else if(val==="next" && this.currentPage<this.pageCount) {
          this.currentPage++;
          this.toTop();
        } else if(val==="first") {
          this.currentPage=1;
          this.toTop();
        } else if(val==="last" && this.currentPage<this.pageCount) {
          this.currentPage = this.pageCount;
          this.toTop();
        }
      },
      // pdf加载时
      loadPdfHandler(e) {
        // 加载的时候先加载第一页
        this.currentPage=1;
      },
    },
    destroyed() {
      // 在页面销毁时记得清空
      clearInterval(this.intervalID);
    },
  };
</script>

<style scoped>
  #container {
    position: absolute!important;
    left:0;
    right:0;
    bottom:0;
    top:0;
    background: #f4f7fd;
    overflow: auto;
    font-family: PingFangSC;
    width:100%;
    display: flex;
    /* justify-content: center; */
    position: relative;
  }
  /* 右侧功能按钮区 */
  .right-btn {
    position: fixed;
    right:5%;
    bottom:15%;
    width: 120px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    z-index:99;
  }
  .pdfArea {
    width: 900px;
    margin:0 auto;
  }
  /* ------------------- 输入页码 ------------------- */
  .pageNum {
    color: #5a5e66;
    margin: 10px 0;
    font-size: 18px;
  }
  /*在谷歌下移除input[number]的上下箭头*/
  input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
    -webkit-appearance: none !important;
    margin:0;
  }
  /*在firefox下移除input[number]的上下箭头*/
  input[type="number"] {
    -moz-appearance: textfield;
  }
  .inputNumber{
    border-radius: 8px;
    border: 1px solid #999999;
    height: 35px;
    font-size: 18px;
    width: 60px;
    text-align: center;
  }
  .inputNumber:focus {
    border: 1px solid #00aeff;
    background-color:rgba(18,163,230,0.096);
    outline: none;
    transition:0.2s;
  }
  /* ------------------- 切换页码 ------------------- */
  .turn {
    background-color: #164fcc;
    opacity:0.9;
    color: #ffffff;
    height: 70px;
    width: 70px;
    border-radius:50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 5px 0;
  }
  .turn:hover {
    transition:0.3s;
    opacity:0.5;
    cursor: pointer;
  }
  .turn-btn {
    background-color: #164fcc;
    opacity:0.9;
    color: #ffffff;
    height: 70px;
    width: 70px;
    border-radius:50%;
    margin: 5px 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .turn-btn:hover {
    transition:0.3s;
    opacity:0.5;
    cursor: pointer;
  }
  /* ------------------- 进度条 ------------------- */
  .progress {
    position: absolute;
    right:50%;
    top:50%;
    text-align: center;
  }
  .progress>span {
    color: #199edb;
    font-size: 14px;
  }
</style>

三、参考页面

接收后端返回的pdf文件流 前端使用Vue-pdf实现预览(分页)

后端返回文件流PDF文件前端如何实现下载/在线打开_啃代码的毛毛虫的博客-CSDN博客

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值