【VUE】Vue3 实现文件预览 Word Excel pdf 图片 视频等格式 大全!!!!
先上效果图
插件安装
先说 word 文件是docx-preview插件
excel文件是用 xlsx 插件
介绍后端返回的数据
因为在拦截器处 做了对数据的处理 最后你调接口拿到的数据是 一个对象 里面包含:
url : blob对象转换的用于访问Blob
数据的临时链接。这个链接可以被用于在网页中展示二进制数据,比如显示图像或者播放音视频文件
blobs: 返回的Blob
对象,代表了从网络请求中获取到的二进制数据
这上下俩部分很重要!!!!!!!!
如果返回的普通格式的话就大家直接转化
const blob = new Blob([res], { type: 'application/pdf' }) //你需要的类型 转化为blob对象
const url = window.URL.createObjectURL(blob) //将对象转化为链接
也就是你后面掉接口返回的数据
给大家打印一下 我当时在网上搜索这类资料的时候 就是在这一部分弄糊涂了 对数据格式不了解
然后就到正式书写了
下载引入插件 (我这是v3 引入 vue2版本 csdn官网上搜vue预览文件 一大堆 大家自己搜一下)
//word文档注释 import { renderAsync } from 'docx-preview'; //excel注释 import * as XLSX from "xlsx";
Word预览
不清楚result 返回内容的往上滑 这里传递的是blob对象!!
<!-- 若是word文档格式数据号展示 我这里是加自己定义的类型判断了 fileType 大家可删除掉 --> <div ref="refWord" id="fileShow" v-else-if="fileType == 'docx'" style="width: 100%;height: 100%;"></div> //js代码处 const previewContainer = document.getElementById('fileShow'); renderAsync(result.blob, previewContainer) //渲染
Excel预览
不清楚result 返回内容的往上滑 这里传递的是blob对象!! 中间内容是在拿到数据渲染的时候插件数据处理 最后将处理的数据当参数传递到处理样式的方法中
<!-- 若是excel格式数据展示 --> <div id="fileShowTwo" style="width: 100%;height: 100%;" v-else-if="fileType == 'xlsx'"> <div class="tab"> <el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable"> <el-radio-button v-for="(item, index) in excel.sheetNames" :key="index" :label="item"></el-radio-button> </el-radio-group> </div> <div style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;"> <div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div> </div> </div> <div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;"> <video :src="fileAddress" controls style="width: 100%;height: 100%;"></video> </div> //js代码处 //表格预览所需数据 定义 const data = reactive({ excel: { // 数据 workbook: {}, // 表名称集合 sheetNames: [], // 激活项 sheetNameActive: "", // 当前激活表格 SheetActiveTable: "" } }) const { excel } = toRefs(data); // 视频预览所需数据 const emptyTips = ref('暂无内容'); //格式为excel时 方法中书写的内容 const reader = new FileReader(); //创建了一个FileReader对象,这个对象用于异步读取文件内容 //通过readAsArrayBuffer将blob转换为ArrayBuffer对象 reader.readAsArrayBuffer(result.blob) // 这里的res.data是blob文件流 reader.onload = (event) => { // 读取ArrayBuffer数据变成Uint8Array var data = new Uint8Array(event.target.result); // 这里的data里面的类型和后面的type类型要对应 var workbook = XLSX.read(data, { type: "array" }); const sheetNames = workbook.SheetNames // 工作表名称集合 excel.value.workbook = workbook excel.value.sheetNames = sheetNames excel.value.sheetNameActive = sheetNames[0] //方法 getSheetNameTable(sheetNames[0]) }; //定义的方法 const getSheetNameTable = (sheetName) => { try { // 获取当前工作表的数据 const worksheet = excel.value.workbook.Sheets[sheetName] // 转换为数据 1.json数据有些问题,2.如果是html那么样式需修改 let htmlData = XLSX.utils.sheet_to_html(worksheet, { header: '', footer: '' }) htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '<table class="default-table" border="1px solid #ccc" cellpadding="0" cellspacing="0"') // 第一行进行改颜色 htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '<tr style="background:#b4c9e8"') excel.value.SheetActiveTable = htmlData } catch (e) { // 如果工作表没有数据则到这里来处理 excel.value.SheetActiveTable = '<h4 style="text-align: center">' + emptyTips.value + '</h4>' } }
pdf 预览
这个需要用到iframe标签 他的blob对象的type需要是"type": "application/pdf" 大家可以看一下自己的blob对象 如果是后端返回的直接是blob格式 但是type不对 那等下我下面代码有转化 如果返回的普通数据 大家自己根据上面的格式自己转化blob对象的时候自己设置一下type
<!-- 若是pdf数据展示 --> <iframe :src="fileAddress" type="application/pdf" v-else-if="fileType == 'pdf'" id="pdfShow" width="100%" height="100%"></iframe> //js代码处 //格式为pdf时 const reader = new FileReader(); reader.readAsArrayBuffer(result.blob); reader.onload = function () { fileAddress.value = URL.createObjectURL(new Blob([reader.result], { "type": "application/pdf" })) }
最后是jpg png ,mp4格式预览
//这里就用到blob对象转化的链接了 注意区分!! if (type == 'jpg' || type == 'png' || type == 'mp4') { fileAddress.value = result.url } //图片类型展示 <img style="width: 150px;height: 150px;" :src="fileAddress" alt="" v-if="fileType == 'jpg' || fileType == 'png'"> //视频类型展示 <div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;"> <video :src="fileAddress" controls style="width: 100%;height: 100%;"></video> </div>
下载文件 !!
<el-button @click="DownloadFn()"> 下载</el-button> // 文件下载 const DownloadFn = () => { let a = document.createElement('a') // 下载链接 a.href = blobUploadValue.value //这个就是那个blob链接!! // 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf' //这里是你上传的文件名 加上他的类型 jpg,png,docx..... a.download = fileNameValue.value + '.' + fileType.value document.body.appendChild(a) // 点击a标签,进行下载 a.click() // 移除元素 document.body.removeChild(a) }
最后是完整代码
<el-dialog v-model="dialogTabsVisible" title="附件展示" class="file-show-box" @close="closeDialog()"> <div class="file-body"> <!-- 左侧附件列表 --> <div class="file-left" > <div class="list" :class="{'list-active' : listAct == index}" v-for="(item, index) in fileList" :key="index" @click="handleClick(item,index)">{{ item.name }}</div> </div> <div class="file-right"> <div class="downFile" v-if="fileType != 'pdf'"> <el-button @click="DownloadFn()"> 下载</el-button> </div> <!-- 若是图片数据展示 --> <img style="width: 150px;height: 150px;" :src="fileAddress" alt="" v-if="fileType == 'jpg' || fileType == 'png'"> <!-- 若是txt格式数据展示 --> <iframe :src="fileAddress" frameborder="0" v-else-if="fileType == 'txt'" style="width: 90%; height: 100%;"></iframe> <!-- 若是pdf数据展示 --> <iframe :src="fileAddress" type="application/pdf" v-else-if="fileType == 'pdf'" id="pdfShow" width="100%" height="100%"></iframe> <!-- 若是word文档格式数据号展示 --> <div ref="refWord" id="fileShow" v-else-if="fileType == 'docx'" style="width: 100%;height: 100%;"></div> <!-- 若是excel格式数据展示 --> <div id="fileShowTwo" style="width: 100%;height: 100%;" v-else-if="fileType == 'xlsx'"> <div class="tab"> <el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable"> <el-radio-button v-for="(item, index) in excel.sheetNames" :key="index" :label="item"></el-radio-button> </el-radio-group> </div> <div style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;"> <div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div> </div> </div> <div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;"> <video :src="fileAddress" controls style="width: 100%;height: 100%;"></video> </div> <div v-else> 该文件暂不支持预览,请下载查看 </div> </div> </div> </el-dialog> //js部分 //表格预览所需数据 const data = reactive({ excel: { // 数据 workbook: {}, // 表名称集合 sheetNames: [], // 激活项 sheetNameActive: "", // 当前激活表格 SheetActiveTable: "" } }) const { excel } = toRefs(data); // 视频预览所需数据 const emptyTips = ref('暂无内容'); // 下载文件 // 文件地址 const fileAddress = ref('') // 下载流数据 const blobUploadValue = ref('') //我这里的参数type是其他地方传递过来的 注意甄别 const downloadFn = (id, type) => { let params = { fileId: id } download(params).then(result => { console.log(result.url, 'resolve'); console.log(result.blob, 'blob'); blobUploadValue.value = result.url if (type == 'jpg' || type == 'png' || type == 'mp4') { //格式为图片 视频时 fileAddress.value = result.url } else if (type == 'docx') { //格式为word时 const previewContainer = document.getElementById('fileShow'); renderAsync(result.blob, previewContainer) //渲染 } else if (type == 'xlsx') { //格式为excel时 const reader = new FileReader(); //通过readAsArrayBuffer将blob转换为ArrayBuffer对象 reader.readAsArrayBuffer(result.blob) // 这里的res.data是blob文件流 reader.onload = (event) => { // 读取ArrayBuffer数据变成Uint8Array var data = new Uint8Array(event.target.result); // 这里的data里面的类型和后面的type类型要对应 var workbook = XLSX.read(data, { type: "array" }); const sheetNames = workbook.SheetNames // 工作表名称集合 excel.value.workbook = workbook excel.value.sheetNames = sheetNames excel.value.sheetNameActive = sheetNames[0] getSheetNameTable(sheetNames[0]) }; } else if (type == 'pdf') { //格式为pdf时 const reader = new FileReader(); reader.readAsArrayBuffer(result.blob); reader.onload = function () { fileAddress.value = URL.createObjectURL(new Blob([reader.result], { "type": "application/pdf" })) } } }) } // 文件下载 const DownloadFn = () => { let a = document.createElement('a') // 下载链接 a.href = blobUploadValue.value // 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf' a.download = fileNameValue.value + '.' + fileType.value document.body.appendChild(a) // 点击a标签,进行下载 a.click() // 移除元素 document.body.removeChild(a) } const getSheetNameTable = (sheetName) => { try { // 获取当前工作表的数据 const worksheet = excel.value.workbook.Sheets[sheetName] // 转换为数据 1.json数据有些问题,2.如果是html那么样式需修改 let htmlData = XLSX.utils.sheet_to_html(worksheet, { header: '', footer: '' }) htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '<table class="default-table" border="1px solid #ccc" cellpadding="0" cellspacing="0"') // 第一行进行改颜色 htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '<tr style="background:#b4c9e8"') excel.value.SheetActiveTable = htmlData } catch (e) { // 如果工作表没有数据则到这里来处理 excel.value.SheetActiveTable = '<h4 style="text-align: center">' + emptyTips.value + '</h4>' } }
这里是后端返回回来一个附件名称列表 我渲染到左侧的附件列表中 然后通过选中不同的附件 右侧展示不同的文件预览 他的文件类型我也是从这里得到的 然后我通过点击不同的附件列表 执行上面的预览方法 获取到不同的blob数据 然后进行展示
我只能给大家说一下我的逻辑 毕竟每个人代码不一样 不一定能直接复制 还是希望能帮到大家
最后贴上效果图
原文链接https://blog.csdn.net/m0_65607651/article/details/133887921如有侵权可联系删除
猜你喜欢
- 【Vue】Vue中使用Vuex管理全局状态详解和示例
- vue.js是一种流行的前端框架,它提供了很多方便的功能,但当应用变得越来越复杂时,我们很快就会发现向子组件传递大量数据变得非常困难。这就是为什么vuex在vue中变得如此重要的原因。vuex是一个全局状态管理器,使得数据和状态的共享变得更容易。在本文中,我们将深入了解vuex的工作原理并演示如何将其集成到您的vue应用程序中。什么是VuexVuex是一个用于Vue.js应用程序的状态管理模式和库,常用于解决跨层级、多组件、多页面共享状态问题。它将应用程序的状态集中存储到一个单一的store中,
- 【Vue】uniapp(vue3)+node.js+websocket(实现实时通信效果)
- 文章目录概要整体架构流程技术名词解释技术细节小结概要uniapp基于vue3,小程序的聊天功能项目是基于node.js服务器搭建的简易双向通信网页,实现了实时更新在线人数以及用户间即时通讯的功能。整体架构流程后台接口代码1、首先我们可以通过Express 应用程序生成器快速搭建一个后台框架。(这快可以参考官网)2、服务端/** * WebSocket模块 */ const { WebSocketServer }&nbs
- 【Vue】yarn 运行vue3项目开发模式
- 要在YARN中以Vue.js 3的开发模式运行项目,可以按照以下步骤进行操作:确保已经安装了Node.js和YARN。如果没有安装,请先安装这两个工具。打开命令提示符或终端并导航到Vue.js 3项目所在的文件夹。使用以下命令来初始化新的YARN项目(如果还未创建):yarn init -y接下来,需要安装Vue CLI脚手架工具。运行以下命令来全局安装Vue CLI:npm install -g @vue/cli然后,通过以下命令将Vue CL
- 【Vue】vue创建应用并运行
- 简介Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。Vue 是一个框架,也是一个生态。其功能覆盖了大部分前端开发常见的需求。但 Web 世界是十分多样化的,不同的开发者在 Web 上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue 的设计非常注重灵活性和
- 【Vue】vue是什么模式的前端框架
- vue 中的 mvvm 架构将应用程序分为 model、view 和 viewmodel:model:包含数据和业务逻辑,独立于视图。view:显示 model 中的数据,使用模板语法进行数据绑定。viewmodel:model 和 view 之间的桥梁,包含与 view 交互的数据和方法,并更新 view。mvvm 在 vue 中的优势包括响应式数据绑定、代码可重用性、提高生产力、易于调试。Vue:MVVM 架构什么是 MVVM?MVVM(Model-View-ViewModel)是一种软件设
- 【Vue】Antd Pro Vue的使用(五)—— 多文件上传回显问题
- 需求: 多文件上传 ,上传的时候绑定fileList回显问题: 上传成功了,也拿到了后台返回的数据,但是onchang监听的时候,file的状态一直是uploading原因:onchange 只触发了一次解决: 使用单文件上传时@change事件会至少触发两次,一次file.status=uploading,最后一次要么是done或者error,handleUpload1(info) { if (info
- 【Vue】vue中sync作用
- vue 中的 sync 修饰符用于在父组件和子组件之间实现双向数据绑定。它通过生成一个 v-model 指令,将子组件的 prop 与父组件的 prop 绑定在一起,从而实现数据同步。用法如下:1. 在子组件中使用 v-bind:prop.sync="parentprop",其中 prop 是子组件的 prop 名称,parentprop 是父组件绑定的 prop 名称。Vue 中 sync 作用在 Vue 中,sync 修饰符是一种特殊的语法糖,它允许在父组件和子组件之间进
- 【Vue】vue通过class获取dom
- 其实就是操作 html 中的标签的一些能力 我们可以操作哪些内容 获取一个元素 移除一个元素 创建一个元素 向页面里面添加一个元素 给元素绑定一些事件 获取元素的属性给元素添加一些 css 样式 ... DOM 的核心对象就是 docuemnt 对象 document 对象是浏览器内置的一个对象,里面存储着专门用来操作元素的各种方法 DOM: 页面中的标签,我们通过 js 获取到以后,就把这个对象叫做 DOM 对象获取一个元素通过 js 代码来获取页面中的标签获取到以后我们
- 【Vue】Vue定义全局变量的方法
- 在Vue项目中我们需要使用许多的变量来维护数据的流向和状态,这些变量可以是本地变量、组件变量、父子组件变量等,但这些变量都是有局限性的。在一些场景中,可能需要在多个组件中共享某个变量,此时全局变量就派上了用场。定义全局变量的方法1. 使用Vue.prototype定义全局变量通过在 vue 的原型上定义属性,可以在所有组件中访问该属性。在main.js定义全局变量// main.jsVue.prototype.baseUrl = "https://www.example.com/api
- 【Vue】Vue3 开发实战分享——打印插件 Print.js 的使用(Vue3 + Nodejs + Print.js 实战)以及 el-table 与 el-pagination 的深入使用(上)
- 文章目录📋前言🎯关于 Print.js🧩PDF 打印🧩网页(HTML)打印🧩图像打印🧩JSON 打印🧩下载并安装使用🧩相关配置🎯 Vue3 中使用 Print.js 实战🎯Vue3 + Nodejs + Print.js 模拟打印实战案例🧩启动 Nodejs 服务🧩启动 Vue 项目📝最后📋前言今天久违的更新一下关于 Vue 的文章了,本篇文章是基于 Vue3 + Node.js + ElementPlus 的实战项目分享,实战内容包括有打印插件 Print.js 的