如何使用 C# 和 OleDbConnection 读取 .xlsx 和 .xls 文件?

Posted

技术标签:

【中文标题】如何使用 C# 和 OleDbConnection 读取 .xlsx 和 .xls 文件?【英文标题】:How to read .xlsx and .xls files using C# and OleDbConnection? 【发布时间】:2017-09-29 09:43:53 【问题描述】:

以前我使用ExcelPackage 从 .xlsx 文件中读取数据。那工作正常,但后来我意识到ExcelPackage 不适用于旧的 .xls 格式。所以我升级为使用OleDbConnection 而不是ExcelPackage,如下所示:

var 文件 = HttpContext.Current.Request.Files[0];
数据表 sheetData = new DataTable();
string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
    file.FileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"";

使用 (OleDbConnection conn = new OleDbConnection(connStr))

    conn.Open();
    DataTable dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[]  null, null, null, "TABLE" );
    字符串 sheetName = dtSchema.Rows[0].Field("TABLE_NAME");
    OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "]", conn);
    sheetAdapter.Fill(sheetData);

基本上只是试图阅读那里的第一个电子表格。但是我在异常中得到了这个错误:

Cannot update. Database or object is read-only.

我做错了什么?里面是否隐藏着某种更新操作?

【问题讨论】:

尝试关闭你正在用C#读取的excel文件 您是否打开了 Excel,并且偶然打开了这个特定文件? 我没有在 excel 中打开文件。克里斯蒂安,你是什么意思关闭文件?和疯一样吗? excel文件在哪里?是本地的吗?我发布的代码出错了,但是,一定有其他事情发生。如果您只是尝试读取文件,则错误 Cannot update 似乎是一个奇怪的错误。 【参考方案1】:

下面是一个示例方法,它从给定的 excel 文件路径返回 DataSet。返回的DataSet 应该将工作簿中的每个 Excel 工作表作为DataTableDataSet 中。这似乎工作正常,希望它可以帮助。

private DataSet GetExcelDataSet(string path) 
  string sheetName;
  string ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path +
                        "; Jet OLEDB:Engine Type = 5; Extended Properties =\"Excel 8.0;\"";
  DataSet ds = new DataSet();
  using (OleDbConnection con = new OleDbConnection(ConnectionString)) 
    using (OleDbCommand cmd = new OleDbCommand()) 
      using (OleDbDataAdapter oda = new OleDbDataAdapter()) 
        cmd.Connection = con;
        con.Open();
        DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
        for (int i = 0; i < dtExcelSchema.Rows.Count; i++) 
          sheetName = dtExcelSchema.Rows[i]["TABLE_NAME"].ToString();
          DataTable dt = new DataTable(sheetName);
          cmd.Connection = con;
          cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
          oda.SelectCommand = cmd;
          oda.Fill(dt);
          dt.TableName = sheetName;
          ds.Tables.Add(dt);
        
      
    
  
  return ds;

【讨论】:

【参考方案2】:

试试这个:

OleDbConnection connection;
OleDbCommand command;
OleDbDataReader dr;

        string commandText = "SELECT * FROM [Sheet1$]";
        string oledbConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
        @"Data Source=" + filename + ";" +
        "Extended Properties=\"Excel 12.0;HDR=YES\";";
        connection = new OleDbConnection(oledbConnectString);
        command = new OleDbCommand(commandText, connection);

        try
        
            connection.Open();
            dr = command.ExecuteReader();

            while (dr.Read())
            
                count++;

                for (int i = 1; i < dr.VisibleFieldCount; i++)
                
                   Console.Writeln(""+dr[i].ToString());
                
            

            connection.Close();
        
        catch (Exception ex)
        
            MessageBox.Show("" + ex.Message);
            connection.Close();
        

【讨论】:

当我尝试得到这个时:The Microsoft Office Access database engine cannot open or write to the file ''. It is already opened exclusively by another user, or you need permission to view and write its data. @Ryan 所以问题出在你的文件上。请检查它是否正在使用或您是否有权编辑它:D

以上是关于如何使用 C# 和 OleDbConnection 读取 .xlsx 和 .xls 文件?的主要内容,如果未能解决你的问题,请参考以下文章

C#调用OleDbConnection类读取Excel表格时,报错外部组件发生异常!

C#如何把DataTable更新到Access数据库

如何使用c#连接到access 2007

通过 OleDbConnection 获取单个记录的最佳方法是啥?

用Access作为后台数据库支撑,书写一个用C#写入记录的案例

如何以编程方式检索所有查询的查询文本