2017-05-02 95 views
0

此前我使用ExcelPackage从.xlsx文件中读取数据。这工作正常,但后来我意识到ExcelPackage不适用于旧的.xls格式。所以我升级到使用OleDbConnection,而不是ExcelPackage这样的:如何使用C#和OleDbConnection读取.xlsx和.xls文件?

var file = HttpContext.Current.Request.Files[0]; 
DataTable 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;\""; 

using (OleDbConnection conn = new OleDbConnection(connStr)) 
{ 
    conn.Open(); 
    DataTable dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); 
    string 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.

我在做什么错?那里隐藏着某种更新操作吗?

+0

尝试关闭您在C#中阅读的excel文件 –

+0

您是否打开Excel并偶然使用此特定文件? –

+0

我没有在Excel中打开该文件。基督徒,你是什么意思关闭文件?疯了吗? – Ryan

回答

0

尝试这种情况:

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(); 
     } 
+0

当我尝试这样做时:'Microsoft Office Access数据库引擎无法打开或写入文件''。它已经被另一个用户专门打开,或者你需要查看和写入其数据的权限。“# – Ryan

+0

@Ryan所以问题是你的文件。请检查它是否在使用中,或者您是否有权编辑它:D – julanove

0

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

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