C#使用EPPlus读写Excel

依赖EPPlus

获取依赖可以阅读:Nuget For Unity插件介绍_nugetforunity-CSDN博客


可以参阅该篇快速入门:在Unity中使用Epplus写Excel_unity epplus-CSDN博客


下面是我封装的几个方法:


要在合适的时机配置许可证,比如你的工具类的静态函数.建议使用版本7.7.1

  #region Excel封装,使用Eppluspublic class ExcelRowData{/// <summary>/// 来自那张表/// </summary>public string BelongSheetName { get; set; }/// <summary>/// 来自哪一行(从2开始,第一行为表头)/// </summary>public int RowNumber { get; set; }/// <summary>/// key=列名 value=数据/// </summary>public Dictionary<string, string> Data { get; set; }}#region 读/// <summary>/// 读取 Excel 文件,返回所有工作表的数据(含行号)/// </summary>public static Dictionary<string, List<ExcelRowData>> ReadExcelAllSheets(string filePath){if (!File.Exists(filePath))throw new FileNotFoundException("Excel 文件不存在", filePath);var result = new Dictionary<string, List<ExcelRowData>>();using (var package = new ExcelPackage(new FileInfo(filePath))){foreach (var worksheet in package.Workbook.Worksheets){var sheetData = ReadWorksheet(worksheet);result[worksheet.Name] = sheetData;}}return result;}/// <summary>/// 读取指定工作表的数据(含行号)/// </summary>public static List<ExcelRowData> ReadExcelSheet(string filePath, string sheetName){if (!File.Exists(filePath))throw new FileNotFoundException("Excel 文件不存在", filePath);using (var package = new ExcelPackage(new FileInfo(filePath))){var worksheet = package.Workbook.Worksheets[sheetName];if (worksheet == null)throw new ArgumentException($"未找到工作表:{sheetName}");return ReadWorksheet(worksheet);}}/// <summary>/// 读取单个工作表的数据(第一行为表头,返回包含行号的结构)/// </summary>private static List<ExcelRowData> ReadWorksheet(ExcelWorksheet worksheet){var result = new List<ExcelRowData>();if (worksheet.Dimension == null)return result;int rowCount = worksheet.Dimension.End.Row;int colCount = worksheet.Dimension.End.Column;var sheetName = worksheet.Name;// 读取表头var headers = new List<string>();for (int col = 1; col <= colCount; col++){var header = worksheet.Cells[1, col].Text.Trim();if (string.IsNullOrEmpty(header))throw new Exception($"表头第 {col} 列为空,请检查Excel文件格式。");headers.Add(header);}// 读取数据行for (int row = 2; row <= rowCount; row++){var rowDict = new Dictionary<string, string>();for (int col = 1; col <= colCount; col++){string cellValue = worksheet.Cells[row, col].Text.Trim();if (string.IsNullOrEmpty(cellValue))throw new Exception($"工作表 '{worksheet.Name}' 第 {row} 行,第 {col} 列({headers[col - 1]})单元格为空,请检查数据完整性。");string header = headers[col - 1];rowDict[header] = cellValue;}result.Add(new ExcelRowData { BelongSheetName = sheetName, RowNumber = row, Data = rowDict });}return result;}#endregion#region 写/// <summary>/// 将单张表的数据写入 Excel 文件(如果文件不存在会自动创建)/// </summary>/// <param name="sheetName">工作表名称,不能为空或空白</param>/// <param name="rows">该表的数据行列表,不能为空且至少包含一行数据</param>/// <param name="filePath">可选,指定输出文件路径。如果为 null 或空,则默认保存到桌面“Excel”目录下,并以当前时间戳+GUID命名文件</param>/// <exception cref="ArgumentException">当 sheetName 为空或 rows 为空时抛出异常</exception>public static void WriteExcelSingleSheet(string sheetName, List<ExcelRowData> rows, string filePath = null){if (string.IsNullOrWhiteSpace(sheetName))throw new ArgumentException("工作表名称不能为空", nameof(sheetName));if (rows == null || rows.Count == 0)throw new ArgumentException("数据不能为空", nameof(rows));string desktopExcelPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Excel");Directory.CreateDirectory(desktopExcelPath);if (string.IsNullOrWhiteSpace(filePath)){filePath = Path.Combine(desktopExcelPath, $"Excel_{DateTime.Now:yyyyMMdd_HHmmss}_{Guid.NewGuid()}.xlsx");}using (var package = new ExcelPackage(filePath)){var ws = package.Workbook.Worksheets.Add(sheetName);// 写表头var headers = rows[0].Data.Keys.ToList();for (int col = 0; col < headers.Count; col++){ws.Cells[1, col + 1].Value = headers[col];}// 写数据行for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++){var rowData = rows[rowIndex].Data;int excelRow = rowIndex + 2;int colIndex = 1;foreach (var header in headers){rowData.TryGetValue(header, out string cellValue);ws.Cells[excelRow, colIndex].Value = cellValue;colIndex++;}}package.Save();}}/// <summary>/// 将多个表的数据写入同一个 Excel 文件(如果文件不存在会自动创建)/// </summary>/// <param name="excelData">字典,key 为工作表名称,value 为对应的该表数据行列表,字典不能为空且至少含有一个表数据</param>/// <param name="filePath">可选,指定输出文件路径。如果为 null 或空,则默认保存到桌面“Excel”目录下,并以当前时间戳+GUID命名文件</param>/// <exception cref="ArgumentNullException">当 excelData 为 null 或为空时抛出异常</exception>public static void WriteExcelAllSheets(Dictionary<string, List<ExcelRowData>> excelData, string filePath = null){if (excelData == null || excelData.Count == 0)throw new ArgumentNullException(nameof(excelData));string desktopExcelPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Excel");Directory.CreateDirectory(desktopExcelPath);if (string.IsNullOrWhiteSpace(filePath)){filePath = Path.Combine(desktopExcelPath, $"Excel_{DateTime.Now:yyyyMMdd_HHmmss}_{Guid.NewGuid()}.xlsx");}using (var package = new ExcelPackage(filePath)){foreach (var sheetData in excelData){WriteSheetToPackage(sheetData.Key, sheetData.Value, package);}package.Save();}}private static void WriteSheetToPackage(string sheetName, List<ExcelRowData> rows, ExcelPackage package){if (string.IsNullOrWhiteSpace(sheetName))throw new ArgumentException("工作表名称不能为空", nameof(sheetName));if (rows == null || rows.Count == 0)throw new ArgumentException("数据不能为空", nameof(rows));var ws = package.Workbook.Worksheets.Add(sheetName);// 写表头var headers = rows[0].Data.Keys.ToList();for (int col = 0; col < headers.Count; col++){ws.Cells[1, col + 1].Value = headers[col];}// 写数据行for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++){var rowData = rows[rowIndex].Data;int excelRow = rowIndex + 2;int colIndex = 1;foreach (var header in headers){rowData.TryGetValue(header, out string cellValue);ws.Cells[excelRow, colIndex].Value = cellValue;colIndex++;}}}#endregion#endregion

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性能Web服务器

一、Web服务基础介绍 1.1、互联网发展历程 1993年3月2日&#xff0c;中国科学院高能物理研究所租用AT&T公司的国际卫星信道建立的接入美国SLAC国家实验室的64K专线正式开通&#xff0c;成为我国连入Internet的第一根专线。 1995年马云开始创业并推出了一个web网站中国黄…

《算法导论》第 16 章 - 贪心算法

大家好&#xff01;今天我们来深入探讨《算法导论》第 16 章的核心内容 —— 贪心算法。贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。它在许多优化问题中都有广泛应…

Redis面试精讲 Day 18:Redis网络优化与连接管理

【Redis面试精讲 Day 18】Redis网络优化与连接管理 开篇 欢迎来到"Redis面试精讲"系列第18天&#xff0c;今天我们将深入探讨Redis网络优化与连接管理技术。在分布式系统中&#xff0c;Redis的网络性能和连接管理直接影响整个系统的响应速度和稳定性。掌握这些优化…

Centos8系统在安装Git包时,报错:“没有任何匹配: git”

报错类型&#xff1a; sudo dnf install git Repository AppStream is listed more than once in the configuration Repository BaseOS is listed more than once in the configuration Repository extras is listed more than once in the configuration Repository fasttrac…

glide缓存策略和缓存命中

一 缓存策略 1 Glide 的 diskCacheStrategy() 一共有 5 种枚举值&#xff08;DiskCacheStrategy&#xff09;&#xff0c;每种的作用和区别如下&#xff1a;1. DiskCacheStrategy.ALL 作用&#xff1a;同时缓存原始图片&#xff08;原图数据&#xff09;和经过变换&#xff08;…

如何将PDF文档进行高效编辑处理!

PDF文件可以在任何设备上以相同的格式查看&#xff0c;无论操作系统或软件环境如何&#xff0c;可以确保修改后的文档仍然保持原有的布局和格式。它完全免费&#xff0c;下载后双击即可运行&#xff0c;无需安装&#xff0c;使用非常方便。它具备出色的文本编辑功能&#xff0c…

应用层模拟面试题

模拟面试-C第一题(开发音视频处理模块)在开发音视频处理模块时&#xff0c;FFmpeg资源&#xff08;AVFrame*&#xff09;需要自动释放。如何用unique_ptr定制删除器替代手动av_frame_free()&#xff1f;写出代码并解释RAII优势。参考答案&#xff1a;auto frame_deleter[](AVFr…

分享一款基于STC8H8K32U-45I-LQFP48单片机的4路数字量输入输出模块

4路数字量输入输出模块产品说明产品特性输入部分&#xff1a; 4路光耦隔离数字量输入通道支持NPN和PNP两种输入方式&#xff0c;可通过拨码开关切换输入电压范围&#xff1a;10-30VDC典型应用&#xff1a;可连接按钮开关、接近开关、光电传感器等数字信号设备输出部分&#xff…

redis常见的性能问题

Redis 的性能问题通常源于配置不当、数据结构误用、资源瓶颈或架构缺陷。以下是 Redis 常见的性能问题及优化方案&#xff0c;结合线上经验整理&#xff1a;&#x1f9e0; ​一、内存相关问题​​1. 内存不足&#xff08;OOM&#xff09;​​​现象​&#xff1a;OOM errors、响…

Blender 基础操作

基础操作 一、视角控制 ①旋转视角 &#xff1a; 拖动鼠标中键 ②平移视角 &#xff1a; shift 鼠标中键 ③放大\缩小 &#xff1a;鼠标滚轮 二、物体控制 1、重要 ① 移动物体 : G ② 旋转物体 : R ③ 缩放物体 : S 2、不重要 ④ 新建物体 : shift A ⑤ 复制物体 : shift D…

Go 语言三大核心数据结构深度解析:数组、切片(Slice)与映射(Map)

&#x1f680;Go 语言三大核心数据结构深度解析&#xff1a;数组、切片&#xff08;Slice&#xff09;与映射&#xff08;Map&#xff09; 在 Go 语言的开发领域&#xff0c;数组、切片与映射 这三大核心数据结构犹如构建程序的基石&#xff0c;支撑着各类数据的存储与处理。它…

《Webpack与Vite热模块替换机制深度剖析与策略抉择》

从早期简单的文件合并工具,到如今功能强大、高度自动化的Webpack和Vite,它们重塑了前端开发的流程与效率。而热模块替换(HMR, Hot Module Replacement)机制,作为其中关键的一环,更是成为开发者提升开发体验、加速项目迭代的秘密武器。Webpack,作为前端构建领域的先驱者,…

虚拟乐队“天鹅绒落日”:AI生成音乐引发的行业风暴

引言近日&#xff0c;音乐行业掀起了一阵关于一支名为“The Velvet Sundown”&#xff08;天鹅绒落日&#xff09;乐队的新闻热潮。原因何在&#xff1f;这支乐队很可能并非真正的乐队&#xff0c;其音乐也或许是由人工智能生成的。事实上&#xff0c;越来越多的共识认为&#…

c++ final override 关键字

1.finalfinal 防止子类继承&#xff0c;用于类或虚函数&#xff0c;限制继承或重写class Base final {}; // Base类不能被继承class Base { public:virtual void foo() final; // 禁止子类重写foo() };2.overrideoverride 子类中重写父类中函数&#xff0c;&#xff0c;仅用于…

剑桥大学最新研究:基于大语言模型(LLM)的分子动力学模拟框架,是MD的GPT时刻还是概念包装?

近期&#xff0c;剑桥大学 Michele Vendruscolo 团队在预印本平台上发布了一项最新研究&#xff0c;提出了一个名为 MD-LLM 的框架&#xff0c;旨在为高效研究蛋白质动态提供一种全新的思路。简单来说&#xff0c;他们希望借助大语言模型&#xff08;LLM&#xff09;&#xff0…

MySQL梳理:其他

MySQL数据库技术知识合集&#xff0c;涵盖InnoDB存储引擎的区管理机制、缓冲池机制等核心技术要点。本文档将持续补充MySQL相关的重要技术知识点。 &#x1f4cb; 目录 模块一&#xff1a;InnoDB区状态管理机制 1.1 核心设计思想1.2 四种区状态详解1.3 渐进式空间分配策略1.4…

影刀 —— 飞书电子表格

以获取列上第一个可用行为例我们需要获取的分别是 凭证 和 表格唯一标识首先来看如何获取凭证在飞书开发者后台创建应用然后添加权限发版拿App ID 和 App Secret下面来创建电子表格&#xff01;&#xff01;&#xff01;注意这个表格一定不要创建到知识库里面如果创建到知识库里…

1.二维图像处理(完整版)

目录 1.变换矩阵 2.在矩阵的基础上添加各种变换形式 3.开始变换 4.计算变换矩阵参数 新算子 二、阈值分割 新算子 三、blob分析案例 1.焊点 2.石头 3.木材 4.车牌 5.骰子 新算子 四、傅里叶变换频域分析 问题一 五、滤波处理 1.均值滤波 2.中值滤波 3.高斯…

【linux基础】Linux 文本处理核心命令指南

Linux 文本处理核心命令指南 文本处理是 Linux 系统管理的核心能力&#xff0c;约 80% 的配置文件操作都依赖于文本处理技术。本指南详细讲解 echo、重定向、cat、grep、wc 和 vim 等关键命令&#xff0c;涵盖从基础操作到高级技巧的完整知识体系&#xff0c;并配有实用案例演示…

基于深度学习YOLOv12的草莓成熟度检测系统(YOLOv12+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)https://www.bilibili.com/video/BV1

一、项目介绍 本项目构建了一套基于深度学习 YOLOv12 的草莓成熟度识别检测系统&#xff0c;旨在实现对草莓在不同成熟阶段的高精度、实时检测与分类。系统采用 YOLO 格式数据集&#xff0c;将草莓分为 3 个类别&#xff1a;生&#xff08;raw&#xff09;、半熟&#xff08;tu…