C#与Vue2上传下载Excel文件
1、上传文件流程:先上传文件,上传成功,返回文件名与url,然后再次发起请求保存文件名和url到数据库
前端Vue2代码:
使用element的el-upload组件,action值为后端接收文件接口,headers携带session信息,成功后调用onsuccess对应的方法保存文件信息
<el-upload :action="uploadUrl" :headers="uploadHeaders" accept=".xlsx" :show-file-list="false":limit="1" ref="upload" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"><el-button type="primary">导入</el-button></el-upload>
beforeAvatarUpload (res) {const isExcel = /\.(xlsx)$/.test(res.name);if (!isExcel) {toast.error('只能读取.xlsx文件,请另存为.xlsx文件!');return false}const fileSuffix = res.name.substring(res.name.lastIndexOf(".") + 1);const list = ["exe"]if (list.indexOf(fileSuffix) >= 0) {toast.error(list.toString() + '文件类型限制传入!')return false}if (res.size / 1024 / 1024 > 50) {toast.error('文件大小不能超过50MB!')return false}return true},//上传成功开始保存本条数据handleAvatarSuccess (res, file) {if (res.code == apiCode.Success) {let instance = {stationId: this.stationId,originalFileName: res.data.attachmentName,newFileName: res.data.fileName,Url: res.data.url,}this.$axios.post(ZlCustomeTimeFile.Save, instance).then(response => {let res = response.data;if (res.code == apiCode.Success) {this.getData()toast.success()} else {toast.error(res.msg)}})} else {toast.error(res.msg)}},
后端代码C#,aspnet core,接收文件并保存到服务器,然后返回文件信息:
[HttpPost]public async Task<ApiResult<ImageUploadResponse>> UploadFileAsync(List<IFormFile> file){if (file?.Count > 0){}else{return base.DoFail<ImageUploadResponse>(ApiCode.Fail, msg: $"上传文件失败,请选择文件");}var exMsg = "";var formFile = file[0];try{var filePath = $"/upload/";System.IO.Directory.CreateDirectory(_hostingEnvironment.WebRootPath + filePath);Random rd = new Random(); string FileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + rd.Next(100, 1000) + formFile.FileName.Substring(formFile.FileName.LastIndexOf(".") == -1 ? 0 : formFile.FileName.LastIndexOf("."));using (var stream = System.IO.File.Create(_hostingEnvironment.WebRootPath + filePath + FileName)){await formFile.CopyToAsync(stream);}var request = HttpContext.Request;return base.DoSuccess<ImageUploadResponse>(new ImageUploadResponse{Url = $"{request.Scheme}://{request.Host.Host}{(request.Host.Port == 80 ? "" : ":" + request.Host.Port)}" + filePath + FileName,FileName = FileName,AttachmentName = formFile.FileName,});}catch (Exception ex){exMsg = ex.Message;}return base.DoFail<ImageUploadResponse>(ApiCode.Fail, msg: $"上传文件失败,{exMsg}");}
2、静态a标签下载文件
<a target="_blank" :href="row.url">{{ row.originalFileName }}
<el-link :href="row.url">{{ row.originalFileName }}</el-link>
3、动态a标签下载文件,使用二进制流blob直接下载,可以修改文件名
<span style="cursor: pointer;" @click="down(row)">{{ row.originalFileName }}</span>
//路径转为相对路径,然后使用二进制流blob直接下载,可以修改文件名down (data) {var newurl = data.url.substring(data.url.indexOf("//") + 2)console.log(newurl)newurl = newurl.substring(newurl.indexOf("/"))console.log(newurl)const x = new XMLHttpRequest()x.open('GET', newurl, true)x.responseType = 'blob'x.onload = () => {const url = window.URL.createObjectURL(x.response)// 创建隐藏的可下载链接var eleLink = document.createElement('a');eleLink.download = data.originalFileName;eleLink.style.display = 'none';// 下载内容转变成blob地址eleLink.href = url;// 触发点击document.body.appendChild(eleLink);eleLink.click();// 然后移除document.body.removeChild(eleLink);}x.send()},
4、动态下载Excel文件,使用二进制流blob,前端vue2下载按钮事件,后端C#接口代码:
import { saveAs } from 'file-saver';downloadControllerAction (row) {var that = this;this.$axios.get(CustomeTimeFile.Download, {params: { id: row.id },responseType: 'blob'}).then(response => {console.log(response)if (response.status !== 200) {toast.error('下载失败');return;}const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });saveAs(blob, row.originalFileName); // 直接调用saveAs函数}).catch((error) => {console.log(error);let errorMessage = '';if (error instanceof Blob) {const reader = new FileReader();reader.onload = function (e) {try {const errorJson = JSON.parse(e.target.result);errorMessage = errorJson.message || '出现错误';} catch (err) {errorMessage = '下载错误,请重新下载.';}toast.error(errorMessage);};reader.readAsText(error);} else {errorMessage = error.message;console.error('出现错误:', errorMessage);toast.error(errorMessage);}});},
public async Task<IActionResult> Download([FromQuery] long id){var fileInfo = DapperContext.GetDatabase().Get<ZustomeTimeFile>(id);if (fileInfo == null || fileInfo.Url.IsNullOrEmpty()) return StatusCode(500, new { Message = "找不到文件,请重新上传统计" });var energylist = CustomeTimeEnergyRepository.GetListByFile(fileInfo.StationId, fileInfo.Id);var energydict = energylist.GroupBy(t => t.RowNumber).ToDictionary(t => t.Key, t => t.First());try{ byte[] fileBytes = null;var filePath = $"/upload/";var fileName = fileInfo.NewFileName;try{fileBytes = System.IO.File.ReadAllBytes(_hostingEnvironment.WebRootPath + filePath + fileName);}catch (Exception ex1){LogHelper.WriteInfo("读取文件异常," + ex1);return StatusCode(500, new { Message = "找不到已上传文件,请重新上传" });}// 从URL下载Excel文件到字节数组,内部网络权限设置,不允许从外网访问,改为直接从服务器下载//try//{// fileBytes = await HttpClientHelper.DownloadFileAsync(fileInfo.Url);//}//catch (Exception ex)//{// return StatusCode(500, new { Message = "找不到已上传文件,请重新上传" });//}// 使用NPOI解析Excel文件using (MemoryStream memoryStream = new MemoryStream(fileBytes, true)){IWorkbook workbook = null;// 确定文件格式并创建相应的工作簿对象if (fileInfo.Url.EndsWith(".xlsx")) workbook = new XSSFWorkbook(memoryStream);else if (fileInfo.Url.EndsWith(".xls")) workbook = new HSSFWorkbook(memoryStream);if (workbook != null){ISheet sheet = workbook.GetSheetAt(0);foreach (IRow row in sheet){if (energydict.ContainsKey(row.RowNum)){ICell cell = row.GetCell(5) ?? row.CreateCell(5);if (energydict[row.RowNum].ElectricityValue.HasValue){cell.SetCellValue((double)energydict[row.RowNum].ElectricityValue);}cell = row.GetCell(6) ?? row.CreateCell(6);if (energydict[row.RowNum].NaturalGasValue.HasValue){cell.SetCellValue((double)energydict[row.RowNum].NaturalGasValue);}cell = row.GetCell(7) ?? row.CreateCell(7);if (!energydict[row.RowNum].StatisticMessage.IsNullOrEmpty()){cell.SetCellValue(energydict[row.RowNum].StatisticMessage);}}}}using (var stream = new MemoryStream()){workbook.Write(stream);workbook.Close();stream.Flush();// 设置响应头以提示浏览器下载文件return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileInfo.OriginalFileName);}}}catch (Exception ex){return StatusCode(500, new { Message = "出现异常:" + ex.Message });}}}
5、读取Excel文件,NPOI方式
public async Task<ApiResult> Save(CustomeTimeFile instance){instance.UploadTime = DateTime.Now;instance.DateCode = instance.UploadTime.ToDateCode();instance.IsStatistic = 0;instance.UploaderName = CurrentUser.RealName;var id = DapperContext.GetDatabase().Insert(instance);if (id > 0){var list = new List<CustomeTimeEnergy>();try{// 从URL下载Excel文件到字节数组,旧版本从下载链接直接读取,但是网络权限网关限制不允许外网读取,修改为直接读取文件//byte[] fileBytes = await HttpClientHelper.DownloadFileAsync(instance.Url);var filePath = $"/upload/";var fileName = instance.NewFileName;byte[] fileBytes = new byte[0];try{fileBytes = System.IO.File.ReadAllBytes(_hostingEnvironment.WebRootPath + filePath + fileName);}catch (Exception ex1){LogHelper.WriteInfo("读取文件异常," + ex1);throw;}// 使用NPOI解析Excel文件using (MemoryStream memoryStream = new MemoryStream(fileBytes)){IWorkbook workbook = null;// 确定文件格式并创建相应的工作簿对象try{if (instance.Url.EndsWith(".xlsx")) workbook = new XSSFWorkbook(memoryStream);else if (instance.Url.EndsWith(".xls")) workbook = new HSSFWorkbook(memoryStream);}catch (Exception exx){LogHelper.WriteInfo($"读取到workbook异常={exx}");}if (workbook != null){ISheet sheet = workbook.GetSheetAt(0);foreach (IRow row in sheet){var rowNum = row.RowNum; // 使用 RowNum 属性获取行号var deviceName = row.Cells[0].StringCellValue;var startTime = row.Cells[1].DateCellValue;var endTime = row.Cells[3].DateCellValue;if (deviceName.IsNullOrEmpty() || startTime.HasValue == false || endTime.HasValue == false) continue;list.Add(new CustomeTimeEnergy(){StationId = instance.StationId,UploadFileId = (int)id,RowNumber = rowNum,ClassificationSubitemId = 0,ClassificationSubitemName = deviceName,StartTime = startTime,EndTime = endTime,CollectTime = startTime.Value.Date,IsStatistic = 0,DateCode = startTime.Value.ToDateCode(),RecordTime = instance.UploadTime,});}}workbook.Close();}CustomeTimeEnergyRepository.BatchInsert(list);}catch (Exception ex){DoFail($"保存失败:{ex.Message}");}return DoSuccess();}return DoFail("保存失败");}
相关文章:

C#与Vue2上传下载Excel文件
1、上传文件流程:先上传文件,上传成功,返回文件名与url,然后再次发起请求保存文件名和url到数据库 前端Vue2代码: 使用element的el-upload组件,action值为后端接收文件接口,headers携带session信…...

Linux(Centos7)安装Mysql/Redis/MinIO
安装Mysql 安装Redis 搜索Redis最先版本所在的在线安装yum库 查看以上两个组件是否是开机自启 安装MinIO 开源的对象存储服务,存储非结构化数据,兼容亚马逊S3协议。 minio --help #查询命令帮助minio --server --help #查询--server帮助minio serve…...

港科夜闻 | 香港科大与微软亚洲研究院签署战略合作备忘录,推动医学健康教育及科研协作...
关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大与微软亚洲研究院签署战略合作备忘录,推动医学健康教育及科研协作。根据备忘录,双方将结合各自于科研领域的优势,携手推动医学健康领域的交流与合作。合作方向将涵盖人才培训、…...

森林网络部署,工业4G路由器实现林区组网远程监控
在广袤无垠的林区,每一片树叶的摇曳、每一丝空气的流动,都关乎着生态的平衡与安宁。林区监控正以强大的力量,为这片绿色家园筑起一道坚固的防线。 工业 4G 路由器作为林区监控组网的守护者,凭借着卓越的通讯性能,突破…...

ASP.NET Core - 配置系统之自定义配置提供程序
ASP.NET Core - 配置系统之自定义配置提供程序 4. 自定义配置提供程序IConfigurationSourceIConfigurationProvider 4. 自定义配置提供程序 在 .NET Core 配置系统中封装一个配置提供程序关键在于提供相应的 IconfigurationSource 实现和 IConfigurationProvider 接口实现&…...

npm、yarn、pnpm包安装器差异性对比
特性npmyarnpnpm发布年份2010 年发布2016 年发布2017 年发布安装速度较慢(旧版本),但自 npm 5 后有所改善较快,尤其是在缓存方面极快,使用硬链接和全局缓存来提高速度包管理模式扁平化依赖,可能会发生重复依…...

正点原子repo放到自己的git服务器
atk-rk3568_android11 导出project-objects对应仓库 .repo/repo/repo list -n > project-object.txt将project-object.txt格式化,并通过gitolite.conf创建对应仓库 atk-rk3568_android11_repo atk-rk3568_android11/RKTools atk-rk3568_android11_repo atk-…...

[MySQL | 二、基本数据类型]
基本数据类型 一、数值类型举例表结构1. 整数类型zerofill属性 与 int(n) 中 n 的关系 2.bit类型3. 小数类型float类型decimal类型 二、字符串类型1. char2. varchar如何选择定长或变长字符串? 3. 日期时间类型(date datetime timestamp)4. enum枚举类型5. set多选类…...

工作记录小点
postman问题 postman 返回404 可以先看看这个模块是否集成到pom文件中 postman 返回200不调debug 请求参数Json有错误请求方式不对Get/Post debug报错连接失败 host文件没copy同事的 2.对应组件的不同服务白名单没添加导致的 host文件刷新 进入 C:\windows\system32\drivers\e…...

在PyCharm中使用Anaconda中的虚拟环境
1、在File菜单中找到Settings 2、Settings中搜索interpreter,找到Python Interpreter,再点击Add 3、选择第一个local interpreter 4、如图: 5、找到anaconda安装位置中的envs文件夹,在里面选择需要添加的python环境,如…...

ansible基础
ansible 1.概述 ansible是基于python语言开发,配置管理和部署应用的工具。批量的配置,部署,管理“上千台”主机 (实际一次100台左右),ansible只要在一台主机上就可以对其他主机进行操作。 (1&…...

人工智能之深度学习_[2]-PyTorch入门
PyTorch 1.PyTorch简介 1.1 什么是PyTorch PyTorch是一个基于Python的科学计算包 PyTorch安装 pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simplePyTorch一个基于Python语言的深度学习框架,它将数据封装成张量(Tensor)来进行…...

基于Java的语音陪聊软件——支持聊天私聊-礼物系统-直播系统-缘分匹配-游戏陪玩
丰富的经验、成熟的技术,打造适合当下市场发展的语音交友软件源码。Java 语言凭借其独特的优势,为这款语音陪聊软件的稳健运行和持续发展奠定了坚实基础。它不仅融合了聊天私聊、礼物系统和直播系统等实用且有趣的功能,还创新性地引入了缘分匹…...

Go语言的文件操作
Go语言的文件操作 Go语言是一种开源的编程语言,由谷歌开发,具有简单、高效和并发的特点。在日常开发中,文件操作是一个非常重要且常见的任务。从读取配置文件到写入日志文件,从处理数据到存储结果,文件操作无处不在。…...

php审计1-extract函数变量覆盖
php审计1-extract函数变量覆盖 这是一个关于php审计的栏目,本人也是初学者,分享一下网上的关于php审计的一些知识,学习一下php的语法,顺便记录一下学习过程。 以下是一个关于php审计ctf题 <?php$flagflag.txt; extract($_…...

百度热力图数据原理,处理及论文应用7
目录 0、数据简介0、示例数据1、百度热力图数据日期如何选择1.1、其他实验数据的时间1.2、看日历1.3、看天气 2、百度热力图几天够研究?部分文章统计3、数据原理3.1.1 ** 这个比较重要,后面还会再次出现。核密度的值怎么理解?**3.1.2 Csv->…...

端口镜像和端口安全
✍作者:柒烨带你飞 💪格言:生活的情况越艰难,我越感到自己更坚强;我这个人走得很慢,但我从不后退。 📜系列专栏:网络安全从菜鸟到飞鸟的逆袭 目录 一,端口镜像二…...

Elasticsearch:Jira 连接器教程第一部分
作者:来自 Elastic Gustavo Llermaly 将我们的 Jira 内容索引到 Elaasticsearch 中以创建统一的数据源并使用文档级别安全性进行搜索。 在本文中,我们将回顾 Elastic Jira 原生连接器的一个用例。我们将使用一个模拟项目,其中一家银行正在开发…...

ThreeJs功能演示——几何体操作导入导出
1、内部创建几何体导出编辑能力 1)支持内部创建的面、正方体、球体 内部创建物体时,如果是三维物体,要创建集合形状geometry,和对应的材质material。再一起创建一个三维物体。 // 存储创建的几何体列表const geometries [];cre…...

LeetCode::2270. 分割数组的方案数
2270. 分割数组的方案数 思路 前缀和 提示 给你一个下标从 0 开始长度为 n 的整数数组 nums 。 如果以下描述为真,那么 nums 在下标 i 处有一个 合法的分割 : 前 i 1 个元素的和 大于等于 剩下的 n - i - 1 个元素的和。下标 i 的右边 至少有一个 元…...

elementui表单验证,数据层级过深验证失效
先看示例代码,代码为模拟动态获取表单数据,然后动态添加rules验证规则,示例表单内输入框绑定form内第四层: <template><el-form :model"form" :rules"rules" ref"ruleForm" label-width&…...

【Java】LinkedHashMap (LRU)淘汰缓存的使用
文章目录 **1. initialCapacity(初始容量)****2. loadFactor(加载因子)****3. accessOrder(访问顺序)****完整参数解释示例****示例验证** LinkedHashMap 在 Java 中可维护元素插入或访问顺序,并…...

CancerGPT :基于大语言模型的罕见癌症药物对协同作用少样本预测研究
今天我们一起来剖析一篇发表于《npj Digital Medicine》的论文——《CancerGPT for few shot drug pair synergy prediction using large pretrained language models》。该研究聚焦于一个极具挑战性的前沿领域:如何利用大语言模型(LLMs)在数…...

《汽车维护与修理》是什么级别的期刊?是正规期刊吗?能评职称吗?
问题解答: 问:《汽车维护与修理》是不是核心期刊? 答:不是,是知网收录的正规学术期刊。 问:《汽车维护与修理》级别? 答:国家级。主管单位:中国汽车维修行业协会 …...

tomcat状态一直是Exited (1)
docker run -di -p 80:8080 --nametomcat001 你的仓库地址/tomcat:9执行此命令后tomcat一直是Exited(1)状态 解决办法: 用以下命令创建运行 docker run -it --name tomcat001 -p 80:8080 -d 你的仓库地址/tomcat:9 /bin/bash最终结果 tomcat成功启动...

消息中间件的基础概念入门
目录 一、什么是消息中间件 1.1、简介 1.2、消息中间件的主要作用 解耦合 异步通信 负载均衡 可靠性与持久性 消息路由与调度 削峰 事务支持 监控与审计 跨平台和跨语言支持 二、常用消息中间件对比 2.1、 RabbitMQ 2.1.1、特点 2.1.2、适用场景 2.2、Apache K…...

基于Web的宠物医院看诊系统设计与实现(源码+定制+开发)在线预约平台、宠物病历管理、医生诊疗记录、宠物健康数据分析 宠物就诊预约、病历管理与健康分析
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...

Excel数据叠加生成新DataFrame:操作指南与案例
目录 一、准备工作 二、读取Excel文件 三、数据叠加 四、处理重复数据(可选) 五、保存新DataFrame到Excel文件 六、案例演示 七、注意事项 八、总结 在日常数据处理工作中,我们经常需要将不同Excel文档中的数据整合到一个新的DataFrame中,以便进行进一步的分析和处…...

Web 开发入门之旅:从静态页面到全栈应用的第一步
Web 开发入门之旅:从静态页面到全栈应用的第一步 在当今互联网飞速发展的时代,掌握 Web 开发技能已成为众多技术爱好者和职场人士的必修课。然而,对于初学者而言,面对繁杂的技术栈和庞大的学习资源,往往感到无从下手。…...

WebSocket实现分布式的不同方案对比
引言 随着实时通信需求的日益增长,WebSocket作为一种基于TCP的全双工通信协议,在实时聊天、在线游戏、数据推送等场景中得到了广泛应用。然而,在分布式环境下,如何实现WebSocket的连接管理和消息推送成为了一个挑战。本文将对比几…...