您的当前位置:首页>全部文章>文章详情

【VUE】Vue3 实现文件预览 Word Excel pdf 图片 视频等格式 大全!!!!

CrazyPanda发表于:2023-12-28 20:57:16浏览:313次TAG:

先上效果图

1.png

1.png 

 插件安装

先说 word 文件是docx-preview插件

          excel文件是用 xlsx 插件    

介绍后端返回的数据

1.png

因为在拦截器处 做了对数据的处理 最后你调接口拿到的数据是 一个对象 里面包含:

url : blob对象转换的用于访问Blob数据的临时链接。这个链接可以被用于在网页中展示二进制数据,比如显示图像或者播放音视频文件

blobs:  返回的Blob对象,代表了从网络请求中获取到的二进制数据

这上下俩部分很重要!!!!!!!!

如果返回的普通格式的话就大家直接转化

  1. const blob = new Blob([res], { type: 'application/pdf' })  //你需要的类型 转化为blob对象

  2. const url = window.URL.createObjectURL(blob)         //将对象转化为链接



也就是你后面掉接口返回的数据  1.png

给大家打印一下 我当时在网上搜索这类资料的时候 就是在这一部分弄糊涂了 对数据格式不了解

 1.png

 然后就到正式书写了

下载引入插件 (我这是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数据 然后进行展示 

我只能给大家说一下我的逻辑 毕竟每个人代码不一样 不一定能直接复制  还是希望能帮到大家


最后贴上效果图

1.png

1.png 


原文链接https://blog.csdn.net/m0_65607651/article/details/133887921如有侵权可联系删除

猜你喜欢

【VUE】Vue3 实现文件预览 Word Excel pdf 图片 视频等格式 大全!!!!
先上效果图&nbsp;&nbsp;插件安装先说 word 文件是docx-preview插件&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; excel文件是用&nbsp;xlsx 插件&nbsp; &nbsp;&nbsp;介绍后端返回的数据因为在拦截器处 做了对数据的处理 最后你调接口拿到的数据是 一个对象 里面包含:url :&nbsp;blob对象转换的用于访问Blob数据的临时链接。这个链接可以被用于在网页中展示二进制数据,比如显示图像或者播放音视频文件blobs:&amp;
发表于:2023-12-28 浏览:314 TAG:
【Vue】vue.js怎么定义一个组件
vue.js 中定义组件有三种方法:直接定义在 &lt;script&gt; 标签中并导出组件对象、使用组件工厂函数和 definecomponent 辅助函数创建、使用类定义组件并继承 vue.extend 创建。&lt;/script&gt;如何在 Vue.js 中定义组件一、直接定义1. 在 &lt;script&gt;&lt;/script&gt; 标签中,使用 export default {} 导出组件对象:&lt;code&nbsp;class=&quot;html&quot;&amp;g
发表于:2024-04-21 浏览:241 TAG:
【Vue】Antd Pro Vue的使用(四)—— 打包发布到站点二级目录,生产环境请求接口配置
如题,Antd Pro Vue开发完成后,要打包发布到站点指定二级目录下,我这里服务端配置的是tp,在站点public文件夹新建一个system文件夹,前端打包后要放到个文件夹里面,需要配置2步1. 在根目录vue.config.js文件夹中配置publicPath&nbsp;publicPath:&nbsp;&#39;/system/&#39;,2. 在/src/router/index.js文件中,增加base配置,配置内容与publicPath保持一致router:&nbsp;{ &amp;nbs
发表于:2024-04-27 浏览:338 TAG:
【Vue】Antd Pro Vue的使用(八) —— 表单组件的常用配置
1、清除配置allow-clear在ant design react组件中,表单组件默认都有清除按钮(输入框右侧的小黑叉号),在vue组件中需要自己配置,即给组件加上allow-clear属性并且所有组件都支持这个属性,a-input、a-select、a-textarea、a-date-picker等都支持&lt;a-form-item&nbsp;label=&quot;用户名&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;a-input&nbsp; &nbsp;
发表于:2024-05-10 浏览:285 TAG:
【Vue】Vue 前后端分离部署方案
方案 1:Docker创建两个 Docker 容器,一个用于后端,一个用于前端。在后端容器中运行 API 代码。在前端容器中运行 Vue 应用程序并将其打包为静态文件(如 HTML、CSS 和 JS)。方案 2:Nginx 代理安装 Nginx Web 服务器作为反向代理。将后端 API 路由到 Nginx。Nginx 将前端静态文件提供给客户端。方案 3:Node Express使用 Node Express 作为后端框架,它可以将静态文件与 API 路由一起托管。在 Express 应用程序
发表于:2024-05-19 浏览:253 TAG:
【Vue】Vue常用框架介绍
现在的应用基本都是前后端分离,在国内,Vue相对来说更受欢迎一些,我们很多后端系统的前端都是Vue来开发的。那么Vue UI框架就显得尤为重要。Vue UI框架提供了一套丰富的用户界面组件及完整的前端UI解决方案,如按钮、表单、导航、布局等,使得开发者可以专注于业务逻辑开发,而不用从零构建这些常用的界面元素,帮助开发者更快速地构建高质量的用户界面。那么,都有哪些开源的UI框架呢?Element UIElement UI是一套为开发者、设计师和产品经理准备的基于Vue 2.0的组件库,提供了丰富的
发表于:2024-04-22 浏览:437 TAG:
【Vue】vue3+node+Element-Ui+spark-md5实现大文件上传、断点续传、秒传、多大文件上传
文章目录目录文章目录前言整体架构流程技术名词解释前端大文件上传断点续传后端大文件上传代码部分js部分的逻辑,按照我们的上面的分析,我们可以写出如下的结构将文件变成二进制,方便后续分片将大文件进行分片创建切片请求将每一个切片 并行/串行 的方式发出后端接口逻辑小结前言在Vue项目中,大图片和多数据Excel等大文件的上传是一个非常常见的需求。然而,由于文件大小较大,上传速度很慢,传输中断等问题也难以避免。因此,为了提高上传效率和成功率,我们需要使用切片上传的方式,实现文件秒传、断点续传、错误重试、
发表于:2023-12-05 浏览:325 TAG:
【Vue】深入剖析:Vue核心之虚拟DOM
转载:https://www.cnblogs.com/caihongmin/p/17510878.html前言使用 Vue 做项目也有两年时间了,对 Vue 的 api也用的比较得心应手了,虽然对 Vue 的一些实现原理也耳有所闻,例如 虚拟DOM、flow、数据驱动、路由原理等等,但是自己并没有特意去探究这些原理的基础以及 Vue 源码是如何利用这些原理进行框架实现的,所以利用空闲时间,进行 Vue 框架相关技术原理和 Vue 框架的具体实现的整理。如果你对 Vue 的实现原理很感兴趣,那么就
发表于:2024-05-25 浏览:289 TAG:
【Vue】yarn 运行vue3项目开发模式
要在YARN中以Vue.js 3的开发模式运行项目,可以按照以下步骤进行操作:确保已经安装了Node.js和YARN。如果没有安装,请先安装这两个工具。打开命令提示符或终端并导航到Vue.js 3项目所在的文件夹。使用以下命令来初始化新的YARN项目(如果还未创建):yarn&nbsp;init&nbsp;-y接下来,需要安装Vue CLI脚手架工具。运行以下命令来全局安装Vue CLI:npm&nbsp;install&nbsp;-g&nbsp;@vue/cli然后,通过以下命令将Vue CL
发表于:2024-02-08 浏览:297 TAG:
【Vue】Antd Pro Vue的使用(十二) —— 菜单选中高亮显示问题
Antd Pro Vue2这套框架的路由菜单有两个问题,1、页面迁移子页面,父页面对应的菜单未能选中高亮显示2、登录后默认的菜单或页面刷新后原来的菜单未选中高亮显示网上查到的一些菜单配置都是新版本的,老版本并不支持这些方法,这里总结一下我的解决方法,如果大家有更好的解决方案,欢迎交流。一、解决第一个问题以我的菜单为例商品列表是菜单页面,添加编辑商品是隐藏菜单,我把他们做成了兄弟菜单,而不是子菜单/src/config/router.config.js配置如下然后再/src/layouts/Bas
发表于:2024-05-14 浏览:275 TAG: