当前位置: 首页 > news >正文

Vue2+Element实现Excel文件上传下载预览【超详细图解】

目录

一、需求背景

二、落地实现 

1.文件上传

图片示例 

HTML代码 

业务代码

2.文件下载

图片示例

方式一:代码

方式二:代码

3.文件预览

图片示例

方式一:代码

方式二:代码


一、需求背景

在一个愉快的年后,需求经理提出需要完成对单个Excel文件的上传、下载、预览的功能,对于一个没写过下载和预览的后端来说,真的十分痛苦,经过不断百度+努力看别人的博客,最终实现如下图所示

二、落地实现 

1.文件上传

图片示例 

HTML代码 

<template><el-upload v-model="form.upload" ref="upload" name="file" action="" drag :on-remove="handleRemove" :on-success="handleSuccess" multiple :limit="1" accept=".xls,.xlsx" :before-upload="beforeUpload" :http-request="handleRequest" :on-exceed="handleExceed"><i class="el-icon-upload" style="color: #409eff"></i><div class="el-upload__tip"><span style="color: #333333;font-size: 13px">点击或将文件拖拽到这里上传</span></div><div class="el-upload__tip"><span style="color: #999999;font-size: 13px">仅支持单文件上传,文件上传行数最多1000,上传格式支持:.xls .xlsx</span></div></el-upload>
<template>

 参数解释

name="file":是传到后端时,它接收这个文件的参数名叫file,本人没有仔细研究,因为在调接口时,可个性化定制参数名,后续贴的代码会提到。

action="":这个Element官方文档写的是一个上传的固定链接,假的,用不了。通常在开发中,也是自定义上传逻辑,所以这里置空。

drag:启用拖拽上传,Element默认是false,直接写drag,不写:drag="true"就是true了。

show-file-list:显示已上传文件列表,就是上传框下面的那行文件名,Element默认是false

multiple:支持多选文件,通常与limit搭配使用。

:limit="1":多选文件数量,如只需要单个文件就设置1。

accept=".xls,.xlsx":接受上传的文件类型,我的需求是只要Excel的。

:on-remove="handleRemove":文件列表移除文件时的方法,就是文件列表右边那个小X触发时调用的。

:on-success="handleSuccess":文件上传成功时的方法,比如弹出一个上传成功提示。

:before-upload="beforeUpload":上传文件之前的方法,通常用于上传文件前对文件的校验。

:http-request="handleRequest":自定义上传方式的方法,比如远程调用。

:on-exceed="handleExceed":文件超出个数限制时的方法,比如弹出一个仅支持单个文件的提示。

class="el-upload__tip":这个是Element封装好的样式,我的需求是需要文字在上传框里显示,所以都用el-upload__tip,官方文档还有个框外的用el-upload__text。

业务代码

export default {name: "upload-dialog",data() {return {};},methods: {handleSuccess(response, file, fileList) {// 文件上传成功的回调this.$message.success("上传成功");},handleRemove(file, fileList) {console.log("删除", file, fileList);// 看需要是否调用删除接口},beforeUpload(file) {// 在这里进行个性化校验const maxSize = 100 * 1024 * 1024; // 100MB(以字节为单位)if (file.size > maxSize) {// 这里可以添加你的提示逻辑(比如 Element UI 的 Message 警告)this.$message.warning("文件大小不能超过 100 MB");return false; // 阻止上传}return true;},handleRequest(option) {// 自定义上传函数,用于并发上传const formData = new FormData();// 这个file就是后端的接收这个文件的参数名,如果为其他,则设成其他formData.append("file", option.file);// 如果还需要其他参数比如id,name,就在这里继续加// formData.append("id", xxx);// 发送请求,这个uploadApi是import进来的,自己写uploadApi(formData).then(res => {// 自定义上传方法的话,需要手动触发文件上传成功的钩子,不然文件状态会一直处于readyoption.onSuccess(null, option.file);}).catch(error => {// 自定义上传方法的话,需要手动触发文件上传失败的钩子,不然文件状态会一直处于readyoption.onError(error, option.file, null);});},// 文件超出个数限制时的钩子handleExceed(files, fileList) {this.$message.warning("仅支持单个文件上传");},},
};

2.文件下载

图片示例

我是通过<a></a>标签去实现文件下载的,如果想通过点击按钮实现,那么,在按钮里面套塞<a></a>即可

方式一:代码

<template><a :href="fileUrl" download>>文件</a>
</template>
export default {data() {return {fileUlr: 'http://static.shanhuxueyuan.com/demo/excel.xlsx'};},
}

这个href放是一个像http://static.shanhuxueyuan.com/demo/excel.xlsx这样的cdn文件地址,点击就可以直接下载到本地。

如果需要通过二进制流、Blob对象实现的话,则自定义按钮,触发方法去调用。(详情请看方式二)

方式二:代码

<template><el-button type="text" @click="downloadFile(fileName)"><span style="color: #0000FF">文件名</span></el-button>
</template>
export default {data() {return {};},methods: {downloadFile(fileName) {// 生成随机数据(示例:5行3列)const data = [["Name", "Age", "Join Date"], // 表头...Array.from({length: 5}, (_, i) => [`User ${i + 1}`, // 姓名Math.floor(Math.random() * 30 + 20), // 随机年龄 (20-50)new Date().toISOString().split("T")[0], // 当前日期]),];// 创建工作表const worksheet = XLSX.utils.aoa_to_sheet(data);// 创建工作簿const workbook = XLSX.utils.book_new();XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");// 生成 Excel 文件const excelBuffer = XLSX.write(workbook, {bookType: "xlsx",type: "array",});const blob = new Blob([excelBuffer], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",});// 创建一个链接元素const link = document.createElement('a');link.href = URL.createObjectURL(blob);link.download = fileName; // 设置下载的文件名// 触发下载link.click();// 释放 URL 对象URL.revokeObjectURL(link.href);this.$message.success("文件下载成功");},}
}

3.文件预览

图片示例

我的需求是:点击文件名,浏览器新打开一个标签页,展示文件内容。

这个需要在route中额外添加一个路由映射

{path: '/preview',name: 'preview',meta: { title: '文件预览', requiresAuth: false },component: () => import('@/views/preview.vue')
},

还需要额外结合@vue-office/excel写页面 

npm install @vue-office/excel vue-demi

方式一:代码

入口代码

<template><el-button type="text"><a :href="'#/preview?fileUrl='+fileUrl" target="_blank">详情</a></el-button>
</template>
export default {data() {return {fileUlr: 'http://static.shanhuxueyuan.com/demo/excel.xlsx'};},
}

 页面代码

<template><vue-office-excel :src="excel" @rendered="rendered" @error="errorHandler"/>
</template>
<script>
//引入VueOfficeExcel组件
import VueOfficeExcel from "@vue-office/excel";
//引入相关样式
import "@vue-office/excel/lib/index.css";
//引入解析Excel文件组件
import XLSX from "xlsx";export default {components: {VueOfficeExcel,},data() {return {// 设置文档地址,支持三种格式// string: Excel文件的网络地址,如cdn地址// ArrayBuffer:以ArrayBuffer格式读取Excel文件的内容// Blob:以Blob格式读取Excel文件的内容excel: "",};},mounted() {this.getExcel();},methods: {rendered() {console.log("渲染完成");},errorHandler() {console.log("渲染失败");},getExcel() {this.excel = this.$route.query.fileUrl;}},
};
</script>

这样直接就是浏览器新打开一个标签页展示文件内容。与文件下载十分相似。

如果需要使用二进制流、Blob对象打开的话。(详情请看方式二)

方式二:代码

入口代码

<template><el-button type="text"><a :href="'#/preview'" target="_blank">详情</a></el-button>
</template>

页面代码

<template><vue-office-excel :src="excel" @rendered="rendered" @error="errorHandler"/>
</template>
<script>
//引入VueOfficeExcel组件
import VueOfficeExcel from "@vue-office/excel";
//引入相关样式
import "@vue-office/excel/lib/index.css";
//引入解析Excel文件组件
import XLSX from "xlsx";export default {components: {VueOfficeExcel,},data() {return {// 设置文档地址,支持三种格式// string: Excel文件的网络地址,如cdn地址// ArrayBuffer:以ArrayBuffer格式读取Excel文件的内容// Blob:以Blob格式读取Excel文件的内容excel: "",};},mounted() {this.createRandomExcel();},methods: {rendered() {console.log("渲染完成");},errorHandler() {console.log("渲染失败");},// 创建随机 Excel 文件createRandomExcel() {// 生成随机数据(示例:5行3列)const data = [["Name", "Age", "Join Date"], // 表头...Array.from({length: 5}, (_, i) => [`User ${i + 1}`, // 姓名Math.floor(Math.random() * 30 + 20), // 随机年龄 (20-50)new Date().toISOString().split("T")[0], // 当前日期]),];// 创建工作表const worksheet = XLSX.utils.aoa_to_sheet(data);// 创建工作簿const workbook = XLSX.utils.book_new();XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");// 生成 Excel 文件const excelBuffer = XLSX.write(workbook, {bookType: "xlsx",type: "array",});const blob = new Blob([excelBuffer], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",});this.excel = blob;},},
};
</script>

上述代码,也适用于展示Word和PPT文件,修改对应的格式即可。 

相关文章:

Vue2+Element实现Excel文件上传下载预览【超详细图解】

目录 一、需求背景 二、落地实现 1.文件上传 图片示例 HTML代码 业务代码 2.文件下载 图片示例 方式一&#xff1a;代码 方式二&#xff1a;代码 3.文件预览 图片示例 方式一&#xff1a;代码 方式二&#xff1a;代码 一、需求背景 在一个愉快的年后&#xff…...

C# 装箱(Boxing)与拆箱(Unboxing)

C# 装箱&#xff08;Boxing&#xff09;与拆箱&#xff08;Unboxing&#xff09; 在 C# 中&#xff0c;装箱和拆箱是与值类型&#xff08;如结构体&#xff09;和引用类型&#xff08;如类&#xff09;之间的转换相关的操作。它们是类型系统的一部分&#xff0c;但如果不正确使…...

【AD】3-10 原理图PDF导出

文件—智能PDF 多页原理图导出 导出设置时选择工程&#xff0c;可自行选择导出一页或多页原理图&#xff0c;一般PCB不用导出...

SQL命令详解之增删改数据

目录 简介 1 添加数据 1.1 基础语法 1.2 SQL 练习 2 修改数据 2.1 基础语法 2.2 SQL 练习 ​3 删除数据 3.1 基础语法 3.2 SQL 练习 总结 简介 在数据库操作中&#xff0c;增、删、改是最基础的操作&#xff0c;它们通常对应着SQL中的INSERT、DELETE和UPDATE命令。…...

Docker 部署 MinIO 对象存储服务

Docker 部署 MinIO 对象存储服务 前言一、准备工作1. 安装 Docker2. 确认服务器架构 二、设置 MinIO 容器的目录结构三、启动一个临时的 MinIO 容器来获取配置文件四、复制 MinIO 配置文件到本地目录五、删除临时 MinIO 容器六、创建并运行 MinIO 容器&#xff0c;挂载本地目录…...

IP段转CIDR:原理Java实现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

翻译: 深入分析LLMs like ChatGPT 一

大家好&#xff0c;我想做这个视频已经有一段时间了。这是一个全面但面向普通观众的介绍&#xff0c;介绍像ChatGPT这样的大型语言模型。我希望通过这个视频让大家对这种工具的工作原理有一些概念性的理解。 首先&#xff0c;我们来谈谈你在这个文本框里输入内容并点击回车后背…...

springboot之HTML与图片生成

背景 后台需要根据字段动态生成HTML&#xff0c;并生成图片&#xff0c;发送邮件到给定邮箱 依赖 <!-- freemarker模板引擎--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifa…...

数据结构(初阶)(三)----单链表

单链表 概念 概念&#xff1a;链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 结点 与顺序表不同的是&#xff0c;链表的结构类似于带车头的火车车厢&#xff0c;&#xff0c;链表的每个车厢都是独立…...

ChatGPT与DeepSeek:AI语言模型的巅峰对决

目录 引言 一、ChatGPT 与 DeepSeek 简介 &#xff08;一&#xff09;ChatGPT &#xff08;二&#xff09;DeepSeek 二、技术原理剖析 &#xff08;一&#xff09;ChatGPT 技术原理 &#xff08;二&#xff09;DeepSeek 技术原理 &#xff08;三&#xff09;技术原理对比…...

DaoCloud 亮相 2025 GDC丨开源赋能 AI 更多可能

2025 年 2 月 21 日至 23 日&#xff0c;上海徐汇西岸&#xff0c;2025 全球开发者先锋大会以 “模塑全球&#xff0c;无限可能” 的主题&#xff0c;围绕云计算、机器人、元宇宙等多元领域&#xff0c;探讨前沿技术创新、应用场景拓展和产业生态赋能&#xff0c;各类专业论坛、…...

人工智能之数学基础:线性代数中矩阵的运算

本文重点 矩阵的运算在解决线性方程组、描述线性变换等方面发挥着至关重要的作用。通过对矩阵进行各种运算,可以简化问题、揭示问题的本质特征。在实际应用中,我们可以利用矩阵运算来处理图像变换、数据分析、电路网络等问题。深入理解和掌握矩阵的运算,对于学习线性代数以…...

(上)基于机器学习的图像识别——遥感图像分类(LeNet-5;AlexNet;VGGNet;GoogLeNet;ResNet)

遥感图像识别&#xff1a; 专业词汇&#xff1a; kernel&#xff1a;卷积 目录 遥感图像分类 1.1 LeNet-5 视频来源&#xff1a; 任务&#xff1a;使用什么网络实现遥感图像的分类 LeNet-5结构&#xff1a; 遥感图像分类 1.2 AlexNet&#xff08;冠军&#xff09; 视频…...

数据集笔记:NUSMods API

1 介绍 NUSMods API 包含用于渲染 NUSMods 的数据。这些数据包括新加坡国立大学&#xff08;NUS&#xff09;提供的课程以及课程表的信息&#xff0c;还包括上课地点的详细信息。 可以使用并实验这些数据&#xff0c;它们是从教务处提供的官方 API 中提取的。 该 API 由静态的…...

HTML元素,标签到底指的哪块部分?单双标签何时使用?

1. 标签&#xff08;Tag&#xff09; vs 元素&#xff08;Element&#xff09; 标签&#xff08;Tag&#xff09; 标签是 HTML 中用于定义元素的符号&#xff0c;用尖括号 < > 包裹。例如 <img> 是标签。元素&#xff08;Element&#xff09; 元素是由 标签 内容…...

基于ai技术的视频生成工具

一、通用型AI视频生成工具 腾讯智影 特点&#xff1a;支持数字人播报、文字转视频&#xff0c;提供免费模板和素材库&#xff0c;登录即送5分钟免费时长&#xff0c;每日签到可兑换额外额度。 限制&#xff1a;免费版分辨率较低&#xff0c;部分高级功能需付费。 LunaAI.vid…...

【Java 后端】Restful API 接口

Restful API 接口 REST&#xff1a;Representational State Transfer&#xff0c;表现层&#xff08;前端的视图页面和后端的控制层&#xff09;资源状态转移。 一种软件架构的风格&#xff08;格式&#xff09; RESTful 是目前最流行的互联网软件架构&#xff0c;如果一个架…...

Matlab地图绘制教程第2期—水陆填充图

上一期分享了海岸线图的绘制方法&#xff1a; 本着由浅入深的理念&#xff0c;本期再来分享一下水陆填充图的绘制方法。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;Matlab地图绘制教程系列&#xff0c;旨在降低大家使用Matlab进行地图类科研绘图的门槛&#xff0c;…...

企业知识库搭建:14款开源与免费系统选择

本文介绍了以下14 款知识库管理系统&#xff1a;1.Worktile&#xff1b;2.PingCode&#xff1b;3.石墨文档&#xff1b; 4. 语雀&#xff1b; 5. 有道云笔记&#xff1b; 6. Bitrix24&#xff1b; 7. Logseq等。 在如今的数字化时代&#xff0c;企业和团队面临着越来越多的信息…...

【Linux系统】—— 冯诺依曼体系结构与操作系统初理解

【Linux系统】—— 冯诺依曼体系结构与操作系统初理解 1 冯诺依曼体系结构1.1 基本概念理解1.2 CPU只和内存打交道1.3 为什么冯诺依曼是这种结构1.4 理解数据流动 2 操作系统2.1 什么是操作系统2.2 设计OS的目的2.3 操作系统小知识点2.4 如何理解"管理"2.5 系统调用和…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...