Excel“外部表的格式不正确。”


162

我正在尝试使用下面显示的代码读取Excel(xlsx)文件。我得到“外部表不是预期的格式”。错误,除非我已经在Excel中打开了文件。换句话说,我必须先在Excel中打开文件,然后才能从C#程序中读取文件。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);
}

FWIW我在excel工作表上收到此消息,尝试打开它时,我使用的是当前的ACE和建议的扩展属性。当我手动打开文件时,它的顶部显示提示以启用编辑功能,我需要找出如何自动翻转该位的方法,但是如果您要获取此文件,则可能只需要打开文件,然后启用编辑功能即可。 。我可能会看一下是否可以以只读方式打开文件,在此线程中我看到了一些很深的东西。
Jeff Patton

Answers:


246

“外部表的格式不正确。” 尝试使用带有以下连接字符串的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;";

10
具有讽刺意味的是,我从其他人的应用程序(Scribe)收到了此错误,但说明仍然为我解决了问题:“另存为” Excel 97-2003,并且已修复错误。
杰夫·戴维斯

4
.xlsx或.xls扩展名?
FAtBalloon'5

3
您可能必须先安装此软件:microsoft.com/en-us/download/confirmation.aspx?
id=23734

11
这可能令人难以置信,但我只是将工作表名称更改为所有小写并使用sheet1 $
Smith,

3
我正在使用LinqToExcel,并且要使LinqToExcel使用该查询字符串,我必须将文件重命名为xlsx。有问题的电子表格确实是excel 97电子表格,但是odbc提供程序似乎并不在乎。一旦我诱使LinqToExcel使用正确的查询字符串,提供程序显然将决定如何读取文件而与文件扩展名无关。我的情况很方便。
蒂姆·科克

26

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

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

因此,如果您使用的是diff版本的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;"""

5
仅供参考:如果您尝试.xls在未安装Jet OleDb 的PC上打开文件,这将引发OleDbException 。
jp2code 2012年

@Trex您确定最后一行代码正确吗?您可以在某些编辑器中再次检查它吗?
乔吉,2017年

15

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

如果您的计算机上尚未安装/注册Ace,则可以从以下位置获取它:https : //www.microsoft.com/zh-CN/download/details.aspx?id=13255

它也适用于Excel 2010。


我已经安装了ACE引擎,但是我需要知道我的项目中需要包含哪些参考II,以便安装程序将其包括在内。并非我的应用程序所安装的所有计算机都必须安装了MS Office。
jp2code 2012年

1
链接现在显示错误消息- We're sorry, this download is no longer available
RBT

9

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

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


我的情况也是如此,但是我的文件实际上是XML。仍然很高兴知道如何使用OBDC导入它,但我认为它不受支持。
David Rogers

@DavidRogers,我见过类似XML ODBC Driver的东西,但从未使用过,请访问cdata.com/drivers/xml/odbc
约瑟夫·丁

同样的情况,我想魔术始于用记事本打开文件,实际上我是在投票给你答案,因为直到现在我还没有向下滚动看到你的帖子(现在我已经打开文件/解析了它)使用Html Agility pack ...),但按照纯逻辑,您的答案应该放在顶部:首先打开文件!看看里面是否有一些Excel风格的文件样式!
加布里埃尔G

如果它是html文件,则只需应用扩展属性,如下所示:Extended Properties=""HTML Import;HDR=No;IMEX=1
Nepaluz

4

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

1.)点击文件

2.)选择“另存为”

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

在此处输入图片说明

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

在此处输入图片说明

5.)点击保存按钮

在此处输入图片说明


1
!恢复为过时的文件格式甚至都不是要考虑的问题。在回答此问题时,97-2003格式已使用16年,但已过时12年。我可以理解几年,但是已经过了十多年了,这不应该向专业开发人员建议文件格式需要更旧。
Lemiarty

3

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

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

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

C:\ Program Files \ Common Files \ Microsoft共享\ OFFICE14 \ ACEOLEDB.DLL

从链接:

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

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

(OS:64位Office:64位)或(OS:32位Office:32位)

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

值名称:(默认)

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

(作业系统:64bit办公室:32bit)

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

值名称:(默认)

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


我发现仅转到“程序和功能”以及“修复ACE”会更容易。(对我来说,ACE被命名为Microsoft Access Runtime 2016)。我以为我遇到了这个问题,并且Repair只是为我重置了所有注册表项,而我不必担心regedit ;-)。
宾基

2

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

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

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

错误消失了。


2

第三方和Oledb阅读XLSX工作簿时出现错误。问题似乎是一个隐藏的工作表,导致错误。取消隐藏工作表使工作簿可以导入。


2

如果该文件为只读文件,则将其删除,即可再次使用。


1

遇到相同的问题并找到了该线程。除了@Smith在13年4月17日对已接受答案的评论外,以上建议均无济于事。

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

我猜想ACE OLEDB希望Excel文件遵循某种XML结构,但是Reporting Services不知何故。


我遇到了表格的同一问题,但格式不正确。我确认我的工作簿没有隐藏的工作表。工作簿中的实际工作表名称大写,但在C#代码中解析我为选项卡名称添加的.ToLower()文件,现在我可以再次解析excel文件。谢谢!
vvvv4d

1

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


0

该文件可能被其他进程锁定,你需要复制它,然后它在这说,加载



0

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


0

如果您仍然遇到此问题,请检查您的权限,我尝试了许多建议,而我的具体问题是我要处理的文件在源代码控制下,并且该线程没有权限,因此我不得不更改整个文件夹的权限并开始工作(我正在其中处理许多文件)...它还与许多建议相匹配,例如更改文件名或检查文件是否被另一个进程检查。

希望对您有帮助。


0

我遇到了这个问题,根据Marcus Miris的这篇文章,将Extended Properties更改为HTML Import修复了它:

strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & importedFilePathAndName _
         & ";Extended Properties=""HTML Import;HDR=No;IMEX=1"";"

0

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

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


5
不建议使用Excel互操作使用Excel。它可能会导致很多问题,因此不建议使用。
MaxOvrdrv

尽管这是一个过时的帖子,但我同意MaxOvrdrv的观点,但使用互操作不是一个好主意,如果出于其他原因(除非需要在服务器上完整安装Excel),则应避免使用互操作。
Lemiarty '16

您绝对不应该这样做。
sovemp

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();

1
它不是。该问题仍然可能发生,但我还没有找到原因,因为我的文件全部来自excel 2007,并且其中一些有效,但其中一些无效。
Henrik

您有该主张的来历吗?我不知道自己,只是想知道。:-)
midoriha_senpai

0

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


0

我最近在与前面列出的任何答案都不匹配的情况下看到此错误。原来是与AutoVer冲突。解决方法:暂时禁用AutoVer。


0

我最近遇到了此“ System.Data.OleDb.OleDbException(0x80004005):外部表未采用预期的格式。” 发生错误。我依赖于Microsoft Access 2010运行时。在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/zh-cn/download/confirmation.aspx?id=39358

在12月12日自动安装到服务器上的更新之前,适用于我的2010版本。 https://www.microsoft.com/zh-CN/download/confirmation.aspx?id=10910 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910

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


0

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

1)下载带有标题行的模板(.xlsx)文件。该文件是使用openxml生成的,可以正常工作。

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

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

任何有想法的人都与我们正在创建的文件相关联,该文件位于xml中如果我们打开它,然后将其保存为excel格式,则格式保存,并且效果很好。

有什么想法可以下载首选文件类型的Excel吗?


您不应该在答案中提出问题,如果您需要对问题的答案,请在需要时分别询问。
Abhishek Garg

0

使用一些较旧的代码并遇到了相同的通用异常。很难找出问题所在,所以我想在这里补充一下,以防其他人受到影响。

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

因此,基本上我只需Close()要先调用StreamReader对象,然后就可以成功打开OleDb Connection。它与Excel文件本身或与OleDbConnection字符串(自然是我刚开始的地方)无关。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.