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

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.xdnf.cn/news/17620.html

相关文章:

  • ubuntu20.04交叉编译vlc3.0.21 x64 windows版本
  • 大模型落地:AI 技术重构工作与行业的底层逻辑
  • Pytest 全流程解析:执行机制与报告生成实战指南
  • java 插入式注解的打开方式!
  • MySQL,Redis重点面试题
  • SQL179 每个6/7级用户活跃情况
  • Spring Framework源码解析——BeanPostProcessor
  • 【学习嵌入式day-22-Linux软件编程-IO】
  • SpringBoot集成支付宝二维码支付接口详解
  • Python3.10 + Firecrawl 下载 Markdown 文档:构建高效通用文章爬虫
  • 不同FPGA开发板系统移植步骤
  • Chrome插件开发【Service Worker练手小项目】
  • 【LeetCode刷题集】--排序(三)
  • 【智能的起源】人类如何模仿,简单的“刺激-反应”机制 智能的核心不是记忆,而是发现规律并能迁移到新场景。 最原始的智能:没有思考,只有简单条件反射
  • Mamba 原理汇总2
  • AI(2)-神经网络(激活函数)
  • 支持小语种的在线客服系统,自动翻译双方语言,适合对接跨境海外客户
  • 数据结构-数组扩容
  • 开发指南130-实体类的主键生成策略
  • Apache ECharts 6 核心技术解密 – Vue3企业级可视化实战指南
  • 排错000
  • 基于 ZooKeeper 的分布式锁实现原理是什么?
  • windows上RabbitMQ 启动时报错:发生系统错误 1067。 进程意外终止。
  • 150V降压芯片DCDC150V100V80V降压12V5V1.5A车载仪表恒压驱动H6203L惠洋科技
  • git:分支
  • 提示词工程实战:用角色扮演让AI输出更专业、更精准的内容
  • 软件测评中HTTP 安全头的配置与测试规范
  • 数据变而界面僵:Vue/React/Angular渲染失效解析与修复指南
  • 基于 Axios 的 HTTP 请求封装文件解析
  • Console Variables Editor插件使用