工作中要處理一批數據,主要是處理從別處導出來的Excel表格(大概有一千多行,三十多列),拿到表格對Excel表格進行分析,按照一定的規則進行拆分成為一萬多行的數據;首先這個需求要用程序進行處理的背景是人工進行拆分已經耗費了一周人天的資源,所以要用C#對數據進行處理,來提高工作效率。開始的想法是把Excel中的數據導入到C#的一個容器中,對容器進行操作,但是拿到規則之后,發現規則太過於復雜,最后的方案變成把Excel數據導入到數據庫中,然后,在數據庫中進行數據處理,然后再把數據庫中的數據導出到Excel表格中。
閱讀目錄
把Excel中的數據導入到數據庫中
在Excel數據到數據庫中時,首先要上傳這個Excel表格,然后找到數據的sheet頁,然后把需要的列數據導入到數據庫中,其中要注意Excel版本兼容性的問題。其具體的代碼如下:
1 if (FileUpload1.HasFile == false)//HasFile用來檢查FileUpload是否有指定文件 2 { 3 Response.Write("<script>alert('請您選擇Excel文件')</script> "); 4 return;//當無文件時,返回 5 } 6 string IsXls = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower();//System.IO.Path.GetExtension獲得文件的擴展名 7 if (IsXls != ".xls" && IsXls != ".xlsx") 8 { 9 Response.Write("<script>alert('只可以選擇Excel文件')</script>"); 10 return;//當選擇的不是Excel文件時,返回 11 } 12 SqlConnection cn = new SqlConnection(strConn); 13 cn.Open(); 14 string filename = DateTime.Now.ToString("yyyymmddhhMMss") + FileUpload1.FileName; //獲取Execle文件名 DateTime日期函數 15 string savePath = Server.MapPath(("~\\upfiles\\") + filename);//Server.MapPath 獲得虛擬服務器相對路徑 16 FileUpload1.SaveAs(savePath); //SaveAs 將上傳的文件內容保存在服務器上 17 DataSet ds = ExecleDs(savePath, filename); //調用自定義方法 18 DataRow[] dr = ds.Tables[0].Select(); //定義一個DataRow數組 19 int rowsnum = ds.Tables[0].Rows.Count; 20 if (rowsnum == 0) 21 { 22 Response.Write("<script>alert('Excel表為空表,無數據!')</script>"); //當Excel表為空時,對用戶進行提示 23 } 24 else 25 { 26 for (int i = 3; i < dr.Length; i++) 27 { 28 //獲取Excel中的內容並把他們導入到SQL Server數據庫中 29 string hhaspx_A = dr[i].ItemArray[0].ToString().Replace("'",""); 30 string hhaspx_B = dr[i].ItemArray[1].ToString(); 31 string hhaspx_C = dr[i].ItemArray[2].ToString(); 32 string hhaspx_D = dr[i].ItemArray[3].ToString(); 33 string hhaspx_E = dr[i].ItemArray[4].ToString().Replace("'", ""); 34 string hhaspx_H = dr[i].ItemArray[7].ToString(); 35 string hhaspx_I = dr[i].ItemArray[8].ToString(); 36 string hhaspx_J = dr[i].ItemArray[9].ToString(); 37 string hhaspx_N = dr[i].ItemArray[13].ToString().Replace("'", ""); 38 string hhaspx_P = dr[i].ItemArray[15].ToString().Replace("'", ""); 39 string hhaspx_S = dr[i].ItemArray[18].ToString(); 40 string hhaspx_X = dr[i].ItemArray[23].ToString().Replace("'", ""); 41 string hhaspx_AB = dr[i].ItemArray[27].ToString(); 42 string insertstr = "INSERT INTO dbo.S_DataToExcel ( hhaspx_A , hhaspx_B , hhaspx_C , hhaspx_D , hhaspx_E , hhaspx_H , hhaspx_I , Hhaspx_J , hhaspx_N , hhaspx_P , hhaspx_S , hhaspx_X , hhaspx_AB)"; 43 insertstr += "values ( '" + hhaspx_A + "' , cast('" + hhaspx_B + "' as int) ,cast( '" + hhaspx_C + "' as int) ,cast( '" + hhaspx_D + "' as int),'" + hhaspx_E + "', cast('" + hhaspx_H + "' as int) ,cast('" + hhaspx_I + "' as int),cast( '" + hhaspx_J + "' as int), '" + hhaspx_N + "', '" + hhaspx_P + "' , cast('" + hhaspx_S + "' as int), '" + hhaspx_X + "' , '" + hhaspx_AB + "')"; 44 SqlCommand cmd = new SqlCommand(insertstr, cn); 45 try 46 { 47 cmd.ExecuteNonQuery(); 48 } 49 catch (MembershipCreateUserException ex) //捕捉異常 50 { 51 Response.Write("<script>alert('導入內容:" + ex.Message + "')</script>"); 52 } 53 54 } 55 }
從上傳路徑的Excel中獲取Excel中的數據並裝載到相應的容器之中:
1 public DataSet ExecleDs(string filenameurl, string table) 2 { 3 //"Provider=Microsoft.ACE.OLEDB.12.0;"因為Excel存在版本的問題,我們這里選用了“Microsoft.ACE.OLEDB.12.0”用來兼容其他類型的Excel 4 string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "data source=" + filenameurl + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'"; 5 OleDbConnection conn = new OleDbConnection(strConn); 6 conn.Open(); 7 DataSet ds = new DataSet(); 8 OleDbDataAdapter odda = new OleDbDataAdapter("select * from [Sheet1$]", conn); 9 odda.Fill(ds, table); 10 return ds; 11 }
如果我們本地的系統中沒有安裝“Microsoft.ACE.OLEDB.12.0”相關的組件,建議在微軟官網進行安裝並下載;
處理Excel中的數據
調用數據庫的存儲過程,把數據按照規則進行轉換,並輸出轉換的結果,存儲過程處理數據的部分就不再贅述。
導出數據庫中的數據到Excel中
把存儲過程轉換過后的數據進行獲取並放到打他table中導出到Excel表格中。
1 string getDataSql = "EXEC sp_Tools_ExcelTrans"; 2 3 SqlCommand cmd1 = new SqlCommand(getDataSql, cn); 4 SqlDataAdapter sda = new SqlDataAdapter(cmd1); 5 DataTable Dt = new DataTable(); 6 sda.Fill(Dt); 7 8 //然后把數據進行導出來 9 DataChangeExcel.DataSetToExcel(Dt, Server.MapPath("~\\upfiles\\outputFormDataBase.xls"));
其中把Datatable數據導出到Excel中的方法:
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Web; 5 using Microsoft.Office.Interop; 6 7 /// <summary> 8 /// DataChangeExcel 的摘要說明 9 /// </summary> 10 11 public class DataChangeExcel 12 { 13 /// <summary> 14 /// 數據庫轉為excel表格 15 /// </summary> 16 /// <param name="dataTable">數據庫數據</param> 17 /// <param name="SaveFile">導出的excel文件</param> 18 public static void DataSetToExcel(DataTable dataTable, string SaveFile) 19 { 20 Microsoft.Office.Interop.Excel.Application excel; 21 Microsoft.Office.Interop.Excel._Workbook workBook; 22 Microsoft.Office.Interop.Excel._Worksheet workSheet; 23 object misValue = System.Reflection.Missing.Value; 24 excel = new Microsoft.Office.Interop.Excel.ApplicationClass(); 25 workBook = excel.Workbooks.Add(misValue); 26 workSheet = (Microsoft.Office.Interop.Excel._Worksheet)workBook.ActiveSheet; 27 int rowIndex = 1; 28 int colIndex = 0; 29 //取得標題 30 foreach (DataColumn col in dataTable.Columns) 31 { 32 colIndex++; 33 excel.Cells[1, colIndex] = col.ColumnName; 34 } 35 //取得表格中的數據 36 foreach (DataRow row in dataTable.Rows) 37 { 38 rowIndex++; 39 colIndex = 0; 40 foreach (DataColumn col in dataTable.Columns) 41 { 42 colIndex++; 43 excel.Cells[rowIndex, colIndex] = 44 row[col.ColumnName].ToString().Trim(); 45 //設置表格內容居中對齊 46 excel.Cells[rowIndex, colIndex]).HorizontalAlignment = 47 Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter; 48 } 49 } 50 excel.Visible = false; 51 workBook.SaveAs(SaveFile, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, misValue, 52 misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, 53 misValue, misValue, misValue, misValue, misValue); 54 dataTable = null; 55 workBook.Close(true, misValue, misValue); 56 excel.Quit(); 57 PublicMethod.Kill(excel);//調用kill當前excel進程 58 releaseObject(workSheet); 59 releaseObject(workBook); 60 releaseObject(excel); 61 } 62 63 private static void releaseObject(object obj) 64 { 65 try 66 { 67 System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 68 obj = null; 69 } 70 catch 71 { 72 obj = null; 73 } 74 finally 75 { 76 GC.Collect(); 77 } 78 } 79 }
其中”using Microsoft.Office.Interop;“要引入微軟Excel的類庫:”Microsoft Excel 15.0 Object Library“,並修改其引用庫的屬性”嵌入互操作類型“為”False“。
總結
有些時候對於Excel表格進行處理,Excel提供了編程在Excel內部對數據列進行處理,但是大部分人對於Excel中的編程不是很熟悉,導致操作起來有一些的困難,如果有一個程序猿(媛)的話,通過程序進行處理那就游刃有余了。