通过 OleDbDataAdapter 方法从 Excel 文件中进行奇怪的 SELECT (C#)
我有一个这种形式的 Excel 文件:
Column 1 Column 2 Column 3
data1 data2
data1 data2
data1 data2
data1 data2
data1 data2 data3
也就是说,除了最后一行之外,整个第 3 列都是空的。 我通过 OleDbDataAdapter 访问 Excel 文件,返回 DataTable:这是代码。
query = "SELECT * FROM [" + query + "]";
objDT = new DataTable();
objCmdSQL = this.GetCommand();
objCmdSQL.CommandText = query;
objSQLDad = new OleDbDataAdapter(objCmdSQL);
objSQLDad.Fill(objDT);
return objDT;
关键是,在这种情况下,我的代码返回一个仅包含第 1 列和第 2 列的 DataTable。
我的猜测是,JET 引擎尝试通过每列中第一个单元格的类型来推断列类型;如果第一个值为 null,则整个列将被忽略。
我试图填写零,这段代码实际上返回了所有三列;这显然是最不优选的解决方案,因为我必须处理大量小文件。
反转选择范围(即从 "A1:C5" 到 "C5:A1" )也不起作用。 我正在寻找更优雅的东西。
我已经找到了几篇讨论类型不匹配的帖子(int 列中的 varchar 单元格,反之亦然),但实际上没有找到与此相关的任何内容。
感谢您的阅读!
编辑
再次出现奇怪的行为。我必须主要处理 Excel 2003 .xls 文件,但既然这个问题已经得到解答,我想我可以针对 Excel 2007 .xslx 文件测试我的代码。 连接字符串如下:
string strConn = @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + _fileName.Trim() + @";Extended Properties=""Excel 12.0;HDR=No;IMEX=1;""";
当 ACE/JET 与打开的文件之间存在版本不匹配时,我收到“外部表不是预期格式”异常,我认为这是标准异常。
该字符串
Provider=Microsoft.ACE.OLEDB.12.0
意味着我正在使用最新版本的 OLEDB,我快速浏览了一下,这个版本在需要连接到 .xlsx 文件的任何地方都使用。
我尝试过仅使用普通提供程序(仅 Excel 12.0,没有 IMEX 或 HDR),但我得到了相同的异常。
我使用的是 .NET 2.0.50727 SP2,也许是时候升级了?
I have got an Excel file in this form :
Column 1 Column 2 Column 3
data1 data2
data1 data2
data1 data2
data1 data2
data1 data2 data3
That is, the whole Column 3 is empty except for the last row.
I am accessing the Excel file via OleDbDataAdapter, returning a DataTable: here's the code.
query = "SELECT * FROM [" + query + "]";
objDT = new DataTable();
objCmdSQL = this.GetCommand();
objCmdSQL.CommandText = query;
objSQLDad = new OleDbDataAdapter(objCmdSQL);
objSQLDad.Fill(objDT);
return objDT;
The point is, in this scenario my code returns a DataTable with just Column 1 and Column 2.
My guess is that JET engine tries to infer column type by the type of the very first cell in every column; being the first value null, the whole column is ignored.
I tried to fill in zeros and this code is actually returning all three columns; this is obviously the least preferable solution because I have to process large numbers of small files.
Inverting the selection range (from, i.e. "A1:C5" to "C5:A1" ) doesn't work either.
I'm looking for something more elegant.
I have already found a couple of posts discussing type mismatch (varchar cells in int columns and vice versa) but actually haven't found anything related to this one.
Thanks for reading!
edit
Weird behavior again. I have to work on mostly Excel 2003 .xls files, but since this question has been answered I thought I could test my code against Excel 2007 .xslx files.
The connection string is the following:
string strConn = @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + _fileName.Trim() + @";Extended Properties=""Excel 12.0;HDR=No;IMEX=1;""";
I get the "External table is not in the expected format" exception which I reckon is the standard exception when there is a version mismatch between ACE/JET and the file being opened.
The string
Provider=Microsoft.ACE.OLEDB.12.0
means that I am using the most recent version of OLEDB, I took a quick peek around and this version is used everywhere there is need of connecting to .xlsx files.
I have tried with just a vanilla provider ( just Excel 12.0, without IMEX nor HDR ) but I get the same exception.
I am on .NET 2.0.50727 SP2, maybe time to upgrade?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我重新创建了您的情况,并正确返回了 3 列。也就是说,前两列完全填充了数据,第三列包含 null,直到最后一行包含数据。
注意:我使用了
Access Database Engine(ACE)
提供程序,它继承了旧的Joint Engine Technology(JET)
提供程序,并且我的结果可能代表了两者之间的行为差异。当然,如果您还没有使用它,我建议您使用ACE
提供程序,我相信 Microsoft 也会这样做。另外,请注意连接的扩展属性
:让我知道这是否有帮助。
I recreated your situation and following returned the 3 columns correctly. That is, the first two columns fully populated with data and the third containing null until the last row, which had data.
Note I used the
Access Database Engine(ACE)
provider, which succeeded the oldJoint Engine Technology(JET)
provider, and my results may represent a behavior difference between the two. Of course, if you aren't already using it I suggest using theACE
provider as I believe Microsoft would too. Also, note the connection'sExtended Properties
:Let me know if this helps.