摘要
EPPlus 是一个流行的用于操作 Excel 文件的开源库,适用于 C# 和 .NET 环境。它提供了丰富的功能,能够轻松地读取、写入和格式化 Excel 文件,使得在 C# 中进行 Excel 文件处理变得更加简单和高效。EPPlus 不需要安装 Microsoft Office 或 Excel,因为它完全是用 C# 编写的,并且直接操作 Excel 文件的数据。
支持 Excel 文件格式:EPPlus 支持读取和写入 Office Open XML (XLSX) 格式的 Excel 文件,这是 Microsoft Excel 2007 及以后版本的默认文件格式。它不支持旧的二进制格式(XLS)
正文
EPPlus 是在 MIT 许可下发布的开源项目,因此你可以免费使用和修改它,也可以将其用于商业项目。它的源代码也是公开可用的,你可以自由查看和学习其中的实现细节。
Nuget 安装epplus,这里版本选上我基本就是5.0以前的够用了。

Announcement: This is the last version of EPPlus under the LGPL License
EPPlus will from version 5 be licensed under the Polyform Noncommercial 1.0.0 license.
With the new license EPPlus is still free to use in some cases, but will require a commercial license to be used in a commercial business.
More information on the license change on our website
常用方法:
Load:将已有的 Excel 文件加载到 ExcelPackage 对象中。
ExcelPackage package = new ExcelPackage();package.Load(FileInfo file);
Save:保存ExcelPackage对象到文件或流。
package.SaveAs(FileInfo file);package.SaveAs(Stream stream);
获取值:获取单元格的值。
object value = worksheet.Cells[row, column].Value;
设置值:设置单元格的值。
worksheet.Cells[row, column].Value = value;
常用属性:
获取 ExcelWorkbook 对象,表示工作簿。
ExcelWorkbook workbook = package.Workbook;
工作表:获取工作簿中的工作表集合。
ExcelWorksheets worksheets = workbook.Worksheets;
单元格:获取工作表中的单元格集合。
ExcelRange cells = worksheet.Cells;
值:获取或设置单元格的值。
object value = cell.Value;cell.Value = value;
地址:获取单元格或范围的地址。
string address = cell.Address;
先做一个导入的例子

导入这样一个全国的省市信息
private void Import(){lsvMain.Items.Clear();string filePath = "./地区.xlsx";// 检查文件是否存在if (!File.Exists(filePath)){MessageBox.Show($"文件没有找到{filePath}");return;}// 使用 EPPlus 打开 Excel 文件using (var package = new ExcelPackage(new FileInfo(filePath))){// 获取工作表// 可以用Sheet的索引package.Workbook.Worksheets[0];// 也可用Sheet名字ExcelWorksheet worksheet = package.Workbook.Worksheets["Sheet1"];// 获取工作表的行数和列数,在实际工作中,用户给的excel不规范,// 可能需要通过固定列数,行数通过某些列为空判断结束int rowCount = worksheet.Dimension.Rows;int columnCount = worksheet.Dimension.Columns;// 读取数据并显示在控制台上// 这个因为有行头,从第二行开始for (int row = 2; row <= rowCount; row++){ListViewItem item = new ListViewItem();item.Text= worksheet.Cells[row, 1].Value.ToString();for (int col = 2; col <= columnCount; col++){var cellValue = worksheet.Cells[row, col].Value;item.SubItems.Add(cellValue==null?"": cellValue.ToString());}lsvMain.Items.Add(item);}}for (int i = 0; i < lsvMain.Columns.Count; i++){lsvMain.Columns[i].Width = -2;//宽度按内容计算}}
注:行与列的有效判断是个问题,再有就是行列都是从1开始,不像C#中其它基本是0开始索引。

导出Excel
先修改一下导入,需要将数据保存到List中
在导入时,增加
areas.Add(new Area{id = int.Parse(item.Text),type = int.Parse(item.SubItems[1].Text),parent_id = int.Parse(item.SubItems[2].Text),name = item.SubItems[3].Text});public class Area{public int id { get; set; }public int type { get; set; }public int parent_id { get; set; }public string name { get; set; }}private void btnExport_Click(object sender, EventArgs e){//找出所有省var provinces = areas.Where(x => x.type == 2);var citys = from t in provincesfrom c in areaswhere c.type == 3 && c.parent_id == t.idselect new{province = t.name,city = c.name} into bgroup b by new { province = b.province } into gselect new{province = g.Key.province,qty = g.Count()};// 使用模板string templatePath = "./统计城市.xlsx";// 找开模板文件FileInfo templateFile = new FileInfo(templatePath);//另存的文件string strDesFileName = "./" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";FileInfo desFile = new FileInfo(strDesFileName);// 载入到packageusing (ExcelPackage package = new ExcelPackage(desFile,templateFile)){//找到sheetExcelWorksheet worksheet = package.Workbook.Worksheets["Sheet1"];int row = 2;foreach (var item in citys.ToList()){worksheet.Cells[row, 1].Value = item.province;worksheet.Cells[row, 2].Value = item.qty;row++;}package.Save();}}

注意,导出有几个技巧,一般我们都是有导出模板,而且有可以有一些公式在Excel中,可用worksheet.Calculate(),激活公式。