数据库

导入Excel到数据库

2014-03-03

导入Excel到数据库中是一个常见的操作,这里采用两种实现,一种比较简洁,一种侧重效率。

这里说明一下:导入的Excel可以包含多个sheet,最终都导入到dataset的同一个table中。

一、简洁实现:

 

 

 

  1.  /// <summary>  
  2.         /// 导入Excel到DataSet中  
  3.         /// </summary>  
  4.         /// <param name="strFileSourse">文件的路径和文件全名,含扩展名</param>  
  5.         /// <returns></returns>  
  6.         public DataSet ExcelToDataSet(string strFileSourse)  
  7.         {  
  8.             DataSet ds = new DataSet();  
  9.             //Excel数据源(兼容03/10)  
  10.             string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strFileSourse + ";
  11. Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";  
  12.   
  13.   
  14.             //连接  
  15.             OleDbConnection conn = new OleDbConnection(strConn);  
  16.             try  
  17.             {  
  18.                 conn.Open();  
  19.   
  20.   
  21.                 //获取Excel中所有的sheet  
  22.                 DataTable dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { nullnullnull
  23. "TABLE" });  
  24.   
  25.   
  26.   
  27.   
  28.                 //把Excel中所有的sheet数据读到一个Table中  
  29.                 for (int i = 0; i < dtSheet.Rows.Count; i++)  
  30.                 {  
  31.                     string strSheetName = dtSheet.Rows[i]["TABLE_NAME"].ToString();  
  32.                     OleDbDataAdapter OleDa = new OleDbDataAdapter("Select × from [" + strSheetName + "]", conn);  
  33.                     OleDa.Fill(ds, "TableName");  
  34.                     conn.Close();  
  35.                 }  
  36.             }  
  37.             catch (Exception)  
  38.             {  
  39.                 //System.Windows.Forms.MessageBox.Show(e.ToString());  
  40.                 throw;  
  41.             }  
  42.             finally  
  43.             {  
  44.                 if (conn.State!=ConnectionState.Closed)  
  45.                 {  
  46.                     conn.Close();  
  47.                 }  
  48.             }  
  49.               
  50.             return ds;  
  51.         }  
 


 

二、侧重效率:

 

[csharp] view plaincopy
 
  1. /// <summary>  
  2. /// 导入Excel到DataSet中  
  3. /// </summary>  
  4. /// <param name="strFileUrl">文件的路径和文件全名,含扩展名</param>  
  5. /// <returns></returns>  
  6. public DataSet ImportExcel(string strFileUrl)  
  7. {  
  8.      
  9.     //创建进程  
  10.     Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.ApplicationClass();  
  11.     //获取Microsoft.Office.Interop.Excel进程启动结束的时间  
  12.     afterTime = DateTime.Now;    
  13.     if (xlApp==null)  
  14.     {  
  15.         returnstatue = -1;  
  16.         returnmessage = "无法创建Microsoft.Office.Interop.Excel.Application对象,请先检查您的计算机是否安装了Office!";  
  17.         return null;  
  18.     }  
  19.   
  20.     //判断要上传的文件是否正在被其他进程使用  
  21.     Microsoft.Office.Interop.Excel.Workbook workBook;  
  22.     try  
  23.     {  
  24.         workBook = xlApp.Workbooks.Open(strFileUrl, 0, false, 5, """"false
  25. Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, ""truefalse, 0, true, 1, 0);  
  26.   
  27.     }  
  28.     catch (Exception)  
  29.     {  
  30.   
  31.         returnstatue = -1;  
  32.         returnmessage = "Excel文件处于打开状态,请保存您的文件后关闭!";  
  33.         return null;  
  34.     }  
  35.   
  36.     //获取所有Sheet名称  
  37.     int intSheetCount = workBook.Worksheets.Count;  
  38.     //根据sheet个数,定义字串数组  
  39.     string[] SheetSet = new string[intSheetCount];  
  40.     //System.Collections.ArrayList al = new System.Collections.ArrayList();  
  41.     //获取Excel中的sheet名数组  
  42.     for (int i = 0; i < intSheetCount; i++)  
  43.     {  
  44.         SheetSet[i - 1] = ((Microsoft.Office.Interop.Excel.Worksheet)workBook.Worksheets[i]).Name;  
  45.   
  46.     }  
  47.       
  48.     //释放Excel相关对象资源  
  49.     workBook.Close(nullnullnull);  
  50.   
  51.     xlApp.Quit();  
  52.       
  53.     
  54.     if (workBook!=null)  
  55.     {  
  56.         //系统中包含有很多释放com对象/cache等常见的所有资源的方法  
  57.         System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);  
  58.         workBook = null;  
  59.           
  60.     }  
  61.   
  62.     if (xlApp!=null)  
  63.     {  
  64.         //交由内存托管,马上释放资源(Interop互操作、Marshal整顿)  
  65.         System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);  
  66.         xlApp = null;  
  67.     }  
  68.   
  69.     //强制CLR执行内存回收  
  70.     GC.Collect();  
  71.   
  72.     //获取了sheet数组后,作为数据源,将Excel中的数据读取到DataSet中  
  73.     DataSet ds = new DataSet();  
  74.     string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strFileUrl + ";
  75. Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";  
  76.     using (OleDbConnection conn = new OleDbConnection(strConn))  
  77.     {  
  78.         conn.Open();  
  79.         OleDbDataAdapter da;  
  80.         for (int i = 0; i < intSheetCount; i++)  
  81.         {  
  82.             string sql = "Select × from ["+SheetSet[i-1]+"+$]";  
  83.             da = new OleDbDataAdapter(sql, conn);  
  84.             //将所有的数据集都填充到一个Table中  
  85.             da.Fill(ds, "Table");  
  86.             da.Dispose();  
  87.         }  
  88.         conn.Close();  
  89.         conn.Dispose();  
  90.     }  
  91.   
  92.   
  93.     ////TODO:销毁Excel进程  
  94.     Kill(xlApp);  
  95.     return ds;  
  96. }  

 

 

销毁进程:

 

[csharp] view plaincopy
 
  1. [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]  
  2. private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);  
  3. /// <summary>  
  4. /// 销毁Excel线程  
  5. /// </summary>  
  6. /// <param name="excel"></param>  
  7. private void Kill(Microsoft.Office.Interop.Excel.Application excel)  
  8. {  
  9.     //得到这个句柄,具体作用是得到这块内存入口  
  10.     IntPtr t = new IntPtr(excel.Hwnd);      
  11.   
  12.     int k = 0;  
  13.     //得到唯一标志k  
  14.     GetWindowThreadProcessId(t, out k);  
  15.     //k的引用  
  16.     System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);  
  17.     //关闭k  
  18.     p.Kill();  
  19. }  

以上是两种不同的实现,第二种更多的调用了操作系统的接口,这里只限于是Windows操作系统,包括销毁进程的方法,也是调用了系统的接口。统的接口。