168

我正在尝试使用下面显示的代码读取 Excel (xlsx) 文件。我得到一个“外部表不是预期的格式”。错误,除非我已经在 Excel 中打开了该文件。换句话说,我必须先在 Excel 中打开文件,然后才能从 C# 程序中读取 if。xlsx 文件在我们的网络上共享。如何在无需先打开文件的情况下读取文件?谢谢

string sql = "SELECT * FROM [Sheet1$]";
string excelConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathname + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\"";

using (OleDbDataAdapter adaptor = new OleDbDataAdapter(sql, excelConnection)) {
    DataSet ds = new DataSet();
    adaptor.Fill(ds);
}
4

25 回答 25

252

“外部表不是预期的格式。” 通常在尝试使用带有以下连接字符串的 Excel 2007 文件时发生:Microsoft.Jet.OLEDB.4.0 和 Extended Properties=Excel 8.0

使用以下连接字符串似乎可以解决大多数问题。

public static string path = @"C:\src\RedirectApplication\RedirectApplication\301s.xlsx";
public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
于 2009-09-01T16:38:52.207 回答
28

感谢这段代码:) 我真的很感激。为我工作。

public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

因此,如果您有不同版本的 Excel 文件,请获取文件名,如果其扩展名是.xlsx,请使用以下命令:

Private Const connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

如果是.xls,请使用:

Private Const connstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" + path + ";Extended Properties=""Excel 8.0;HDR=YES;"""
于 2010-02-11T06:38:45.470 回答
16

(我的声誉太低,无法评论,但这是对 JoshCaba 条目的评论,使用 Ace 引擎而不是 Jet for Excel 2007)

如果您的机器上没有安装/注册 Ace,您可以从以下网址获取:https ://www.microsoft.com/en-US/download/details.aspx?id=13255

它也适用于 Excel 2010。

于 2011-02-25T14:10:29.453 回答
9

只需添加我的案例。我的xls文件是通过网站的数据导出功能创建的,文件扩展名为xls,可以用MS Excel 2003正常打开。但是Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0都有一个“外部表不是预期的格式”异常。

最后,问题是,正如异常所说,“它不是预期的格式”。虽然它的扩展名是xls,但是当我用文本编辑器打开它时,它实际上是一个格式良好的html文件,所有数据都在一个<table>中,每个<tr>是一行,每个<td>是一个细胞。然后我想我可以用html方式解析它。

于 2016-01-22T12:25:00.073 回答
4

我有同样的问题。使用以下步骤解决:

1.) 点击文件

2.) 选择“另存为”

3.) 点击下拉菜单(另存为类型)

在此处输入图像描述

4.) 选择 Excel 97-2003 工作簿

在此处输入图像描述

5.) 点击保存按钮

在此处输入图像描述

于 2019-03-13T06:49:56.337 回答
3

我遇到了同样的问题(使用 ACE.OLEDB),为我解决的问题是这个链接:

http://support.microsoft.com/kb/2459087

它的要点是安装多个office版本和各种office sdk,程序集等导致注册表中的ACEOleDB.dll引用指向OFFICE12文件夹而不是OFFICE14

C:\Program Files\Common Files\Microsoft Shared\OFFICE14\ACEOLEDB.DLL

从链接:

或者,您可以修改注册表项,更改 dll 路径以匹配您的 Access 版本。

Access 2007 应使用 OFFICE12、Access 2010 - OFFICE14 和 Access 2013 - OFFICE15

(操作系统:64 位 Office:64 位)或(操作系统:32 位 Office:32 位)

键:HKCR\CLSID{3BE786A0-0366-4F5C-9434-25CF162E475E}\InprocServer32\

值名称:(默认)

数值数据:C:\Program Files\Common Files\Microsoft Shared\OFFICE14\ACEOLEDB.DLL

(操作系统:64 位办公室:32 位)

键:HKCR\Wow6432Node\CLSID{3BE786A0-0366-4F5C-9434-25CF162E475E}\InprocServer32\

值名称:(默认)

数值数据:C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE14\ACEOLEDB.DLL

于 2013-06-05T12:46:55.047 回答
2

尝试在要导入的工作表上使用复杂的 INDIRECT() 公式时,我也看到了此错误。我注意到了这一点,因为这是两个工作簿之间的唯一区别,其中一个正在导入,另一个没有。两者都是 2007+ .XLSX 文件,并且安装了 12.0 引擎。

我通过以下方式确认这是问题所在:

  • 制作文件的副本(仍然有问题,所以这不是一些另存为的区别)
  • 使用间接公式选择工作表中的所有单元格
  • 仅作为值粘贴

错误消失了。

于 2012-05-11T19:33:51.103 回答
2

我在第三方和 Oledb 阅读 XLSX 工作簿时遇到错误。该问题似乎是导致错误的隐藏工作表。取消隐藏工作表使工作簿能够导入。

于 2014-07-04T18:06:08.133 回答
2

如果文件是只读的,只需将其删除,它应该会再次工作。

于 2019-02-04T22:25:10.353 回答
2

我知道这是一篇非常古老的帖子,但我也可以就我如何设法解决这个问题做出贡献。

我还使用“Microsoft.ACE.OLEDB.12.0”作为提供者。当我的代码尝试读取 XLSX 文件时,它收到错误“外部表不是预期的格式”。但是,当我在 Excel 中保持文件打开然后代码尝试读取它时……它起作用了。

解决方案:我将 Office 365 与公司文档一起使用,就我而言,解决方案非常简单,我只需要禁用文档的敏感性,将其设置为“公共”。详细信息:即使保存为“公共”后,绿色复选标记仍保留在“内部使用”中,但此后问题仍然解决。

在此处输入图像描述

于 2020-11-18T14:14:54.327 回答
1

我遇到了这个问题,根据 Marcus Miris 的这篇文章,将扩展属性更改为 HTML 导入修复了它:

strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & importedFilePathAndName _
         & ";Extended Properties=""HTML Import;HDR=No;IMEX=1"";"
于 2016-06-24T13:07:54.017 回答
1

遇到同样的问题并找到了这个线程。除了@Smith 在 2013 年 4 月 17 日对已接受答案的评论外,上述建议均无帮助。

我的问题的背景与@zhiyazw 的足够接近——基本上是尝试将导出的 Excel 文件(在我的情况下为 SSRS)设置为 dtsx 包中的数据源。经过一番修补,我所做的只是重命名工作表。正如@Smith 所建议的那样,它不必是小写的。

我想 ACE OLEDB 期望 Excel 文件遵循某种 XML 结构,但不知何故 Reporting Services 并没有意识到这一点。

于 2018-06-27T08:02:40.980 回答
0

代替 OleDb,您可以使用 Excel 互操作并以只读方式打开工作表。

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbooks.open(v=office.15).aspx

于 2009-07-16T18:33:25.780 回答
0

该文件可能被另一个进程锁定,您需要复制它然后加载它,如本文所述

于 2014-02-16T23:58:39.167 回答
0

这也可以是包含图像或图表的文件,请参见:http: //kb.tableausoftware.com/articles/knowledgebase/resolving-error-external-table-is-not-in-expected-format

建议保存为 Excel 2003

于 2014-09-24T02:53:42.730 回答
0

只需将我的解决方案添加到此问题。我正在将 .xlsx 文件上传到网络服务器,然后从中读取并批量插入到 SQL Server。收到相同的错误消息,尝试了所有建议的答案,但没有一个有效。最终,我将文件保存为 excel 97-2003 (.xls),它可以工作......我现在唯一的问题是原始文件有 110,000 多行。

于 2015-06-17T09:47:51.350 回答
0

如果你仍然有这个问题,然后检查你的权限,我尝试了很多这些建议,我的具体问题是我要处理的文件在源代码控制下并且线程没有权限,我不得不更改整个文件夹的权限它开始工作(我在那里处理了很多文件)......它还匹配了许多建议,例如更改文件名或检查文件是否被另一个进程锁定。

我希望它对你有帮助。

于 2016-02-16T06:32:03.843 回答
0

ACE 已取代 JET

Ace 支持所有以前版本的 Office

此代码运行良好!

        OleDbConnection MyConnection;
        DataSet DtSet;
        OleDbDataAdapter MyCommand;
        
        MyConnection = new System.Data.OleDb.OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\\Book.xlsx;Extended Properties=Excel 12.0;");
        MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
        DtSet = new System.Data.DataSet();
        
        MyCommand.Fill(DtSet);
        dataGridView1.DataSource = DtSet.Tables[0];
        MyConnection.Close();
于 2016-10-03T11:14:14.653 回答
0

当工作簿受密码保护时,可能会发生这种情况。有一些解决方法可以删除此保护,但您可以在网上找到的大多数示例都已过时。无论哪种方式,简单的解决方案是手动取消保护工作簿,否则使用 OpenXML 之类的东西以编程方式删除保护。

于 2017-02-02T15:25:31.323 回答
0

我最近在与之前列出的任何答案都不匹配的上下文中看到了这个错误。原来是与AutoVer发生冲突。解决方法:暂时禁用 AutoVer。

于 2017-04-26T17:46:30.980 回答
0

该 excel 文件地址的扩展名可能不正确。您可以将扩展名从 xls 更改为 xlsx,反之亦然,然后重试。

于 2018-06-27T08:25:05.733 回答
0

我最近有这个“System.Data.OleDb.OleDbException(0x80004005):外部表不是预期的格式。” 发生错误。我依赖于 Microsoft Access 2010 Runtime。在 2018 年 12 月 12 日自动安装在我的服务器上的更新之前,我的 C# 代码使用 Microsoft.ACE.OLEDB.12.0 提供程序运行良好。安装 2018 年 12 月 12 日的更新后,我的日志文件中开始出现“外部表不是预期格式”。

我放弃了 Microsoft Access 2010 运行时并安装了 Microsoft Access 2013 运行时,我的 C# 代码再次开始工作,没有“System.Data.OleDb.OleDbException (0x80004005):外部表不是预期的格式。” 错误。

为我修复此错误的 2013 版本 https://www.microsoft.com/en-us/download/confirmation.aspx?id=39358

在 12 月 12 日自动安装在我的服务器上的更新之前为我工作的 2010 版本。 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910

我上个月在自动化过程中也发生了这个错误。当我运行它调试时,C# 代码运行良好。我发现运行代码的服务帐户也需要对 C:\Windows\Temp 文件夹的权限。

于 2018-12-20T20:12:27.883 回答
0

我的范围包括模板下载并在模板填充数据时验证模板所以,

1) 下载带有标题行的模板 (.xlsx) 文件。该文件是使用openxml生成的,并且运行良好。

2)上传相同的文件,而不改变它的下载状态。这将导致连接错误并失败(OLEDB 连接用于读取 excel 表)。

在这里,如果数据已填充,则程序按预期工作。

任何有想法的人都知道这个问题与我们正在创建的文件有关,如果我们打开它并保存将它转换为 excel 格式,它就是xml格式,它运行良好。

知道用首选文件类型下载 excel 吗?

于 2019-05-21T12:09:17.367 回答
0

使用一些旧代码并遇到同样的通用异常。很难追查这个问题,所以我想我会在这里添加,以防它帮助别人。

在我的例子中,在 OleDbConnection 尝试打开文件之前,项目中其他地方的代码正在打开 Excel 文件上的 StreamReader (这是在基类中完成的)。

所以基本上我只需Close()要先调用 StreamReader 对象,然后我就可以成功打开 OleDb 连接。它与 Excel 文件本身或 OleDbConnection 字符串(这自然是我首先查看的地方)无关。

于 2019-08-02T19:04:36.820 回答
0

我在我托管的 IIS 网站上发生过这种情况,但很少但会定期弹出这个错误,用于我之前解析得很好的文件。只需重新启动适用的应用程序池似乎可以解决问题。虽然不太清楚为什么...

于 2022-02-04T19:49:56.607 回答