vue中实现PDF文件流预览

news2024/11/17 21:49:02

代码示例 

<template>
	<div class="print">
		<div v-if="!viewShow" class="opt-box">
			<div style="height: 700px; overflow: auto;">
				<el-table :data="tableData" border>
					<el-table-column prop="no" label="序号" align="center">
					</el-table-column>
					<el-table-column prop="proveTypeName" label="文件名称" align="center">
					</el-table-column>
					<el-table-column prop="applyTime" label="申请时间" align="center">
					</el-table-column>
					<el-table-column label="操作" width="260" align="center">
						<template slot-scope="scope">
							<el-button type="text" icon="el-icon-view" @click="onChangeView(scope.row)"> 查看 </el-button>
						</template>
					</el-table-column>
				</el-table>
			</div>
		</div>

		<input ref="input" style="width: 100px" v-show="false" type="file" />
		<div class="print-btn" v-if="viewShow">
			<div class="txt-btn">今日已打印 {{dayCount}} 次 </div>
			<el-button circle type="primary" @click.stop="printAssignFile">打印文件</el-button>
			<el-button circle @click="clearBox">返回上级</el-button>
		</div>
		<div v-show='viewShow' id="viewBox">
		</div>
	</div>
</template>

<script>
	import { printFile, getPrintList } from "@/api/print";
	import { provePreview, queryPrintsSum } from "@/api/preview";

	const blobToJson = (data) => {
		return new Promise((resolve, reject) => {
			const reader = new FileReader();
			reader.readAsText(new Blob([data], {
				type: 'application/json'
			}), 'utf-8');
			reader.onload = () => {
				try {
					const json = JSON.parse(reader.result);
					resolve(json);
				} catch (e) {
					reject(e);
				}
			};
		});
	}
	export default {
		data() {
			return {
				tableData: [],
				dayCount: '',
				viewShow: false,
				dataFile: {},
				proveId: '',
			};
		},
		mounted(){
            //获取列表数据
			this.init();
			//获取打印次数
			this.getPrintsSum()
		},
		methods: {
			//获取列表数据
			init() {
				getPrintList(this.page).then((res) => {
					if (res && res.code === 200) {
						this.tableData = res.data.recordList;
					} else {
						this.$message.error(res.msg);
					}
				});
			},
			//获取打印次数
			getPrintsSum(){
				queryPrintsSum().then((res)=>{
					if(res && res.code == 200){
						this.dayCount = res.data
					} else {
						this.$message.error(res.msg);
					}
				})
			},
			// 清除pdf
			clearBox() {
				this.viewShow = false
				var e = document.querySelector("#viewBox");
				var child = e.lastElementChild;
				while (child) {
					e.removeChild(child);
					child = e.lastElementChild;
				}
			},
            // 展示PDF文件的预览
			showPdfPreview(data) {
				let _self = this
				const deal = () => {
					try {
						_self.clearBox()
						const viewBox = document.getElementById('viewBox');
						const pdf = document.createElement('iframe')
						pdf.id = 'iframe'
						pdf.setAttribute('frameborder', 0)
						const blob = new Blob([data], {
							type: 'application/pdf'
						});
						const pdfUrl = URL.createObjectURL(blob);
						pdf.src = pdfUrl + '#toolbar=0';
						pdf.style.width = '100%'
						pdf.style.height = '100%'
						viewBox.appendChild(pdf)
						_self.viewShow = true
					} catch (e) {
						_self.$message.error("未能正确加载文件");
						_self.clearBox()
					}
				}
				//1. 先将数据转换成json,看下是否是异常
				try {
					blobToJson(data).then((json) => {
						_self.$message.error(json.msg || "未能正确加载文件");
						_self.clearBox()
					}).catch((e) => {
						deal()
					})
				} catch (e) {
					_self.$message.error("未能正确加载文件");
					_self.clearBox()
				}
			},
			//预览
			onChangeView(row) {
				this.dataFile = row
				provePreview({
					proveId: row.proveId
				}).then((res) => {
					this.showPdfPreview(res)
					//获取打印次数
					this.getPrintsSum()
					if (res.code == 500) {
						this.$message.error("文件加载异常" || res.msg);
					}
				}).catch(err => {
					this.clearBox()
					this.$message.error("未能正确加载文件");
				});
			},
			//文件打印
			printAssignFile() {
				printFile(this.dataFile).then((res) => {
					if (res.code === 200) {
						//获取打印次数
						this.getPrintsSum()
						this.$message.success(res.msg);
					} else {
						this.$message.warning(res.msg);
					}
				});
			},
		},
	};
</script>
<style lang='less' scoped>
	.print {
		width: 100%;
		height: 100%;
		margin-top: 200px;
	}
	#viewBox {
		width: 70%;
		height: 720px;
		background-color: #ccc;
		margin: 0 auto;
	}
	.print-btn {
		position: fixed;
		top: 180px;
		right: 60px;
		display: flex;
		flex-direction: column;
		align-items: center;

		.txt-btn {
			margin-bottom: 30px;
			display: block;
			font-size: 22px;
			font-weight: 500;
			color: black;
			width: 180px;
			text-align: center;
		}
		.el-button {
			width: 160px;
			height: 160px;
			font-size: 22px;
		}
		.el-button+.el-button {
			margin-top: 30px;
			margin-left: 0 !important;
		}
	}
</style>

 预览接口preview.js

/**
 * 证明预览
 * @param {*} data pdf文件流
 * @returns
 */
export function provePreview(data) {
	return request({
		url: "/layout/api/view",
		method: "post",
		data: data,
		responseType: 'blob',	//一定要设置响应类型,否则页面会是空白pdf
		contentType: "application/json;charset=UTF-8"
	});
}

实现步骤说明

这段代码我定义了一个 blobToJson 的函数,主要是将 Blob 类型的数据转化为 JSON 对象

 🏳‍🌈 实现步骤如下:

  1. 创建一个 Promise 对象,用于异步处理数据转换
  2. 再创建一个 FileReader 对象,用于读取 Blob 类型的数据
  3. 通过 FileReader 对象的 readAsText() 方法,将 Blob 数据以文本形式读取出来,并指定编码格式为 UTF-8
  4. 在 FileReader 对象的 onload 方法中,通过 try...catch 将读取到的文本数据解析成 JSON 对象,并将解析后的结果作为 Promise 的 resolve 返回值。若是解析失败,则将错误信息作为 reject 返回值。
  5. 若是出现了异常,可使用 Promise 的 catch 方法进行捕获和处理。

clearBox() 方法 

clearBox() 方法:在关闭文件预览时,清空预览区域的内容,以便下次预览文件时重新加载新的内容。

 🏳‍🌈 实现步骤如下:

  1. 将 viewShow 设置为 false,即隐藏文件预览区域。
  2. 通过 document.querySelector("#viewBox") 获取到文件预览区域的 DOM 元素。
  3. 使用 while 循环,在文件预览区域内移除所有子元素,直到没有子元素为止。

  showPdfPreview()方法

        showPdfPreview()方法:用于展示PDF文件的预览,并对异常情况进行处理

        在展示预览之前,先将数据转换成json格式,如果转换过程中出现异常,则显示错误消息并清空文件预览区域;如果转换成功,则进行具体的展示逻辑。

 🏳‍🌈 实现步骤如下:

  1. 创建一个deal函数,用于处理展示PDF预览的具体逻辑。
  2. 在deal函数中,首先调用clearBox方法清空文件预览区域的内容。
  3. 将传入的code赋值给组件的code属性,用于在展示预览时进行标识。
  4. 调用queryCount方法查询打印次数。
  5. 创建一个iframe元素,并设置id为'iframe',设置frameborder为0。
  6. 使用Blob对象将传入的data转换为Blob类型,并设置type为'application/pdf'
  7. 通过URL.createObjectURL方法生成PDF文件的URL。
  8. 将生成的PDF URL赋值给iframe的src属性,添加到文件预览区域,并设置宽度和高度为100%。
  9. 将iframe添加到文件预览区域中。
  10. 将组件的viewShow属性设置为true,显示文件预览区域。
  11. 使用try-catch-finally语句对异常进行处理。
  12. 在try块中,首先将data转换为json格式,判断是否存在异常。若有异常,显示错误消息并调用clearBox方法清空文件预览区域。
  13. 在catch块中,捕获到异常时,显示错误消息并调用clearBox方法清空文件预览区域。
  14. 在finally块中,关闭加载状态。

XX证明列表展示 

XX证明文件预览效果图 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1314107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何拍摄超级大像素图片,超级大像素有哪些应用

引言&#xff1a; 在数字摄影领域&#xff0c;超级大像素照片是指通过高像素的相机或拼接多张照片合成的照片。这样的照片具有更高的分辨率&#xff0c;细节更加清晰&#xff0c;绘画质感更强。那么如何拍摄超级大像素照片&#xff0c;超级大像素可以用在哪些领域呢。 一&…

C++使用回调函数的两种方式

一.函数指针 #include <iostream>typedef void (*callback)(int ,int); class MyTest { public:void setCallback(callback cb){m_callback = cb;}void add(int a, int b){m_callback(a, b);}private:callback m_callback; };void onCallback(int a, int b) {std::cout …

设计模式-策略(Strategy)模式

又被称为政策&#xff08;方针&#xff09;模式策略模式(Strategy Design Pattern)&#xff1a;封装可以互换的行为&#xff0c;并使用委托来决定要使用哪一个策略模式是一种行为设计模式&#xff0c;它能让你定义一系列算法&#xff0c;并将每种算法分别放入独立的类中&#x…

【导航栏内容的设置 Objective-C语言】

一、那接下来呢,我们就来做一做,关于导航控制器, 1.设置它顶部的导航栏儿内容的东西, 1)我们刚刚讲过的这个,通过代码去跳转、返回、 2)通过storyboard去跳转、返回、 但是,这两种情况,大家是不是已经注意到,导航栏里面,没有任何内容, 然后呢,返回,这是红色,…

centos下:mysql一些指令+mysql首次修改密码+mysql忘记密码修改

操作 查看mysql运行状态 systemctl status mysqld 停止mysql systemctl stop mysqld 启动mysql systemctl start mysqld 重启mysql systemctl restart mysqld 开启mysql开机自启动 systemctl enable mysqld 关闭mysql开机自启动 systemctl disable mysqld 查看具体的报错日…

动态内存管理,malloc和calloc以及realloc函数用法

目录 一.malloc函数的介绍 malloc的用法 举个例子 注意点 浅谈数据结构里的动态分配空间 二.calloc函数的介绍 三.realloc函数的介绍 四.柔性数组的介绍 为什么有些时候动态内存函数头文件是malloc.h,有些时候却是stdlib.h 一.malloc函数的介绍 malloc其实就是动态开辟…

innerHTML、innerText、textContent有什么区别

innerHTML、innerText、textContent有什么区别 在 HTML 中&#xff0c;innerHTML、innerText、 和textContent是 DOM&#xff08;文档对象模型&#xff09;的属性。它们允许我们读取和更新 HTML 元素的内容。 但它们在包含的内容以及处理 HTML 标签的方式有不同的行为。 读完…

安恒明御安全网关 aaa_local_web_preview文件上传漏洞复现

0x01 产品简介 明御安全网关秉持安全可视、简单有效的理念,以资产为视角,构建全流程防御的下一代安全防护体系,并融合传统防火墙、入侵检测、入侵防御系统、防病毒网关、上网行为管控、VPN网关、威胁情报等安全模块于一体的智慧化安全网关。 0x02 漏洞概述 明御安全网关在…

jmeter,断言:响应断言、Json断言

一、响应断言 接口A请求正常返回值如下&#xff1a; {"status": 10013, "message": "user sign timeout"} 在该接口下创建【响应断言】元件&#xff0c;配置如下&#xff1a; 若断言成功&#xff0c;则查看结果树的接口显示绿色&#xff0c;若…

Spring Boot启动慢如何分析

如果发现项目启动慢&#xff0c;你知道怎么分析慢的原因吗&#xff1f; 分析方法 自定义监听器 SpringApplicationRunListener是Spring Boot中的一个接口&#xff0c;它的作用是在SpringApplication运行的各个阶段提供回调接口&#xff0c;以便我们可以在这些阶段执行自定义…

PPT插件-好用的插件-放映笔、绘图板-大珩助手

放映笔 幻灯片放映时&#xff0c;工具在幻灯片的左下方&#xff0c;本工具在幻灯片的右侧&#xff0c;可以移动&#xff0c;可以方便在右侧讲课时候使用 绘图板 可在绘图板上写签名、绘制图画、写字等等&#xff0c;点画笔切换橡皮擦&#xff0c;点插入绘图&#xff0c;将背景…

jenkins学习19 - pipline 构建项目生成 allure报告并发送邮箱

前言 个人其实一直的不太喜欢用邮箱发送报告&#xff0c;测试报告用邮件通知这都是五六年前的事情了&#xff0c;但有部分小伙伴依然执着于发邮件报告通知。 这里整理了下发邮箱通知的教程。 配置你的邮箱 配置邮箱这一步最繁琐&#xff0c;由于每个人使用的邮箱不一样&…

欧拉市场份额达36.8%,服务器操作系统市场份额第一

[中国&#xff0c;北京&#xff0c;2023年12月15日] 以“崛起数字时代&#xff0c;引领数智未来”为主题的操作系统大会2023今日在北京国家会议中心举办&#xff0c;大会由开放原子开源基金会、中国电子技术标准化研究院、国家工业信息安全发展研究中心、中国软件行业协会共同主…

【Java】SpringBoot中实现Redis Stream队列

SpringBoot实现Redis Stream队列 前言 简单实现一下在SpringBoot中操作Redis Stream队列的方式&#xff0c;监听队列中的消息进行消费。 jdk&#xff1a;1.8 springboot-version&#xff1a;2.6.3 redis&#xff1a;5.0.1&#xff08;5版本以上才有Stream队列&#xff09;…

机器学习算法---回归

1. 线性回归&#xff08;Linear Regression&#xff09; 原理&#xff1a; 通过拟合一个线性方程来预测连续响应变量。线性回归假设特征和响应变量之间存在线性关系&#xff0c;并通过最小化误差的平方和来优化模型。优点&#xff1a; 简单、直观&#xff0c;易于理解和实现。…

力扣题:数字与字符串间转换-12.16

力扣题-12.16 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;640. 求解方程 解题思想&#xff1a;首先将方程按照“”进行划分&#xff0c;然后分别记录x的因数和常数项&#xff0c;最后进行返回的判断即可 class Solution(object):def solveEqu…

娱乐新拐点:TikTok如何改变我们的日常生活?

在数字时代的浪潮中&#xff0c;社交媒体平台不断涌现&#xff0c;其中TikTok以其独特的短视频内容在全球范围内掀起了一场娱乐革命。本文将深入探讨TikTok如何改变我们的日常生活&#xff0c;从社交互动、文化传播到个人创意表达&#xff0c;逐步改写了娱乐的新篇章。 短视频潮…

【Idea】SpringBoot项目中,jar包引用冲突异常的排查 / SM2算法中使用bcprov-jdk15to18的报错冲突问题

问题描述以及解决方法&#xff1a; 项目中使用了bcprov-jdk15to18 pom依赖&#xff0c;但是发现代码中引入的版本不正确。 追溯代码发现版本引入的是bcprov-jdk15on&#xff0c;而不是bcprov-jdk15to18&#xff0c;但是我找了半天pom依赖也没有发现有引入bcprov-jdk15on依赖。…

【MySQL】:表的增加和查寻

表的增查 一.Create(增)1.基本插入2.插入是否更新3.替换 二.Retrieve(查)1.select列1.全列查询2.指定列查询3.查询字段为表达式4.结果去重 2.where条件查询1.运算符2.运算符使用 3.结果排序4.筛选分页结果 一.Create(增) 1.基本插入 对于表的增加&#xff0c;前面已经用过很多…

什么是供应链安全及其工作原理?

6000公里长的丝绸之路将丝绸、谷物和其他货物从中国运送到帕尔米拉。尽管蒙古治下的和平保护丝绸之路免受海盗、强盗和内部盗窃的侵害&#xff0c;但商人仍然装备精良&#xff0c;并依赖于大型商队旅行和战略性放置的小型堡垒所提供的安全。 为什么供应链安全很重要&#xff1…