上一篇
如何用C高效读取Excel数据并同步至数据库?
- 行业动态
- 2025-05-11
- 1
C#可通过EPPlus或Microsoft.Office.Interop.Excel库读取Excel数据,支持解析单元格内容并转换为DataSet或对象集合,需处理文件格式兼容性及数据类型转换,结合ADO.NET可实现Excel与数据库的批量导入导出操作。
在开发过程中,经常需要将Excel表格作为数据源进行读取,以下是C#处理Excel数据的完整方案,采用主流的EPPlus和NPOI两种库实现,并针对不同场景提供最佳实践。
准备工作
安装NuGet包:
Install-Package EPPlus # 适用于.xlsx格式(Office 2007+) Install-Package NPOI # 支持.xls和.xlsx格式
引用命名空间:
using OfficeOpenXml; // EPPlus using NPOI.SS.UserModel; // NPOI using System.Data.OleDb; // OleDB方式
OleDB读取(传统方式)
适用于简单的数据导入,要求安装Microsoft Access Database Engine:
string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:data.xlsx; Extended Properties='Excel 12.0;HDR=YES;IMEX=1;'"; using (OleDbConnection conn = new OleDbConnection(connectionString)) { conn.Open(); OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", conn); DataTable dt = new DataTable(); da.Fill(dt); foreach (DataRow row in dt.Rows) { Console.WriteLine(row["姓名"] + " | " + row["成绩"]); } }
注意:HDR=YES表示首行为列头,IMEX=1强制混合数据为文本
EPPlus高效处理(推荐)
现代Excel处理方案,支持LINQ操作:
FileInfo file = new FileInfo(@"C:data.xlsx"); using (ExcelPackage package = new ExcelPackage(file)) { ExcelWorksheet worksheet = package.Workbook.Worksheets[0]; int rowCount = worksheet.Dimension.Rows; for (int row = 2; row <= rowCount; row++) { string name = worksheet.Cells[row, 1].GetValue<string>(); DateTime date = worksheet.Cells[row, 2].GetValue<DateTime>(); double score = worksheet.Cells[row, 3].GetValue<double>(); // 处理业务逻辑 Console.WriteLine($"{name} 于 {date:yyyy-MM-dd} 获得 {score} 分"); } }
高级功能:
- 公式计算:
worksheet.Calculate()
- 条件格式读取:
worksheet.Cells[row,col].Style.Font.Bold
- 数据验证:
worksheet.DataValidations
NPOI跨格式支持
同时兼容.xls和.xlsx文件:
using (FileStream fs = new FileStream("data.xls", FileMode.Open)) { IWorkbook workbook = WorkbookFactory.Create(fs); ISheet sheet = workbook.GetSheetAt(0); for (int row = 1; row <= sheet.LastRowNum; row++) { IRow currentRow = sheet.GetRow(row); ICell nameCell = currentRow.GetCell(0); ICell scoreCell = currentRow.GetCell(1); // 处理不同单元格类型 string name = nameCell?.ToString() ?? "未知"; double score = scoreCell?.CellType == CellType.Numeric ? scoreCell.NumericCellValue : 0; } }
提示:使用CellType
判断单元格类型可避免格式异常
常见问题解决方案
日期格式错误:
// EPPlus处理日期 double oaValue = worksheet.Cells[row,2].GetValue<double>(); DateTime date = DateTime.FromOADate(oaValue); // NPOI处理日期 if (DateUtil.IsCellDateFormatted(cell)) DateTime date = cell.DateCellValue;
大文件内存优化:
// EPPlus配置 ExcelPackage.LicenseContext = LicenseContext.NonCommercial; var config = new ExcelReaderConfiguration() { UseCellCache = true // 启用单元格缓存 }; // NPOI事件模型 using (var stream = new FileStream("large.xlsx", FileMode.Open)) { var reader = new XSSFReader(stream); var sheetIterator = reader.Sheets; while (sheetIterator.MoveNext()) { var sheet = (XSSFSheet)reader.GetSheet(sheetIterator.Current); var rowIterator = sheet.GetRowEnumerator(); } }
合并单元格处理:
// EPPlus方式 var mergeCells = worksheet.MergedCells; foreach (var range in mergeCells) { ExcelRangeBase range = worksheet.Cells[range]; string mergedValue = range.First().Text; }
注意事项
数据验证:
- 检查文件扩展名有效性
- 验证用户上传权限
- 设置最大文件尺寸限制
异常处理:
try { // 文件操作代码 } catch (IOException ex) { // 处理文件占用异常 } catch (InvalidOperationException ex) { // 处理格式错误 }
版本兼容性:
| 文件格式 | 推荐库 | 特点 |
|———-|————|————————|
| .xlsx | EPPlus | 高性能,功能丰富 |
| .xls | NPOI | 旧版兼容 |
| 两者 | ClosedXML | 语法更简洁 |
引用说明:
- EPPlus官方文档:https://epplussoftware.com/
- NPOI GitHub仓库:https://github.com/nissl-lab/npoi
- Microsoft OleDB参考:https://learn.microsoft.com/odbc