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"/>
相关推荐
qq_4198540531 分钟前
空间网格管理器
前端·javascript·html
李剑一1 小时前
ant-design-vue 1.x 版本换肤功能开发
前端·vue.js·ant design
李明卫杭州2 小时前
Vue2 与 Vue3 自定义指令详解:钩子变化、迁移指南与实战示例
前端·javascript·vue.js
七月丶2 小时前
线上出 Bug,你还在让用户"清一下缓存"?我用一个插件让每个请求自报版本
前端·javascript·面试
不简说2 小时前
JS 代码技巧 vol.3 — 10 个防抖节流深挖,小白到老炮的踩坑路
前端·javascript·面试
小智社群2 小时前
VR漫游视频完整版
前端·javascript·音视频
蝶恋舞者3 小时前
NMC-G2网络管理卡 资料官网下载流程
pdf
nicole bai4 小时前
vue 自定义模块内容
前端·javascript·vue.js
西西学代码4 小时前
Flutter---StreamBuilder案例
javascript·windows·flutter
qq_422152575 小时前
什么时候需要拆分或合并PDF?几种方案对比
pdf