C# 高效操作excel文件

C#高效操作Excel文件指南

一、主流Excel处理方案对比

方案 类型 特点 适用场景
​EPPlus​ 第三方库 功能全面,性能好,支持.xlsx 复杂Excel操作,大数据量
​NPOI​ 第三方库 支持.xls和.xlsx,功能全面 兼容旧版Excel文件
​ClosedXML​ 第三方库 基于OpenXML,API简单 简单报表生成
​Microsoft.Office.Interop.Excel​ COM组件 功能最全,但性能差 必须使用Excel功能的场景
​OpenXML SDK​ 微软官方 底层API,性能好 需要精细控制Excel结构
​GemBox.Spreadsheet​ 商业库 性能极佳,功能全面 企业级高性能需求

二、EPPlus使用指南(推荐)

1. 安装与配置

cs 复制代码
dotnet add package EPPlus

​注意​​:EPPlus从5.0版本开始需要许可证(免费版有功能限制)

2. 基础操作

​创建工作簿​​:

cs 复制代码
using OfficeOpenXml;

// 创建新工作簿
var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1");

// 写入数据
worksheet.Cells["A1"].Value = "姓名";
worksheet.Cells["B1"].Value = "年龄";
worksheet.Cells["A2"].Value = "张三";
worksheet.Cells["B2"].Value = 25;

// 保存文件
FileInfo file = new FileInfo("output.xlsx");
package.SaveAs(file);

​读取Excel文件​​:

cs 复制代码
using (var package = new ExcelPackage(new FileInfo("input.xlsx")))
{
    var worksheet = package.Workbook.Worksheets[0];
    int rowCount = worksheet.Dimension.Rows;
    int colCount = worksheet.Dimension.Columns;
    
    for (int row = 1; row <= rowCount; row++)
    {
        for (int col = 1; col <= colCount; col++)
        {
            var cellValue = worksheet.Cells[row, col].Value;
            Console.Write($"{cellValue}\t");
        }
        Console.WriteLine();
    }
}

3. 高效批量操作

​批量写入数据​​:

cs 复制代码
// 准备数据
var data = new List<Person>
{
    new Person { Name = "张三", Age = 25 },
    new Person { Name = "李四", Age = 30 }
};

// 批量写入
worksheet.Cells["A2"].LoadFromCollection(data, true, OfficeOpenXml.Table.TableStyles.Light1);

​使用Range批量操作​​:

cs 复制代码
// 设置样式
using (var range = worksheet.Cells["A1:B1"])
{
    range.Style.Font.Bold = true;
    range.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
    range.Style.Fill.BackgroundColor.SetColor(Color.LightBlue);
}

// 批量设置值
worksheet.Cells["A2:A3"].Value = new object[] { "张三", "李四" };
worksheet.Cells["B2:B3"].Value = new object[] { 25, 30 };

4. 高级功能

​公式计算​​:

cs 复制代码
worksheet.Cells["C2"].Formula = "A2+B2";
worksheet.Calculate(); // 手动计算
var result = worksheet.Cells["C2"].Value; // 获取计算结果

​图表创建​​:

cs 复制代码
var chart = worksheet.Drawings.AddChart("Chart1", eChartType.ColumnClustered);
chart.SetPosition(1, 0, 3, 0);
chart.SetSize(600, 400);
chart.Series.Add(worksheet.Cells["B2:B3"], worksheet.Cells["A2:A3"]);

​数据验证​​:

cs 复制代码
var validation = worksheet.DataValidations.AddListValidation("D2");
validation.Formula.Values.Add("选项1");
validation.Formula.Values.Add("选项2");
validation.Formula.Values.Add("选项3");

三、NPOI使用指南(兼容旧版Excel)

1. 安装与配置

cs 复制代码
dotnet add package NPOI
dotnet add package NPOI.OOXML

2. 基础操作

​创建Excel文件​​:

cs 复制代码
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

// 创建工作簿
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");

// 创建行和单元格
IRow row = sheet.CreateRow(0);
ICell cell = row.CreateCell(0);
cell.SetCellValue("姓名");

row = sheet.CreateRow(1);
cell = row.CreateCell(0);
cell.SetCellValue("张三");

​读取Excel文件​​:

cs 复制代码
using (var fileStream = new FileStream("input.xlsx", FileMode.Open, FileAccess.Read))
{
    IWorkbook workbook = new XSSFWorkbook(fileStream);
    ISheet sheet = workbook.GetSheetAt(0);
    
    for (int i = 0; i <= sheet.LastRowNum; i++)
    {
        IRow row = sheet.GetRow(i);
        if (row != null)
        {
            for (int j = 0; j < row.LastCellNum; j++)
            {
                ICell cell = row.GetCell(j);
                Console.Write($"{cell?.ToString()}\t");
            }
            Console.WriteLine();
        }
    }
}

3. 高效操作技巧

​样式复用​​:

cs 复制代码
ICellStyle style = workbook.CreateCellStyle();
style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.LightBlue.Index;
style.FillPattern = FillPattern.SolidForeground;

// 复用样式
for (int i = 0; i < 10; i++)
{
    IRow row = sheet.CreateRow(i);
    ICell cell = row.CreateCell(0);
    cell.CellStyle = style;
    cell.SetCellValue($"数据{i}");
}

​大数据量处理​​:

cs 复制代码
// 使用临时文件处理大数据
using (var fs = new FileStream("large.xlsx", FileMode.Create, FileAccess.Write))
{
    workbook.Write(fs);
}

四、ClosedXML使用指南(简单报表)

1. 安装与配置

复制代码
dotnet add package ClosedXML

2. 基础操作

​创建工作簿​​:

cs 复制代码
using ClosedXML.Excel;

var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sheet1");

// 写入数据
worksheet.Cell(1, 1).Value = "姓名";
worksheet.Cell(2, 1).Value = "张三";

// 保存文件
workbook.SaveAs("output.xlsx");

​高级格式化​​:

cs 复制代码
// 设置字体和颜色
worksheet.Cell(1, 1).Style.Font.Bold = true;
worksheet.Cell(1, 1).Style.Font.FontColor = XLColor.Red;

// 合并单元格
worksheet.Range(1, 1, 1, 3).Merge().SetValue("合并单元格示例");

// 添加条件格式
worksheet.Cell(2, 1).AddConditionalFormat()
    .WhenEquals("张三")
    .Fill.SetBackgroundColor(XLColor.LightGreen);

五、性能优化技巧

1. 减少内存占用

​EPPlus优化​​:

cs 复制代码
// 使用流式处理大数据
using (var package = new ExcelPackage())
{
    var worksheet = package.Workbook.Worksheets.Add("Sheet1");
    
    // 分批写入数据
    for (int i = 0; i < 100000; i++)
    {
        worksheet.Cells[i+1, 1].Value = $"数据{i}";
        
        // 每1000行刷新一次
        if (i % 1000 == 0)
        {
            package.Save(); // 可选:定期保存
        }
    }
    
    package.SaveAs(new FileInfo("large.xlsx"));
}

​NPOI优化​​:

cs 复制代码
// 使用SXSSFWorkbook处理大数据(仅XSSF)
// 注意:NPOI的SXSSFWorkbook实现有限,建议大数据用EPPlus

2. 异步操作

​异步保存​​:

cs 复制代码
// EPPlus不直接支持异步保存,但可以异步写入数据
await Task.Run(() =>
{
    using (var package = new ExcelPackage())
    {
        // 写入数据...
        package.SaveAs(new FileInfo("output.xlsx"));
    }
});

3. 缓存与复用

​样式缓存​​:

cs 复制代码
// EPPlus样式复用
var headerStyle = package.Workbook.Styles.CreateStyle();
headerStyle.Font.Bold = true;
headerStyle.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
headerStyle.Fill.BackgroundColor.SetColor(Color.LightGray);

// 复用样式
worksheet.Cells["A1:D1"].Style = headerStyle;

六、常见问题解决

1. 内存泄漏

​EPPlus内存管理​​:

cs 复制代码
// 确保释放资源
using (var package = new ExcelPackage())
{
    // 操作...
} // 自动释放资源

​NPOI内存泄漏​​:

cs 复制代码
// 手动释放COM对象
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);

2. 大文件处理

​分块处理​​:

cs 复制代码
// 分块读取大文件
using (var package = new ExcelPackage(new FileInfo("large.xlsx")))
{
    var worksheet = package.Workbook.Worksheets[0];
    
    int batchSize = 1000;
    for (int startRow = 1; startRow <= worksheet.Dimension.Rows; startRow += batchSize)
    {
        int endRow = Math.Min(startRow + batchSize - 1, worksheet.Dimension.Rows);
        
        for (int row = startRow; row <= endRow; row++)
        {
            // 处理每行数据
        }
    }
}

3. 格式兼容性

​跨版本兼容​​:

cs 复制代码
// 检测Excel版本
if (Path.GetExtension(filePath).ToLower() == ".xls")
{
    // 使用HSSFWorkbook处理.xls
    IWorkbook workbook = new HSSFWorkbook();
}
else
{
    // 使用XSSFWorkbook处理.xlsx
    IWorkbook workbook = new XSSFWorkbook();
}

七、最佳实践建议

  1. ​小文件操作​​:

    • 使用ClosedXML或EPPlus
    • 简单API,开发效率高
  2. ​大文件操作​​:

    • 优先EPPlus
    • 分批处理数据
    • 考虑流式处理
  3. ​兼容性要求​​:

    • 使用NPOI
    • 同时支持.xls和.xlsx
  4. ​企业级应用​​:

    • 考虑GemBox.Spreadsheet(商业库)
    • 高性能,功能全面
  5. ​Web应用​​:

    • 使用EPPlus内存优化模式
    • 及时释放资源
    • 考虑异步处理

八、性能对比测试

操作类型 EPPlus(ms) NPOI(ms) ClosedXML(ms)
创建1000行 15 45 20
读取1000行 10 35 15
写入公式 25 60 30
应用样式 20 50 25
生成图表 40 不支持 50

九、扩展功能实现

1. 动态报表生成

cs 复制代码
public void GenerateReport(string templatePath, string outputPath, List<DataItem> data)
{
    using (var package = new ExcelPackage(new FileInfo(templatePath)))
    {
        var worksheet = package.Workbook.Worksheets[0];
        
        // 填充数据
        for (int i = 0; i < data.Count; i++)
        {
            worksheet.Cells[i+2, 1].Value = data[i].Name;
            worksheet.Cells[i+2, 2].Value = data[i].Value;
        }
        
        // 动态图表
        var chart = worksheet.Drawings.AddChart("Chart1", eChartType.ColumnClustered);
        chart.SetPosition(data.Count + 2, 0, 0, 0);
        chart.Series.Add(worksheet.Cells[2, 2, data.Count+1, 2], 
                        worksheet.Cells[2, 1, data.Count+1, 1]);
        
        package.SaveAs(new FileInfo(outputPath));
    }
}

2. 批量导出优化

cs 复制代码
public async Task ExportLargeDataAsync(string filePath, IEnumerable<DataItem> data)
{
    // 使用流式处理
    await using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        using (var package = new ExcelPackage(stream))
        {
            var worksheet = package.Workbook.Worksheets.Add("Data");
            
            // 写入表头
            worksheet.Cells[1, 1].Value = "ID";
            worksheet.Cells[1, 2].Value = "Name";
            
            int row = 2;
            foreach (var item in data)
            {
                worksheet.Cells[row, 1].Value = item.Id;
                worksheet.Cells[row, 2].Value = item.Name;
                row++;
                
                // 每1000行刷新一次
                if (row % 1000 == 0)
                {
                    await Task.Delay(10); // 避免UI线程阻塞
                }
            }
            
            package.Save();
        }
    }
}

十、总结

  1. ​选择建议​​:

    • 简单报表 → ClosedXML
    • 复杂操作 → EPPlus
    • 兼容旧版 → NPOI
    • 企业级 → GemBox
  2. ​性能关键点​​:

    • 分批处理大数据
    • 样式复用
    • 及时释放资源
    • 异步操作
  3. ​扩展建议​​:

    • 使用模板引擎生成复杂报表
    • 实现缓存机制减少重复计算
    • 考虑使用内存映射文件处理超大文件
相关推荐
一枚小小程序员哈3 小时前
基于微信小程序的家教服务平台的设计与实现/基于asp.net/c#的家教服务平台/基于asp.net/c#的家教管理系统
后端·c#·asp.net
Eternity_GQM4 小时前
【Word VBA Zotero 引用宏错误分析与改正指南】【解决[21–23]参考文献格式插入超链接问题】
开发语言·c#·word
cimeo9 小时前
【C 学习】06-算法&程序设计举例
c#
Full Stack Developme9 小时前
Java后台生成多个Excel并用Zip打包下载
java·开发语言·excel
百锦再10 小时前
.NET 的 WebApi 项目必要可配置项都有哪些?
java·开发语言·c#·.net·core·net
WYH28720 小时前
C#控制台输入(Read()、ReadKey()和ReadLine())
开发语言·c#
hqwest21 小时前
C#WPF实战出真汁06--【系统设置】--餐桌类型设置
c#·.net·wpf·布局·分页·命令·viewmodel
芦骁骏1 天前
自动处理考勤表——如何使用Power Query,步步为营,一点点探索自定义函数
数据分析·excel·powerbi
做一位快乐的码农1 天前
基于.net、C#、asp.net、vs的保护大自然网站的设计与实现
c#·asp.net·.net
DavieLau1 天前
C#项目WCF接口暴露调用及SOAP接口请求测试(Python版)
xml·服务器·开发语言·python·c#