如何使用ClosedXML将Excel工作表读取至C# DataTable?
使用ClosedXML将Excel读取到C# DataTable的实现方案
没问题!用ClosedXML来搞定这个需求刚好合适,完全不需要依赖Microsoft.ACE.OLEDB驱动,完美解决你遇到的环境问题。下面是具体的实现步骤和代码:
第一步:安装ClosedXML
首先通过NuGet安装ClosedXML包,你可以在Visual Studio的NuGet包管理器中搜索ClosedXML并安装,或者在包管理器控制台执行命令:
Install-Package ClosedXML
第二步:核心实现代码
下面的方法可以处理列数行数不固定的Excel表,首行作为列名,同时自动过滤完全空白的数据行(如果需要保留全空行,去掉对应的判断即可):
using ClosedXML.Excel; using System.Data; using System.Linq; public class ExcelReader { public DataTable ReadExcelToDataTable(string filePath, string sheetName = null) { var resultTable = new DataTable(); // 打开Excel文件,using自动释放资源 using (var workbook = new XLWorkbook(filePath)) { // 选择目标工作表:指定名称则用指定的,否则取第一个工作表 var targetSheet = string.IsNullOrEmpty(sheetName) ? workbook.Worksheets.First() : workbook.Worksheet(sheetName); // 读取首行作为DataTable的列名 var headerRow = targetSheet.Row(1); int totalColumns = headerRow.CellsUsed().Count(); // 逐个添加列到DataTable foreach (var headerCell in headerRow.CellsUsed()) { // 处理空列名:如果首行单元格为空,自动生成列名(比如Column1、Column2) string columnName = string.IsNullOrWhiteSpace(headerCell.Value.ToString()) ? $"Column{headerCell.ColumnNumber}" : headerCell.Value.ToString(); // 避免列名重复(如果有相同列名,自动加后缀) if (resultTable.Columns.Contains(columnName)) { columnName = $"{columnName}_{headerCell.ColumnNumber}"; } resultTable.Columns.Add(columnName); } // 遍历数据行(从第二行开始,跳过首行列名) foreach (var dataRow in targetSheet.RowsUsed().Skip(1)) { var newDataRow = resultTable.NewRow(); bool isRowAllEmpty = true; // 逐个单元格读取值 for (int colIndex = 0; colIndex < totalColumns; colIndex++) { var cell = dataRow.Cell(colIndex + 1); // ClosedXML的列索引从1开始 string cellValue = cell.Value.ToString(); // 空单元格用DBNull.Value填充,避免DataTable报错 newDataRow[colIndex] = string.IsNullOrWhiteSpace(cellValue) ? DBNull.Value : cellValue; // 标记此行是否有非空值 if (!string.IsNullOrWhiteSpace(cellValue)) { isRowAllEmpty = false; } } // 仅添加非全空的行到DataTable(如果需要保留全空行,删除这个判断即可) if (!isRowAllEmpty) { resultTable.Rows.Add(newDataRow); } } } return resultTable; } }
关键细节说明
CellsUsed()和RowsUsed():这两个方法会自动跳过完全空白的单元格/行,提升读取效率,同时避免处理不必要的空内容。- 空列名处理:如果首行有空白单元格,会自动生成类似
ColumnX的列名,同时处理重复列名的情况,避免DataTable抛出异常。 - 空值处理:空白单元格用
DBNull.Value填充,符合DataTable的空值规范。 - 格式支持:ClosedXML仅支持
.xlsx格式的Excel文件,如果需要处理旧版.xls文件,可能需要额外的转换工具或库。
使用示例
调用方法很简单,比如读取指定路径的第一个工作表:
var reader = new ExcelReader(); DataTable excelData = reader.ReadExcelToDataTable(@"C:\YourFile.xlsx");
如果要指定工作表名:
DataTable excelData = reader.ReadExcelToDataTable(@"C:\YourFile.xlsx", "Sheet2");
内容的提问来源于stack exchange,提问作者webworm




