如何用C#读取Excel 2016?现有代码返回空DataTable求助
解决C#读取Excel 2016的问题
先修复你的空DataTable问题
你的代码里有几个关键错误,导致读取不到数据:
- 驱动匹配错误:
.xlsx格式(Excel 2007及以上,包括2016)需要用Microsoft.ACE.OLEDB.12.0驱动,而你用了针对旧版.xls的Microsoft.Jet.OLEDB.4.0 - 扩展名判断逻辑失效:你直接把
fileExt写死成.xlsx,没有从传入的文件名里动态获取实际扩展名,导致判断永远走错误的分支 - 连接字符串笔误:
HRD=Yes是拼写错误,应该是HDR=Yes(表示Excel第一行是表头) - 连接字符串不完整:
.xlsx对应的Extended Properties应该是Excel 12.0 Xml;HDR=Yes;IMEX=1
修正后的代码如下:
using System.Data; using System.Data.OleDb; using System.IO; public static DataTable ReadExcel(string fileName) { // 动态获取文件扩展名并转小写 string fileExt = Path.GetExtension(fileName).ToLower(); string conn = string.Empty; DataTable dtexcel = new DataTable(); if (fileExt == ".xlsx" || fileExt == ".xlsm") { // Excel 2007+(含2016)的连接字符串 conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0 Xml;HDR=Yes;IMEX=1';"; } else if (fileExt == ".xls") { // 旧版Excel的连接字符串 conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';"; } else { throw new ArgumentException("不支持的文件格式,请传入.xls或.xlsx/.xlsm文件"); } using (OleDbConnection oleConn = new OleDbConnection(conn)) { oleConn.Open(); // 获取工作表列表,取第一个工作表 DataTable schemaTable = oleConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); if (schemaTable == null || schemaTable.Rows.Count == 0) { return dtexcel; } string sheetName = schemaTable.Rows[0]["TABLE_NAME"].ToString(); // 查询并填充DataTable string query = $"SELECT * FROM [{sheetName}]"; using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, oleConn)) { adapter.Fill(dtexcel); } } return dtexcel; }
注意:使用ACE驱动需要确保你的电脑安装了Microsoft Access Database Engine 2010 Redistributable,且版本(32/64位)要和你的项目编译平台一致。
更推荐的方法:使用EPPlus库
OLEDB驱动需要额外安装组件,处理复杂格式也容易出问题,现在更常用的是EPPlus(专门针对Excel 2007+的.NET库),步骤如下:
- 在NuGet包管理器中安装EPPlus(非商业用途建议用4.x版本,最新版本需要商业授权)
- 使用以下代码读取:
using System.Data; using System.IO; using OfficeOpenXml; public static DataTable ReadExcelWithEPPlus(string fileName) { DataTable dt = new DataTable(); // 非商业用途需设置LicenseContext ExcelPackage.LicenseContext = LicenseContext.NonCommercial; using (ExcelPackage package = new ExcelPackage(new FileInfo(fileName))) { // 获取第一个工作表 ExcelWorksheet worksheet = package.Workbook.Worksheets[0]; int rowCount = worksheet.Dimension.Rows; int colCount = worksheet.Dimension.Columns; // 添加表头列 for (int col = 1; col <= colCount; col++) { dt.Columns.Add(worksheet.Cells[1, col].Text); } // 填充数据行 for (int row = 2; row <= rowCount; row++) { DataRow dr = dt.NewRow(); for (int col = 1; col <= colCount; col++) { dr[col - 1] = worksheet.Cells[row, col].Text; } dt.Rows.Add(dr); } } return dt; }
这个方法不需要额外安装驱动,代码更简洁,还能轻松处理Excel的公式、样式等复杂内容。
内容的提问来源于stack exchange,提问作者RajeshVerma
相关产品推荐
相关产品推荐

