当前位置:首页 » 《随便一记》 » 正文

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

18 人参与  2023年05月03日 11:45  分类 : 《随便一记》  评论

点击全文阅读


vue系列文章目录

需求:后端返回文件流前端将文件流转为成blob地址预览pdf文件


提示:以下是本篇文章正文内容,下面案例可供参考

一、安装PDF插件依赖

npm install vue-pdf --save

二、封装vuePdf组件为预览页面,通过Management.vue路由传参形式跳转到预览页面

1.Management.vue

代码如下(示例):

在这里插入图片描述

封装的请求pdfDocument在这里插入图片描述
  一定要加上      {        responseType: "blob",      }

后台返回的pdf文件流 也就是result.data
在这里插入图片描述
附代码:

 // 预览    async scanSubmit(row) {      // 这个代码我不多做解释,接口请求而已      const result = await pdfDocument(this.fileId);      // 直接使用createObjectURL可能会出现问题      // 所以我建议使用下面这种方式将文件流转化为本地blod地址      var binaryData = [];      binaryData.push(result.data);      console.log(binaryData);      // 记得一定要设置application的类型      let url = window.URL.createObjectURL(        new Blob(binaryData, {          type: "application/pdf;charset=utf-8",        })      );      if (url != null && url != undefined && url) {        // vue路由跳转并以问号形式携带vue-pdf预览时所需要的pdf地址        const { href } = this.$router.resolve({          path: "/vuePdf",          query: {            //要传的参数            url: url,          },        });        // 新页面打开        window.open(href, "_blank");        this.openTheScanningdialog = false;      }    },

2.vuedf.vue

HTML部分,无需修改,复制可直接使用

<template>  <div id="container">    <!-- 上一页、下一页 -->    <div class="right-btn">      <!-- 输入页码 -->      <div class="pageNum">        <input          v-model.number="currentPage"          type="number"          class="inputNumber"          @input="inputEvent()"        />        / {{ 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>    <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>

JS部分,无需修改,复制可直接使用

<script>import pdf from "vue-pdf";export default {  components: {    pdf,  },  data() {    return {      // ----- loading -----      remindText: {        loading: "加载文件中,文件较大请耐心等待...",        refresh: "若卡住不动,可刷新页面重新加载...",      },      remindShow: "加载文件中,文件较大请耐心等待...",      intervalID: "",      // ----- vuepdf -----      // src静态路径: /static/xxx.pdf      // src服务器路径: 'http://.../xxx.pdf'      src: "",      // 当前页数      currentPage: 0,      // 总页数      pageCount: 0,      // 加载进度      loadedRatio: 0,    };  },  created() {    // 页面加载,拿到路由中的url复制给data中的src    this.src = this.$route.query.url;    console.log(this.src);  },  mounted() {    // // 更改 loading 文字    this.intervalID = setInterval(() => {      this.remindShow === this.remindText.refresh        ? (this.remindShow = this.remindText.loading)        : (this.remindShow = this.remindText.refresh);    }, 4000);  },  methods: {    // 页面回到顶部    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() {    // 在页面销毁时记得清空 setInterval    clearInterval(this.intervalID);  },};</script>

CSS部分,可根据自己的需求自行修改

<style scoped>#container {  position: absolute !important;  left: 0;  right: 0;  bottom: 0;  top: 0;  background: #f4f7fd;  overflow: auto;  font-family: PingFang SC;  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 {  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-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,.turn: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>

效果图

在这里插入图片描述

**

实现下载/在线打开

**

①安装downloadjs

npm install downloadjs

②在需要的地方引入

import download from 'downloadjs'

③在下载的方法里调用download就可以实现下载了

在这里插入图片描述
文件流数据 保存的名字 要下载的文件类型


点击全文阅读


本文链接:http://zhangshiyu.com/post/60398.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1