正在做一個體檢管理系統,涉及到把Excel資料匯入到SQLServer,本以為挺簡單的一件事還是折騰了會,在讀取完資料更新到資料庫時用了三種方法,覺得這個最可取,話不多說,來看代碼。
B S系統,先使用FileUpload控制項儲存當前Excel檔案到伺服器,再讀取Excel中的資料,如下:
public DataSet GetExcelTabel() { string isXls = "";//用來儲存副檔名 //檢查檔案是否存在 if (FileUpload1.HasFile == false)//HasFile用來檢查FileUpload是否有指定檔案 { Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('請您選擇Excel檔案! ');</script>"); //return;//當無檔案時,返回 return null; } //System.IO.Path.GetExtension獲得檔案的副檔名 isXls = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower(); //如果不是excel檔案給出提示 if (isXls != ".xls") { Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('只可以選擇Excel檔案件! ');</script>"); //return;//當選擇的不是Excel檔案時,返回 return null; } //給檔案名稱加上時間 string filename = DateTime.Now.ToString("yyyymmddhhMMss") + FileUpload1.FileName; //擷取Execle檔案名稱 DateTime日期函數 string savePath = Server.MapPath(("~\\uploads\\") + filename);//Server.MapPath 獲得虛擬伺服器相對路徑 //如果已經存在就清空 ClearFile(Server.MapPath("~\\uploads")); FileUpload1.SaveAs(savePath); //SaveAs 將上傳的檔案內容儲存在伺服器上 try { //連接字串 string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + savePath + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'"; //建立adapter擷取Excel中的資料 OleDbDataAdapter da = new OleDbDataAdapter("select * from [Sheet1$]", strConn); //填充讀取的Excel資料到DataSet DataSet ds = new DataSet(); da.Fill(ds, "T_TeamPatient"); return ds; } catch (Exception) { return null; throw new Exception ("擷取Excel中的資料失敗"); } }
再把讀取的資料匯入到資料庫中:
public bool ImportToSQL() { DataSet ds=GetExcelTabel ();//從excel中擷取的dataset DataSet dsPre = new DataSet();//從資料庫擷取的dataset //建立資料庫連接 string connString = "server=.;database=CHAOYANG_HOSPITAL;uid=sa;pwd=123456"; string sqlnowtxt = "select * from T_TeamPatient"; SqlConnection sqlconn = new SqlConnection(connString); SqlCommand sqlcmd = new SqlCommand(sqlnowtxt , sqlconn); try { sqlconn.Open(); //建立映射 SqlDataAdapter da = new SqlDataAdapter(sqlcmd); da.Fill(dsPre,"T_TeamPatient");//從資料庫中擷取資料 //複製excel表dataset中的資料表格 DataTable dt = ds.Tables[0].Copy (); //添加到即將更新到資料庫的dataset foreach (DataRow dr in dt.Rows ) { dsPre.Tables[0].Rows.Add(dr.ItemArray); } //更新資料庫 SqlCommandBuilder scb = new SqlCommandBuilder(da); da.UpdateCommand = sqlcmd; da.Update(dsPre, "T_TeamPatient"); return true; } catch (Exception) { return false; throw new Exception("匯入資料到資料庫失敗"); } finally { sqlconn.Close(); sqlcmd.Dispose(); } }
在這裡,更新dsPre時,提供給大家另外兩種思路:
DataTable dt = ds.Tables[0].Copy (); dsPre.Tables.Add(dt); dsPre.Tables.Remove(dsPre.Tables[0]);
即先刪除從資料庫來的表,再補充上Excel的資料表,再更新上去,為什麼需要先copy一下?因為dt原屬於ds,如果強制添加給dsPre則會引發“已經屬於另外一個DataSet”的錯誤。這個方法更適合替換資料而非補充資料。
另外一種方法是,先將讀取的Excel資料轉換為DataRow數組,使用Merge將兩張表合并:
dsPre .Merge (dataRow[]);
當然最好是把資料庫連接寫成一個獨立的函數,以供其它函數調用;需要注意的是總需要“select”語句讓SqlDataAdapter知道需要更新資料庫的哪張表;Update時標明映射的資料庫表名。
維護考試系統時,裡面有匯入Excel到資料庫的函數,想著直接粘貼過來,改來改去反而越改越亂,索性自己寫了一個。