Vue封装文件上传组件(支持图片、PDF、Excel、word预览下载)

一、准备工作

安装预览依赖包:exceljs、mammoth、vue-pdf

二、封装组件

文件上传组件

fileUploadPro.vue。默认预览、下载是true,可通过isPreView、isDownLoad控制

<template><div style="display: flex"><el-uploadmultipleaction=""ref="uploadF":show-file-list="false":file-list="fileList":http-request="fileUpLoad"><el-button v-if="!readOnly" size="mini" type="primary">点击上传</el-button></el-upload><div style="flex-grow: 1;flex-wrap: wrap"><el-tag@close="removeFile(index)"v-for="(tag, index) in fileList":key="tag.fileId":closable="true"type="info"><div style="float: left">{{tag.name}}</div><div v-if="isPreView" class="iconStyle" @click="preView(tag)"><i  class="el-icon-view"></i></div><div v-if="isDownLoad" class="iconStyle" @click="downLoad(tag)"><i  class="el-icon-download"></i></div></el-tag></div></div>
</template>
<script>export default {name: "fileUploadPro",props: {fileList: {type: Array,default: []},isPreView: {type: Boolean,default: true},isDownLoad: {type: Boolean,default: true},readOnly:{type: Boolean,default: false}},data() {return {}},methods:{fileUpLoad(e) {let file = e.filelet formData = new FormData();formData.append("file", file); // 'file' 可变 相当于 input 表单的name 属性formData.append("name", file.name);formData.append("type", file.type);formData.append("size", file.size);formData.append("lastModifiedDate", file.lastModifiedDate);this.$http({method: 'post',url: "/base/ctBaseFile/saveFile50",data: formData}).then((response) => {if (response.data.code === 200) {this.$message.success('上传成功')this.fileList.push({fileId: response.data.data.ctBaseFile.id,name: file.name})}})},removeFile(index) {this.fileList.splice(index, 1)},preView(file) {let fileUrl = '';let fileType = '';if (file) {fileUrl = this.$fileUrl + '/common/getFileRes/' + file.fileIdconst addTypeArray = file.name.split(".");const addType = addTypeArray[addTypeArray.length - 1];if (addType === "pdf") {fileType = 'pdf'}else if(addType === 'xls' || addType === 'xlsx'){fileType = 'excel'}else if (addType === "doc" || addType === "docx") {fileType = 'word'} else if (["png", "jpg", "jpeg"].includes(addType)) {fileType = 'image'} else {fileType = addType}}this.$emit("preView",fileType,fileUrl);//that.showModal = true},downLoad(file){let a = document.createElement("a");//创建a标签a.setAttribute("href", this.$fileUrl + '/common/getFileRes/' + file.fileId);//设置文件下载地址a.setAttribute('target', '_blank');//在当前页面创建下载document.body.appendChild(a);//添加到bodya.click();//触发事件document.body.removeChild(a);//移除标签},}}
</script>
<style scope>.iconStyle{float: left;width: 16px;height: 16px;line-height: 16px;text-align: center;position: relative;top:7px;margin-left: 6px;border-radius: 50%;cursor: pointer;}.iconStyle:hover{background-color: #909399;color: #fff;}
</style>

预览组件

preViewDialog.vue

<template><div><!-- Modal --><el-dialog:title="'预览' + fileType":visible.sync="showModal"width="70%"top="5vh":before-close="handleClose":close-on-click-modal="false"><!-- Conditional rendering based on fileType --><div v-if="fileType === 'image'" style="text-align:center"><img v-loading="loading" style="height: 400px" :src="fileUrl" alt="预览图片"></div><div v-else-if="fileType === 'excel'"><el-table v-loading="loading" size="mini" :data="excelData" height="400" width="100%" :show-header="false"><el-table-column width="150" v-for="(cell, key) in excelData[0]" :key="key" :prop="key" :label="key"></el-table-column></el-table></div><div v-else-if="fileType === 'pdf'"><!-- Render PDF preview here --><VuePdf v-loading="loading" :src="pdfUrl"></VuePdf></div><div v-else-if="fileType === 'word'"><!-- Render Word preview here --><div v-loading="loading" v-html="wordContent"></div></div><div v-else><p>不支持的文件类型或未提供URL。</p></div><!-- Close Button --><span slot="footer" class="dialog-footer"><el-button type="primary" @click="downLoad(fileUrl)">下 载</el-button><el-button type="info" @click="closeModal">关 闭</el-button></span></el-dialog></div>
</template><script>import ExcelJS from 'exceljs';import mammoth from 'mammoth';import VuePdf from 'vue-pdf';export default {props: {fileType: {type: String,required: true,},fileUrl: {type: String,required: true}},components: {VuePdf,},data() {return {pdfUrl:'',loading: true,excelContent: '',wordContent: '',showModal: false,excelData: [],};},mounted() {this.showModal = truethis.loadFile();},methods: {async loadFile() {switch (this.fileType) {case 'excel':await this.loadExcel();break;case 'word':await this.loadWord();break;case 'pdf':// 加载 PDF 的逻辑await this.loadPdf();break;default:this.loading = false;break;}},closeModal() {this.loading = true;this.$emit('close-modal');},async loadExcel() {try {const response = await fetch(this.fileUrl);if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}const arrayBuffer = await response.arrayBuffer();const workbook = new ExcelJS.Workbook();await workbook.xlsx.load(arrayBuffer);const worksheet = workbook.worksheets[0]; // Assuming you want the first worksheetif (worksheet) {let data = [];worksheet.eachRow((row, rowIndex) => {let rowData = {};row.eachCell((cell, colIndex) => {rowData[`col${colIndex}`] = cell.value;});data.push(rowData);});this.excelData = data;} else {this.excelData = [];}} catch (error) {console.error('Error loading Excel:', error);this.excelData = [];} finally {this.loading = false;}},async loadWord() {try {const response = await fetch(this.fileUrl);const arrayBuffer = await response.arrayBuffer();const result = await mammoth.extractRawText({ arrayBuffer });this.wordContent = result.value;} catch (error) {this.wordContent = '加载Word文件失败。';} finally {this.loading = false;}},async loadPdf() {try {this.pdfUrl = VuePdf.createLoadingTask({url:this.fileUrl,cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.6.347/cmaps/',cMapPacked: true})const response = await fetch(this.pdfUrl);if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}} catch (error) {console.error('Error fetching data:', error);}finally {this.loading = false}},handleClose() {this.closeModal()},downLoad(file){let a = document.createElement("a");//创建a标签a.setAttribute("href", file);//设置文件下载地址a.setAttribute('target', '_blank');//在当前页面创建下载document.body.appendChild(a);//添加到bodya.click();//触发事件document.body.removeChild(a);//移除标签},},};
</script><style scoped>
</style>

三、组件调用

<template><div><fileUploadPro:file-list.sync="fileList":isPreView="true":isDownLoad="false"@preView="preView"/><previewDialogv-if="showModal":file-type="fileType":file-url="fileUrl"@close-modal="showModal = false"/></div>
</template>
<script>import previewDialog from '../components/previewDialog';import fileUploadPro from "../components/fileUploadPro";export default {name: "parentXXX",components:{previewDialog,fileUploadPro},data() {return{fileList:[],fileType: '',fileUrl:'',showModal: false,}},methods:{preView(type,url){this.fileUrl = url;this.fileType = type;this.showModal = true},}}
</script>

四、效果

 

 

 

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

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

相关文章

SSM 整合(Spring + MyBatis;Spring + Spring MVC)

1. SSM 整合(Spring MyBatis&#xff1b;Spring Spring MVC) 文章目录 1. SSM 整合(Spring MyBatis&#xff1b;Spring Spring MVC)2. 引入相关依赖3. SSM 整合3.1 创建包结构 4. Spring 整合 MyBatis4.1 编写 jdbc.properties4.2 编写 DataSourceConfig 数据源配置4.3 编…

大数减法c++

这里写目录标题 key key 检查减数和被减数的大小&#xff0c;大的放前&#xff0c;小的放后确定结果是正数&#xff0c;还是负数&#xff0c;即符号位从低位开始减如果a[i]<b[i]&#xff0c;则向高位借1当10&#xff0c;a[i1]–;a[i]10 #include <iostream> #include…

[MySQL][索引][下][理解索引]详细讲解

目录 0.前期准备1.为何IO交互要是Page&#xff1f;2.理解单个Page3.理解多个Page4.页目录5.单页情况6.多页情况7.总结复盘8.InnoDB 在建立索引结构来管理数据的时候&#xff0c;其他数据结构为何不行&#xff1f;9.聚簇索引 vs 非聚簇索引 0.前期准备 建立测试表 create table …

云手机结合自主ADB命令接口 提升海外营销效率

现在&#xff0c;跨境电商直播已经成为在线零售的重要渠道&#xff0c;在大环境下&#xff0c;确保直播应用的稳定性和用户体验至关重要。 云手机支持自主ADB命令接口&#xff0c;为电商直播营销提供了技术支持&#xff0c;使得应用开发、测试、优化和运维更加高效。 什么是A…

Linux-交换空间(Swap)管理

引入概念 在计算机中&#xff0c;硬盘的容量一般比内存大&#xff0c;内存&#xff08;4GB 8GB 16GB 32GB 64GB…&#xff09;&#xff0c;硬盘&#xff08;512GB 1T 2T…&#xff09;。 冯诺依曼的现代计算机结构体系里面的存储器就是内存 内存是一种易失性存储器&#xff0c…

0718,TCP协议,三次握手,四次挥手

爬东西只能明天了喵 上课喵&#xff1a; TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;的状态迁移图 这图别看&#xff0c;会瞎 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;的状态迁移图描述…

40.简易频率计(基于等精度测量法)(3)

&#xff08;1&#xff09;BCD8421码&#xff1a;十进制数字转换成BCD8421码的方法 补零&#xff1a;你需要显示多少位数字&#xff0c;就在前面补上四倍的位宽。比如你要显示一个十进制8位的数字&#xff0c;就在前面补上8*432个零。判断&#xff1a;判断补零部分显示的十进制…

注册安全分析报告:东方航空

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

ruoyi部署前端,服务器访问模块报错:Error: Cannot find module ‘@/views/system/user/index’

找到permission.js文件 loadView修改代码如下&#xff1a; export const loadView (view) > {if (process.env.NODE_ENV development) {return (resolve) > require([/views/${view}], resolve)} else {// 使用 import 实现生产环境的路由懒加载// return () > imp…

Linux下vim编辑器的使用方法

Vim编辑器 vim kk 使用vim来创建或编辑 kk文件 一般模式下的操作 x 为向后删除一个字符 nx 连续向后删除n个字符 dd 删除光标所在行 ndd 删除光标所在的向下n行 yy 复制光标所在的那一行 nyy 复制光标所在的向下n列 p 将已复制的数据在光标下一行粘贴上 P 则为贴在光标的上一…

【golang-ent】go-zero框架 整合 ent orm框架 | 解决left join未关联报错的问题

一、场景 1、子表&#xff1a;cp_member_point_history cp_member_point_history表中字段&#xff1a;cp_point_reward_id 是cp_point_reward的主键id 当本表中的cp_point_reward_id字段为0&#xff08;即&#xff1a;没有可关联主表的&#xff09; CREATE TABLE cp_member_poi…

studio编译报错java.lang.NullPointerException

安卓studio编译报错&#xff0c;这个是一个新建的项目就报错&#xff0c;原因是 implementation androidx.appcompat:appcompat:1.7.0版本太高&#xff0c;修改后版本 implementation androidx.appcompat:appcompat:1.4.0&#xff0c; 编译又报错 18 issues were found wh…

浅聊 Three.js 屏幕空间反射SSR-SSRShader

浅聊 Three.js 屏幕空间反射SSR(2)-SSRShader 前置基础 渲染管线中的相机和屏幕示意图 -Z (相机朝向的方向)||| -------------- <- 屏幕/投影平面| | || | || | (f) | <- 焦距| | ||…

SpringBoot框架学习笔记(三):Lombok 和 Spring Initailizr

1 Lombok 1.1 Lombok 介绍 &#xff08;1&#xff09;Lombok 作用 简化JavaBean开发&#xff0c;可以使用Lombok的注解让代码更加简洁Java项目中&#xff0c;很多没有技术含量又必须存在的代码&#xff1a;POJO的getter/setter/toString&#xff1b;异常处理&#xff1b;I/O…

解决gitlab报502的问题

external_url http://10.7.24.6:10002 puma[port] 8091 sudo gitlab-ctl reconfigure sudo gitlab-ctl restart 设置管理员密码&#xff1a; 1. 切换目录&#xff1a;cd 安装目录gitlab的bin目录下 2. 以root执行 &#xff1a;gitlab-rails console命令&#xff0c;等待…

Axure RP移动端医院在线挂号app问诊原型图模板

医疗在线挂号问诊Axure RP原型图医院APP原形模板&#xff0c;是一款原创的医疗类APP&#xff0c;设计尺寸采用iPhone13&#xff08;375*812px&#xff09;&#xff0c;原型图上加入了仿真手机壳&#xff0c;使得预览效果更加逼真。 本套原型图主要功能有医疗常识科普、医院挂号…

PyTorch 深度学习实践-处理多维特征的输入

视频指路 参考博客笔记 参考笔记二 通过多个线性模型来模拟非线性的空间变换&#xff0c;矩阵计算就是不同维度之间的空间转换 说明&#xff1a;1、乘的权重(w)都一样&#xff0c;加的偏置(b)也一样。b变成矩阵时使用广播机制。神经网络的参数w和b是网络需要学习的&#xff0c…

0718vscode问答

终于来到 qt # Question 多态 # Answer 多态是面向对象编程中的一个重要概念&#xff0c;指的是同一个接口可以有多种不同的实现方式。多态性允许我们使用一个统一的接口来处理不同类型的对象&#xff0c;从而提高代码的灵活性和可扩展性。 在Java中&#xff0c;多态可以通过以…

使用Python实现高效的图像处理:基于OpenCV的实战指南

目录 引言 准备工作 安装Python与OpenCV 导入必要的库 基本图像处理操作 读取与显示图像 转换图像颜色空间 图像变换 图像滤波 实战案例&#xff1a;边缘检测 引言 在现代科技快速发展的今天&#xff0c;图像处理已成为众多领域不可或缺的一部分&#xff0c;包括计算…

Wireshark抓取HTTP

HTTP请求响应 使用wireshark抓取 本地机器是192.168.33.195&#xff0c;远程机器是192.168.32.129&#xff0c;远程HTTP服务端口是9005 TCP/IP实际共分为4层&#xff0c;抓包信息中可以看到各层的数据&#xff0c;最上面的数据帧包含了所有数据。 附&#xff1a;抓取本地H…