Excel“外部表格格式不符合预期。”

169

我正在尝试使用以下代码读取Excel(xlsx)文件。如果我没有在Excel中打开该文件,则会出现“外部表格格式不正确”的错误。换句话说,在我能够从C#程序中读取它之前,我必须先在Excel中打开该文件。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);
}

就我而言,我是在尝试使用当前ACE和建议的扩展属性打开Excel表格时收到了这个错误提示。当我手动打开文件时,它出现了一个提示,让我启用编辑权限。我需要找出如何自动翻转该位,但如果您也遇到此问题,您可能只需要打开该文件,然后启用编辑权限即可。我可以尝试查看一下能否以只读方式打开该文件,因为在本帖子的很远处我看到了有关此内容的信息。 - Jeff Patton
25个回答

255

"外部表格不符合预期格式"通常在尝试使用一个连接字符串为Microsoft.Jet.OLEDB.4.0和Extended Properties=Excel 8.0的Excel 2007文件时出现。

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

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;";

11
具有讽刺意味的是,我从其他人的应用程序(Scribe)中收到了这个错误,但是这个解释仍然帮助我解决了问题:“另存为” Excel 97-2003,错误得以修复。 - Jeff Davis
3
你可能需要先安装这个:http://www.microsoft.com/en-us/download/confirmation.aspx?id=23734 - rovsen
11
这可能令人难以置信,但我只需将工作表名称改为全部小写,并使用"sheet1$"。 - Smith
3
我在使用LinqToExcel,为了让它使用查询字符串,我需要将文件重命名为xlsx格式。 要注意的是,这个电子表格实际上是Excel 97电子表格,但ODBC提供程序似乎并不在意这一点。 一旦我欺骗LinqToExcel使用正确的查询字符串,提供程序就会自行确定如何读取文件,而与文件的扩展名无关。 在我的案例中,这是一个便利的漏洞。 - Tim Coker
1
@Smith 这并不是不可思议的,因为每当您打开文件并进行任何更改时,格式都会得到纠正。这只有在您控制正在使用的文件时才有帮助。如果您的应用程序从随机用户那里接收文件,则仍然无法解决问题。 - jwize
显示剩余7条评论

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;"""

5
请注意:如果您尝试在未安装Jet OleDb的PC上打开一个 .xls 文件,将会抛出一个OleDbException异常。 - user153923
@Trex你确定你的最后一行代码是正确的吗?你能再次在某个编辑器中检查一下吗? - Jogi

16

(我的声望不够高,不能发表评论,但这是对JoshCaba条目的评论,建议在Excel 2007中使用Ace引擎而不是Jet)

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

同样适用于Excel 2010。


我已经安装了ACE引擎,但我需要知道在我的项目中需要包含哪个引用,以便我的安装程序可以包括它。并非所有安装了我的应用程序的计算机都必定安装了MS Office。 - user153923
1
链接现在显示错误信息 - “抱歉,此下载不再可用”。 - RBT
链接又可以使用了。 - J. Rockwood

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驱动程序的东西,但从未使用过,你可以看看https://www.cdata.com/drivers/xml/odbc/. - Fengtao Ding
同样的情况也发生在我这里,我猜想魔法从用记事本打开文件开始,事实上我会点赞你的回答,因为直到现在我才看到你的帖子(而现在我已经用Html Agility包打开/解析了文件...),但你的回答应该是最好的,纯粹的逻辑:首先打开文件!看看它是否有一些类似Excel的文件格式! - Gabriel G
1
如果它是一个HTML文件,只需应用扩展属性,如下所示:Extended Properties=""HTML Import;HDR=No;IMEX=1 - Nepaluz

6
我遇到了同样的问题,按照以下步骤解决: 1.) 点击文件 2.) 选择“另存为” 3.) 点击下拉框(保存类型) enter image description here 4.) 选择Excel 97-2003工作簿 enter image description here 5.) 点击保存按钮 enter image description here

2
Boo!回归过时的文件格式甚至不应该被考虑。在回答此问题时,97-2003格式已经16年历史,已经过时12年。我可以理解几年,但超过十年的过时时间不应该让专业开发人员认为文件格式需要更老。 - Lemiarty

3

我曾经遇到了同样的问题(使用ACE.OLEDB),解决方法是通过以下链接:

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

其核心内容是:安装多个Office版本和各种Office SDK、程序集等导致注册表中的ACEOleDB.dll引用指向OFFICE12文件夹而不是OFFICE14文件夹,因此需要进行如下修改:

或者,您可以修改注册表键,将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位 Office:32位)

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

值名称:(默认)

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

请注意,保留了HTML标签。

我发现直接进入“程序和功能”并修复ACE(对我来说,ACE的名称为Microsoft Access Runtime 2016)更容易。我认为我遇到了这个问题的变体,而修复程序只是在不需要使用regedit的情况下为我重置了所有的注册表键;-) - binki

2
我曾在尝试在导入的工作表上使用复杂的INDIRECT()公式时发现了这个错误。我注意到这是两个工作簿之间唯一的区别,其中一个正在导入,另一个没有。两者都是2007+ .XLSX文件,并安装了12.0引擎。
我通过以下方式确认了这个问题:
- 复制文件(仍然存在问题,因此不是一些保存的差异) - 选择具有间接公式的工作表中的所有单元格 - 只粘贴值
然后该错误消失了。

2
如果文件是只读的,只需删除它,然后它就可以正常工作了。最初的回答。

2

我在使用第三方和Oledb读取XLSX工作簿时遇到了错误。

问题似乎是由一个隐藏的工作表引起的错误。将工作表取消隐藏后,工作簿可以被导入。


2
我知道这是一个非常古老的帖子,但我也可以做出我的贡献,介绍一下我如何解决这个问题。
我也使用“Microsoft.ACE.OLEDB.12.0”作为提供程序。当我的代码尝试读取XLSX文件时,它收到了错误消息“外部表格不符合预期格式”。然而,当我在Excel中保持文件打开状态,然后代码尝试读取它时...它起作用了。
解决方案:我使用Office 365处理公司文档,在我的情况下,解决方案非常简单,我只需要禁用文档的敏感性,将其设置为“公共”。详情:即使保存为“公共”,绿色勾号仍然标记为“内部使用”,但问题仍然得到解决。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接