vue使用pdf.js实现在线查看pdf文件

需求:有一个列表页,用户点击查看,弹层展示后台接口返回的pdf内容(不是文件、地址之类的,乱码的pdf铭文(二进制文件流))

1、pdf.js安装

复制代码
npm install --save vue-pdf

2、正文代码

复制代码
<template>
    <div>
		<el-table :data="dataList">
	        <el-table-column prop="fieldName" width="120" label="操作">
	          <template slot-scope="scope">
	            <span @click="look(scope.row)">查看</span>
	          </template>
	        </el-table-column>
       </el-table>
	   <el-dialog title="预览" :visible.sync="dialogVisible" :before-close="closePdf">
      	 <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i" />
       </el-dialog>
	</div>
<template>
<script>
	import pdf from 'vue-pdf'
	export default {
	  components: {
	    pdf
	  },
	  data() {
   		 return {
  		 	  dialogVisible: false,
		      numPages: 1,
		      pdfSrc:"",
		      close:false,
   		 }
   	  },
   	  methods: {
		// 查看预览
	    look(row) {
	      const that = this;
	      that.pdfSrc = "";
		  // 接口文件地址(接口入参拼出来的路径)
	      const url = `${Host}xxxxxx/xxxx/xxx?fileId=${row.fileId}&amp;fileName=${row.fileName}.pdf`;
		  // 如果调用接口(接口的responseType一定要是blob,默认json,不然解析出来的pdf是空白的)后拿的返回的值(乱码的pdf铭文(二进制文件流))则需要转一下
		  // const url = window.URL.createObjectURL(new Blob([res]), { // res为接口返回值
			// type: "application/msword"
		  // });
	      that.pdfSrc = pdf.createLoadingTask(url)
	      that.pdfSrc.promise.then(pdf => {
	        that.dialogVisible = true;
	        that.numPages = pdf.numPages
	        //保证pdf加载成功,否则不能关闭弹层
	        setTimeout(() => {
	          that.close = true;
	        }, 2000);
	      })
	      .catch(error => {
	        that.$message.error("无效的PDF文件!");
	      })
	    },
	    //此方法解决第一次查看pdf文字没有加载完成影响后续查看
	    closePdf(done){
	      if(this.close) {
	        this.numPages = 1;//必须重置,多次查看会出现头部内容缺失
	        this.close = false;
	        done();
	      } else {
	        this.$message.warning("PDF文件加载中");
	      }
	    }
	  }
	}
</script>

遇到的问题:

1、多次查看后头部内容不显示。 设置numPages = 1;

2、上一条pdf查看没有加载完成,下一条pdf查看pdfSrc清空了还是无法正常加载。 延迟关闭弹层(这个方法有点暴力,希望能找到好的解决方法);

3、头部会有点多余内容溢出,内容没啥,就是感觉有类似border的东西。 头部其他内容设置样式盖住(具体css略)。

在后续项目中又实现了该功能,没有遇到以上问题,盲猜是因为pdf dialog标签上加了v-if,光设置visible.sync只会控制元素的显示隐藏,不会重新渲染。

总结:只要是dialog最好加上v-if,会避免很多问题。

拓展:

如果后端返回的是html格式,前端调用的接口responseType就不要用blob了,直接将返回结果放在v-html里面。例:

复制代码
<div v-html="responseData"/>
相关推荐
@菜菜_达2 分钟前
jquery.inputmask插件介绍
前端·javascript·jquery
摸鱼小李上线了17 分钟前
vue项目页面添加水印实现方法
前端·javascript·vue.js
砍材农夫23 分钟前
物联网 基于netty构建mqtt协议规范(主题通配符订阅)
java·前端·javascript·物联网·netty
爱滑雪的码农39 分钟前
React Native 完整开发全流程(从零到上线)
javascript·react native·react.js
shuaiqinke44 分钟前
【分享】Master PDF Editor v5.9.98便携版 多功能PDF编辑工具
智能手机·pdf
HwJack2044 分钟前
HarmonyOS APP开发中ArkTS/JS 类型错误全景拆解
javascript·华为·harmonyos
子琦啊1 小时前
构造函数、this指向和原型链机制
javascript·算法·贴图
Maimai108081 小时前
React 多步骤表单工程化落地:从 Zod Schema、React Hook Form 到 Zustand 持久化
前端·javascript·react.js·前端框架·状态模式
Maimai108081 小时前
React Query + Zustand 正确结合方式:不要把接口数据复制进 Store
前端·javascript·react.js·前端框架·web3·状态模式
i220818 Faiz Ul1 小时前
智慧养老平台|基于SprinBoot+vue的智慧养老平台系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·智慧养老平台