Microsoft.ACE.OLEDB.12.0读取Excel时忽略首行空列数据的问题求助
问题描述
我使用以下C#代码加载.xlsx文件:
Connection = new OleDbConnection( @"Provider = Microsoft.ACE.OLEDB.12.0;" + @"Data Source='" + FileWork + "';" + @"Extended Properties=""Excel 12.0; HDR = YES"""); Connection.Open(); var dtSchema = Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); OriginTableName = "[" + dtSchema.Rows[0].Field<string>("TABLE_NAME") + "]"; // 取第一个工作表 Adapter = new OleDbDataAdapter("SELECT * FROM " + OriginTableName, Connection); MyData.Clear(); Adapter.Fill(MyData);
遇到的问题:当某列前若干行完全为空时,整列数据会被彻底忽略无法加载;但只要该列前几行存在至少一个空格,就能正常加载所有数据。我的Excel表头包含ULICE列,表格样式如下:
我已尝试在连接字符串中添加TypeGuessRows=0、ImportMixedTypes=Text、IMEX=1,但均无效果,请问该如何解决?
解决方案
1. 修正连接字符串参数格式与内容
ACE OLEDB驱动对参数顺序和格式要求严格,调整连接字符串如下:
Connection = new OleDbConnection( @"Provider=Microsoft.ACE.OLEDB.12.0;" + @"Data Source='" + FileWork + "';" + @"Extended Properties=""Excel 12.0 Xml; HDR=YES; IMEX=1; TypeGuessRows=0; ImportMixedTypes=Text""");
注意点:
- 针对xlsx格式,需将
Excel 12.0改为Excel 12.0 Xml - 参数间用分号分隔,避免多余空格
- 确保引号嵌套正确
2. 修改注册表强制全列扫描
仅修改连接字符串可能无效,需配合注册表设置让TypeGuessRows=0生效:
- 打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel(64位系统需查看Wow6432Node下的对应路径) - 将
TypeGuessRows的值改为0,ImportMixedTypes的值改为Text - 若不存在对应项,手动新建字符串值并设置内容
3. 改用EPPlus等第三方Excel处理库(推荐)
OLEDB驱动的类型猜测机制存在固有缺陷,改用专门的Excel库可彻底解决问题,示例代码(需先安装EPPlus NuGet包):
using (var package = new ExcelPackage(new FileInfo(FileWork))) { var worksheet = package.Workbook.Worksheets[0]; MyData.Clear(); // 添加列名 for (int col = 1; col <= worksheet.Dimension.End.Column; col++) { MyData.Columns.Add(worksheet.Cells[1, col].Text); } // 读取数据行 for (int row = 2; row <= worksheet.Dimension.End.Row; row++) { DataRow dataRow = MyData.NewRow(); for (int col = 1; col <= worksheet.Dimension.End.Column; col++) { dataRow[col - 1] = worksheet.Cells[row, col].Text ?? string.Empty; } MyData.Rows.Add(dataRow); } }
该方式不受驱动类型猜测影响,能稳定读取所有列,包括前几行为空的列。
4. 临时预处理Excel文件(应急方案)
若无法修改代码或注册表,可临时在Excel中空列的前几行添加占位内容(如空格),保存后再用原代码加载,但这仅为临时 workaround,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Martin Dusek
相关产品推荐
相关产品推荐

