摘要
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 provinces
from c in areas
where c.type == 3 && c.parent_id == t.id
select new
{
province = t.name,
city = c.name
} into b
group b by new { province = b.province } into g
select 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);
// 载入到package
using (ExcelPackage package = new ExcelPackage(desFile,templateFile))
{
//找到sheet
ExcelWorksheet 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(),激活公式。