当前位置: 首页 > 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: 'www.aaa.com/test.txt'};},
}

这个href放是一个像www.aaa.com/test.txt这样的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: 'www.aaa.com/test.txt'};},
}

 页面代码

<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…...

物联网平台建设方案一

系统概述 构建物联网全域支撑服务能力&#xff0c;为实现学院涵盖物联网设备的全面感知、全域互联、全程智控、全域数字基底、全过程统筹管理奠定基础&#xff0c;为打造智能化提供坚实后台基石。 物联网平台向下接入各种传感器、终端和网关&#xff0c;向上通过开放的实施分…...

机器学习破局指南:零基础6个月系统训练计划

以下是为零基础学习者制定的「机器学习」系统学习计划&#xff08;含学习路径资源推荐&#xff09;&#xff0c;分为6个阶段&#xff0c;建议学习周期4-6个月&#xff1a; 一、基础准备阶段&#xff08;1-2周&#xff09; 目标&#xff1a;掌握必要数学工具与编程基础 数学基础…...

mmdetection框架下使用yolov3训练Seaships数据集

之前复现的yolov3算法采用的是传统的coco数据集&#xff0c;这里我需要在新的数据集上跑&#xff0c;也就是船舶检测方向的SeaShips数据集&#xff0c;这里给出教程。 Seaships论文链接&#xff1a;https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber8438999 一、…...

unity学习52:UI的最基础组件 rect transform,锚点anchor,支点/轴心点 pivot

目录 1 image 图像&#xff1a;最简单的UI 1.1 图像的基本属性 1.2 rect transform 1.3 image的component: 精灵 → 图片 1.4 修改颜色color 1.5 修改材质 1.6 raycast target 1.7 maskable 可遮罩 1.8 imageType 1.9 native size 原生大小 2 rect transform 2.1 …...

STM32MP15-FSMP1A单片机移植Linux系统platform总线驱动

之前在该单片机下移植的Linux驱动是学习过程中&#xff0c;对Linux内核驱动的引导学习&#xff0c;接下来才是比较正常的驱动开发。 在Linux内核中&#xff0c;对于驱动的处理&#xff0c;一般会通过总线进行设备信息和设备驱动的匹配&#xff0c;来达到自动检测外设连接系统以…...

Java 常见的面试题(设计模式)

一、说一下你熟悉的设计模式&#xff1f; **设计模式&#xff1a;**是一套被反复使用的代码设计经验的总结&#xff08;情境中一个问题经过证实的一个解决方案&#xff09;。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使人们可以更加简…...

机器学习3-聚类

1 聚类解决的问题 知识发现&#xff0c;发现事物之间的潜在关系异常值检测特征提取 数据压缩的例子新闻自动分组、用户分群、图像分割、像素压缩等等 2 与监督学习比较 监督学习是需要给定X、Y&#xff0c;X为特征&#xff0c;Y为标签&#xff0c;选择模型&#xff0c;学习&a…...

html中的css

css &#xff08;cascading style sheets&#xff0c;串联样式表&#xff0c;也叫层叠样式表&#xff09; css规范一般约定&#xff1a; 1.存放CSS样式文件的目录一般命名为style或css。 2.在项目初期&#xff0c;会把不同类别的样式放于不同的CSS文件&#xff0c;是为了CSS编…...

36. Spring Boot 2.1.3.RELEASE 中实现监控信息可视化并添加邮件报警功能

1. 创建 Spring Boot Admin Server 项目 1.1 添加依赖 在 pom.xml 中添加 Spring Boot Admin Server 和邮件相关依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-w…...

Linux: 已占用接口

Linux: 已占用接口 1. netstat&#xff08;适用于旧系统&#xff09;1.1 书中对该命令的介绍 2. ss&#xff08;适用于新系统&#xff0c;替代 netstat&#xff09;3. lsof&#xff08;查看详细进程信息&#xff09;4. fuser&#xff08;快速查找占用端口的进程&#xff09;5. …...

Vscode的通义灵码占用空间过大问题【.lingma】

C盘空间发现没装几个软件但是空间占用太离谱了&#xff0c; 最后排查发现是一个.lingma的文件夹问题&#xff0c;这个文件夹用了我居然差不多一百G的空间&#xff0c; 点进去。删除掉ai训练时产生的dbc文件就好了&#xff0c; windowsI 打开系统设置&#xff0c;搜索存储&#…...

鸿蒙Next如何自定义标签页

前言 项目需求是展示标签&#xff0c;标签的个数不定&#xff0c;一行展示不行就自行换行。但是&#xff0c;使用鸿蒙原生的 Grid 后发现特别的难看。然后就想着自定义控件。找了官方文档&#xff0c;发现2个重要的实现方法&#xff0c;但是&#xff0c;官方的demo中讲的很少&…...

知识拓展:Python 接口实现方式对比:Protocol vs @implementer

Python 接口实现方式对比&#xff1a;Protocol vs implementer 1. 两种接口实现方式 1.1 Python Protocol&#xff08;结构化子类型&#xff09; from typing import Protocolclass DownloadHandlerProtocol(Protocol):def download_request(self, request: Request, spider:…...

开源程序wordpress在海外品牌推广中的重要作用

WordPress作为全球最流行的开源内容管理系统(CMS)&#xff0c;在全球网站搭建中占据超过40%的市场份额。其强大的功能、灵活性和易用性使其成为企业进行海外品牌推广的首选平台。以下是WordPress在海外品牌推广中的重要性分析&#xff1a; 1. 多语言支持与本地化 WordPress通…...

【Python爬虫(89)】爬虫“反水”:助力数字版权保护的逆向之旅

【Python爬虫】专栏简介&#xff1a;本专栏是 Python 爬虫领域的集大成之作&#xff0c;共 100 章节。从 Python 基础语法、爬虫入门知识讲起&#xff0c;深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑&#xff0c;覆盖网页、图片、音频等各类数据爬取&#xff…...

k8s面试题总结(五)

1.考虑一种情况&#xff0c;即公司希望通过维持最低成本来提高其效率和技术运营速度。您认为公司将如何实现这一目标&#xff1f; 公司可以通过构建 CI/CD 管道来实现 DevOps 方法&#xff0c;但是这里可能出现的一个问题是配置可能需要一段时间才能启动并运行。 因此&#x…...

文章精读篇——用于遥感小样本语义分割的可学习Prompt

题目&#xff1a;Learnable Prompt for Few-Shot Semantic Segmentation in Remote Sensing Domain 会议&#xff1a;CVPR 2024 Workshop 论文&#xff1a;10.48550/arXiv.2404.10307 相关竞赛&#xff1a;https://codalab.lisn.upsaclay.fr/competitions/17568 年份&#…...

Spring Boot2.0之十 使用自定义注解、Json序列化器实现自动转换字典类型字段

前言 项目中经常需要后端将字典类型字段值的中文名称返回给前端。通过sql中关联字典表或者自定义函数不仅影响性能还不能使用mybatisplus自带的查询方法&#xff0c;所以推荐使用自定义注解、Json序列化器&#xff0c;Spring的缓存功能实现自动转换字典类型字段。以下实现Spri…...

从电子管到量子计算:计算机技术的未来趋势

计算机发展的历史 自古以来人类就在不断地发明和改进计算工具,从结绳计数到算盘,计算尺,手摇计算机,直到1946年第一台电子计算机诞生,虽然电子计算机至今虽然只有短短的半个多世纪,但取得了惊人的发展吗,已经经历了五代的变革。计算机的发展和电子技术的发展密切相关,…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...