Microsoft Jet 提供程序用于连接到 Excel 工作簿。在以下连接字符串中,Extended Properties 关键字设置 Excel 特定的属性。“HDR=Yes;”指示第一行中包含列名,而不是数据,“IMEX=1;”通知驱动程序始终将“互混”数据列作为文本读取。Excel 8.0 针对Excel2000及以上版本,Excel5.0 针对Excel97。
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""
注意,Extended Properties 所需的双引号必须还要加双引号。
Provider=Microsoft.Jet.OLEDB.4.0只支持Office97-2003,不支持2007。如果需要支持2007,使用 Provider='Microsoft.Ace.OLEDB.12.0
使用ADO.NET打开、读取并关闭代码示例如下:
using System.Data.OleDb; using System.Data; String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:/test.xls;" + "Extended Properties=Excel 8.0;"; OleDbConnection objConn = new OleDbConnection(sConnectionString); objConn.Open(); OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM [sheet1]", objConn); OleDbDataAdapter objAdapter1 = new OleDbDataAdapter(); objAdapter1.SelectCommand = objCmdSelect; DataSet objDataset1 = new DataSet(); //将Excel中数据填充到数据集 objAdapter1.Fill(objDataset1, "XLData"); objConn.Close();
另一版本参考代码:
string ConnnectionString = string.Format(@"Provider='Microsoft.Ace.OLEDB.12.0';Data Source={0};" + "Extended Properties=Excel 8.0;", ExcelPath); OleDbConnection Excelconn = new OleDbConnection(ConnnectionString); try { Excelconn.Open(); OleDbCommand Excelcomm = new OleDbCommand(); //这段代码甚至可以让Connection重定向,根据实际需要选择该写,如果不需要重定向,From TableName就好了
string ExcelCommText = string.Format("select * FROM [Excel 8.0;HDR=yes;DATABASE={0}].[{1}$]", ExcelPath, TableName);
OleDbDataAdapter sda = new OleDbDataAdapter(ExcelCommText, Excelconn); DataSet ds = new DataSet(); sda.Fill(ds);
从上面可以看出,使用ADO.NET可将Excel当作普通数据库,使用SQL语句来操作。
通过ADO.NET获取Excel文件的各Sheet名称,可使用元数据方式:
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:/test.xls;" + "Extended Properties=Excel 8.0;"; OleDbConnection cn = new OleDbConnection(sConnectionString); cn.Open(); DataTable tb = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); foreach (DataRow row in tb.Rows) { //遍历弹出各Sheet的名称 MessageBox.Show(row["TABLE_NAME"]); }
关于使用ADO.NET创建并写入Excel文件与普通数据库操作极为类似,参见以下代码:
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:/test.xls;" + "Extended Properties=Excel 8.0;"; OleDbConnection cn = new OleDbConnection(sConnectionString); string sqlCreate = "CREATE TABLE TestSheet ([ID] INTEGER,[Username] VarChar,[UserPwd] VarChar)"; OleDbCommand cmd = new OleDbCommand(sqlCreate, cn); //创建Excel文件:C:/test.xls cn.Open(); //创建TestSheet工作表 cmd.ExecuteNonQuery(); //添加数据 cmd.CommandText = "INSERT INTO TestSheet VALUES(1,'elmer','password')"; cmd.ExecuteNonQuery(); //关闭连接 cn.Close();
另一版本Update参考代码
string ConnnectionString = string.Format(@"Provider='Microsoft.Ace.OLEDB.12.0';Data Source={0};" + "Extended Properties=Excel 8.0;", ExcelPath); OleDbConnection Excelconn = new OleDbConnection(ConnnectionString); Excelconn.Open(); OleDbCommand Excelcomm = new OleDbCommand(); //~ where XXX=’’ 在SQL中应改成 XXX is null ExcelCommText=string.Format("update [{0}$] set error = '{1}' where XXX is null",TableName, row["error"].ToString()); Excelcomm.CommandText = ExcelCommText; Excelcomm.Connection = Excelconn;//OleDbCommand 也需Connection属性,可以直接用OleDbConnection赋给 Excelcomm.ExecuteNonQuery();
直接读取Excel,写入Acces的方法
public bool InsertAccess(string AccessPath, string AccessName, string TableName, string ExcelPath,out string vErr) { bool bRet = false; vErr = string.Empty; try { vErr = string.Empty; string ConnnectionString = string.Format(@"Provider='Microsoft.Ace.OLEDB.12.0';Data Source={0}\\{1}.accdb", AccessPath, AccessName); OleDbConnection Accessconn = new OleDbConnection(ConnnectionString); try { Accessconn.Open(); OleDbCommand Accesscomm = new OleDbCommand(); string AccessCommText = string.Format(" SELECT * INTO [{0}] FROM [Excel 8.0;DATABASE={1}].[{2}$]", TableName.Replace("'", ""), ExcelPath, TableName.Replace("'", "")); //string AccessCommText = string.Format(" insert INTO [{0}] select * FROM [Excel 8.0;HDR=yes;DATABASE={1}].[{2}$]", TableName, ExcelPath, TableName); Accesscomm.CommandText = AccessCommText; Accesscomm.Connection = Accessconn; Accesscomm.ExecuteNonQuery(); bRet = true; } catch (Exception vTemp) { vErr += vTemp.Message + "\r\n"; } finally { Accessconn.Close(); Accessconn.Dispose(); } } catch (Exception ex) { vErr += ex.Message + "\r\n"; } return bRet; }
关于SQL语句中用到的数据类型,请查看System.Data.OleDb.OleDbType 枚举。
至此,使用ADO.NET打开、创建、读取、写入、保存并退出已全部实现,总结起来,与数据库操作基本无异,很简单。这种方式的好处就是通用性强,将Excel中内容看作数据表,读取操作简单可靠,适合内容规范的Excel表格的数据读取。缺点是当Excel结构复杂,如含合并单元等时,无法正确读取,甚至出现不可预知的异常。