我有一个简单的C#程序,应该读取XLS文件并将其作为DataTable
对象返回。除非在MS Excel中打开相同的文件,否则它无法获取数据 - 同时,在启动程序时。该程序使用Microsoft.Jet.OLEDB.4.0
提供程序以及OleDbConnection
和OleDbDataAdapter
类实例来访问数据:
public class ExcelImport
{
static public DataTable GetDataTable(string excelFileName, string sqlSelect)
{
string tpl = @"Provider=Microsoft.Jet.OLEDB.4.0;Data source={0};Extended Properties=""Excel 8.0;HDR=Yes;""";
string excelConnectionString = string.Format(tpl, excelFileName);
using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
{
connection.Open(); // <---- here it fails
using (OleDbDataAdapter adapter = new OleDbDataAdapter(sqlSelect, connection))
{
DataTable table = new DataTable();
adapter.Fill(table);
return table;
}
}
}
}
电话看起来像这样:
string fname = @"d:\directory\the_file.xls";
string sqlcmd = @"
SELECT
[Code],
[Name]
FROM [Sheet1$]";
DataTable dt = ExcelImport.GetDataTable(fname, sqlcmd);
当MS Excel(版本2016,如果重要)正在运行时,程序正常工作,并且确切的文件是打开的。否则,connection.Open();
将失败,并显示以下消息:
System.Data.OleDb.OleDbException occurred
HResult=0x80004005
Message=Neočekávaná chyba z externího ovladače databáze (1).
Source=Microsoft JET Database Engine
StackTrace:
at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionInternal.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.OleDb.OleDbConnection.Open()
at ExcelImport.GetDataTable(String excelFileName, String sqlSelect) in D:\__XXXX_webapp\WEBAPP\WEBAPP\App_Code\ExcelImport.cs:line 20
at cz.company.mylogin.DataPump.DataPumpTheFileXLS() in D:\__XXXX_webapp\DataPump\Program.cs:line 249
at cz.company.mylogin.DataPump.Main() in D:\__XXXX_webapp\DataPump\Program.cs:line 308
根据报告的HRESULT错误,我找到了相关原因https://support.microsoft.com/en-us/help/295297/prb-error-message-0x80004005-general-error-unable-to-open-registry-key
我不知道对HRESULT的解释是否具有误导性或是否真的是这个原因。
问题是:为什么在MS Excel中打开同一个文件时它会起作用?如何在不运行Excel的情况下获取数据还需要做什么?