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("保存失败");
        }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp区域滚动——上划进行分页加载数据(详细教程)

##标题 用来总结和学习&#xff0c;便于自己查找 文章目录 一、为什么scroll-view?          1.1 区域滚动页面滚动&#xff1f;          1.2 代码&#xff1f; 二、分页功能&#xff1f;          2.1 如何实现&#xff…

【Git版本控制器--1】Git的基本操作--本地仓库

目录 初识git 本地仓库 认识工作区、暂存区、版本库 add操作与commit操作 master文件与commit id 修改文件 版本回退 撤销修改 删除文件 初识git Git 是一个分布式版本控制系统&#xff0c;主要用于跟踪文件的更改&#xff0c;特别是在软件开发中。 为什么要版本…

【STM32-学习笔记-7-】USART串口通信

文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode…

Spring MVC简单数据绑定

【图书介绍】《SpringSpring MVCMyBatis从零开始学&#xff08;视频教学版&#xff09;&#xff08;第3版&#xff09;》_springspringmvcmybatis从零开始 代码、课件、教学视频与相关软件包下载-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)&#xff08;第3版&…

初识JVM HotSopt 的发展历程

目录 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 各大 JVM look 看一下虚拟机 HotSopt 的发展历程 总结 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 即时编译 主要是…

【pytorch】注意力机制-1

1 注意力提示 1.1 自主性的与非自主性的注意力提示 非自主性提示&#xff1a; 可以简单地使用参数化的全连接层&#xff0c;甚至是非参数化的最大汇聚层或平均汇聚层。 自主性提示 注意力机制与全连接层或汇聚层区别开来。在注意力机制的背景下&#xff0c;自主性提示被称为查…

大数据技术Kafka详解 ⑤ | Kafka中的CAP机制

目录 1、分布式系统当中的CAP理论 1.1、CAP理论 1.2、Partitiontolerance 1.3、Consistency 1.4、Availability 2、Kafka中的CAP机制 C软件异常排查从入门到精通系列教程&#xff08;核心精品专栏&#xff0c;订阅量已达600多个&#xff0c;欢迎订阅&#xff0c;持续更新…

ESP-IDF学习记录(5) 画一块esp32-c3 PCB板

最近看了半个多月&#xff0c;趁着嘉立创官方活动&#xff0c;研究esp32-c3规格书&#xff0c;白嫖PCB 和元器件。原本计划按照官方推荐的搞个四层板&#xff0c;结果打样太贵&#xff0c;火速改成双层板&#xff0c;用了官方的券。小于10*10,也可以使用嘉立创的免费打样。 下面…

nginx 实现 正向代理、反向代理 、SSL(证书配置)、负载均衡 、虚拟域名 ,使用其他中间件监控

我们可以详细地配置 Nginx 来实现正向代理、反向代理、SSL、负载均衡和虚拟域名。同时&#xff0c;我会介绍如何使用一些中间件来监控 Nginx 的状态和性能。 1. 安装 Nginx 如果你还没有安装 Nginx&#xff0c;可以通过以下命令进行安装&#xff08;以 Ubuntu 为例&#xff0…

Netty 入门学习

前言 学习Spark源码绕不开通信&#xff0c;Spark通信是基于Netty实现的&#xff0c;所以先简单学习总结一下Netty。 Spark 通信历史 最开始: Akka Spark 1.3&#xff1a; 开始引入Netty&#xff0c;为了解决大块数据&#xff08;如Shuffle&#xff09;的传输问题 Spark 1.6&…

鸿蒙报错Init keystore failed: keystore password was incorrect

报错如下&#xff1a; > hvigor ERROR: Failed :entry:defaultSignHap... > hvigor ERROR: Tools execution failed. 01-13 16:35:55 ERROR - hap-sign-tool: error: Init keystore failed: keystore password was incorrect * Try the following: > The key stor…

IDEA的Git界面(ALT+9)log选项不显示问题小记

IDEA的Git界面ALT9 log选项不显示问题 当前问题idea中log界面什么都不显示其他选项界面正常通过命令查询git日志正常 预期效果解决办法1. 检查 IDEA 的 Git 设置2. 刷新 Git Log (什么都没有大概率是刷新不了)3. 检查分支和日志是否存在4. 清理 IDEA 缓存 (我用这个成功解决)✅…

ffmpeg硬件编码

使用FFmpeg进行硬件编码可以显著提高视频编码的性能&#xff0c;尤其是在处理高分辨率视频时。硬件编码利用GPU或其他专用硬件&#xff08;如Intel QSV、NVIDIA NVENC、AMD AMF等&#xff09;来加速编码过程。以下是使用FFmpeg进行硬件编码的详细说明和示例代码。 1. 硬件编码支…

65.在 Vue 3 中使用 OpenLayers 绘制带有箭头的线条

前言 在现代的前端开发中&#xff0c;地图已经成为许多项目的核心功能之一。OpenLayers 是一个强大的开源地图库&#xff0c;它提供了丰富的功能和高度的定制化支持。在本篇文章中&#xff0c;我将向大家展示如何在 Vue 3 中使用 OpenLayers 绘制带有箭头的线条。 我们将实现…

C++内存泄露排查

内存泄漏是指程序动态分配的内存未能及时释放&#xff0c;导致系统内存逐渐耗尽&#xff0c;最终可能造成程序崩溃或性能下降。在C中&#xff0c;内存泄漏通常发生在使用new或malloc等分配内存的操作时&#xff0c;但没有正确地使用delete或free来释放这块内存。 在日常开发过程…

Ubuntu上,ffmpeg如何使用cuda硬件解码、编码、转码加速

本文使用 Ubuntu 环境。Ubuntu 直接使用 APT 安装的就支持 CUDA 加速。本文使用这样下载的版本进行演示&#xff0c;你自己编译或者其他源的版本可能会不同。 ffmpeg 的一些介绍&#xff0c;以及 macOS 版本的 ffmpeg 硬件加速请见《macOS上如何安装&#xff08;不需要编译安装…

linux: 文本编辑器vim

文本编辑器 vi的工作模式 (vim和vi一致) 进入vim的方法 方法一:输入 vim 文件名 此时左下角有 "文件名" 文件行数,字符数量 方法一: 输入 vim 新文件名 此时新建了一个文件并进入vim,左下角有 "文件名"[New File] 灰色的长方形就是光标,输入文字,左下…

调用企业微信新建日程 API 报 api forbidden 的解决方案

报错详细信息&#xff1a; {"errcode":48002,"errmsg":"api forbidden, hint: [1266719663513970651415782], from ip: xxx.xxx.xxx.xxx, more info at https://open.work.weixin.qq.com/devtool/query?e48002" } 解决方案&#xff1a; 1. 登…

rtthread学习笔记系列(4/5/6/7/15/16)

文章目录 4. 杂项4.1 检查是否否是2的幂 5. 预编译命令void类型和rt_noreturn类型的区别 6.map文件分析7.汇编.s文件7.1 汇编指令7.1.1 BX7.1.2 LR链接寄存器7.1.4 []的作用7.1.4 简单的指令 7.2 MSR7.3 PRIMASK寄存器7.4.中断启用禁用7.3 HardFault_Handler 15 ARM指针寄存器1…

微软与腾讯技术交锋,TRELLIS引领3D生成领域多格式支持新方向

去年 11 月&#xff0c;腾讯推出 Hunyuan3D 生成模型&#xff0c;是业界首个同时支持文字和图像生成 3D 的开源大模型。紧接着不到一个月&#xff0c;微软便发布了全新框架 TRELLIS&#xff0c;加入 3D 资产生成领域的竞争中。TRELLIS 支持多格式输出&#xff0c;包括辐射场、3…