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

How to read .xlsx and .xls files using C# and OleDbConnection?

以前我用ExcelPackage从.xlsx文件中读取数据。这很好,但后来我意识到ExcelPackage不适用于旧的.xls格式。所以我升级到使用OleDbConnection而不是ExcelPackage,就像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
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.

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


试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();
        }


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
}