通过 OleDbDataAdapter 方法从 Excel 文件中进行奇怪的 SELECT (C#)

发布于 2024-10-05 09:21:40 字数 1431 浏览 8 评论 0原文

我有一个这种形式的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千纸鹤带着心事 2024-10-12 09:21:40

我重新创建了您的情况,并正确返回了 3 列。也就是说,前两列完全填充了数据,第三列包含 null,直到最后一行包含数据。

string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";";
DataTable dt = new DataTable();
OleDbConnection conn = new OleDbConnection(connString);
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", conn);

adapter.Fill(dt);

注意:我使用了Access Database Engine(ACE) 提供程序,它继承了旧的Joint Engine Technology(JET) 提供程序,并且我的结果可能代表了两者之间的行为差​​异。当然,如果您还没有使用它,我建议您使用 ACE 提供程序,我相信 Microsoft 也会这样做。另外,请注意连接的扩展属性

“HDR=是;”表明第一个
行包含列名,而不是数据。
“HDR=否;”表示相反。

“IMEX=1;”告诉司机永远
读“混合”(数字、日期、
字符串等)数据列作为文本。
请注意,此选项可能会影响
Excel 工作表写访问权限为负。

让我知道这是否有帮助。

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.

string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";";
DataTable dt = new DataTable();
OleDbConnection conn = new OleDbConnection(connString);
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", conn);

adapter.Fill(dt);

Note I used the Access Database Engine(ACE) provider, which succeeded the old Joint 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 the ACE provider as I believe Microsoft would too. Also, note the connection's Extended Properties:

"HDR=Yes;" indicates that the first
row contains columnnames, not data.
"HDR=No;" indicates the opposite.

"IMEX=1;" tells the driver to always
read "intermixed" (numbers, dates,
strings etc) data columns as text.
Note that this option might affect
excel sheet write access negative.

Let me know if this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文