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"/>
相关推荐
用户57573033462422 分钟前
🔥 前端必考!AJAX 数据请求全解析,async true/false 区别一次搞懂
javascript
麦麦大数据43 分钟前
F071_vue+flask基于YOLOv8的实时目标检测与追踪系统
vue.js·yolo·目标检测·flask·vue·视频检测
烤麻辣烫44 分钟前
正则表达式快速掌握
前端·javascript·学习·正则表达式·html
心之语歌2 小时前
flutter 父子组件互相调用方法,值更新
前端·javascript·flutter
带你看月亮2 小时前
Vue3解析学习 - handlers 模块
vue.js·学习
肖。35487870942 小时前
html中onclick误区,后续变量会更改怎么办?
android·java·javascript·css·html
暴力袋鼠哥2 小时前
SpringBoot+Vue实战:多模态疾病初筛与护理建议系统(含泳道图+时序图+完整后端代码)
vue.js·spring boot·后端
Lee川2 小时前
从字符串操作到数组映射:一次JavaScript数据处理的深度探索
javascript
随逸1773 小时前
《React 性能优化:useMemo 与 useCallback 实战》
javascript·react.js
HelloReader3 小时前
Tauri 用“系统 WebView + 原生能力”构建更小更快的跨平台应用
前端·javascript·后端