导入Excel到数据库中是一个常见的操作,这里采用两种实现,一种比较简洁,一种侧重效率。
这里说明一下:导入的Excel可以包含多个sheet,最终都导入到dataset的同一个table中。
一、简洁实现:
- /// <summary>
- /// 导入Excel到DataSet中
- /// </summary>
- /// <param name="strFileSourse">文件的路径和文件全名,含扩展名</param>
- /// <returns></returns>
- public DataSet ExcelToDataSet(string strFileSourse)
- {
- DataSet ds = new DataSet();
- //Excel数据源(兼容03/10)
- string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strFileSourse + ";
- Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
- //连接
- OleDbConnection conn = new OleDbConnection(strConn);
- try
- {
- conn.Open();
- //获取Excel中所有的sheet
- DataTable dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null,
- "TABLE" });
- //把Excel中所有的sheet数据读到一个Table中
- for (int i = 0; i < dtSheet.Rows.Count; i++)
- {
- string strSheetName = dtSheet.Rows[i]["TABLE_NAME"].ToString();
- OleDbDataAdapter OleDa = new OleDbDataAdapter("Select × from [" + strSheetName + "]", conn);
- OleDa.Fill(ds, "TableName");
- conn.Close();
- }
- }
- catch (Exception)
- {
- //System.Windows.Forms.MessageBox.Show(e.ToString());
- throw;
- }
- finally
- {
- if (conn.State!=ConnectionState.Closed)
- {
- conn.Close();
- }
- }
- return ds;
- }
二、侧重效率:
- /// <summary>
- /// 导入Excel到DataSet中
- /// </summary>
- /// <param name="strFileUrl">文件的路径和文件全名,含扩展名</param>
- /// <returns></returns>
- public DataSet ImportExcel(string strFileUrl)
- {
- //创建进程
- Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
- //获取Microsoft.Office.Interop.Excel进程启动结束的时间
- afterTime = DateTime.Now;
- if (xlApp==null)
- {
- returnstatue = -1;
- returnmessage = "无法创建Microsoft.Office.Interop.Excel.Application对象,请先检查您的计算机是否安装了Office!";
- return null;
- }
- //判断要上传的文件是否正在被其他进程使用
- Microsoft.Office.Interop.Excel.Workbook workBook;
- try
- {
- workBook = xlApp.Workbooks.Open(strFileUrl, 0, false, 5, "", "", false,
- Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, false, 0, true, 1, 0);
- }
- catch (Exception)
- {
- returnstatue = -1;
- returnmessage = "Excel文件处于打开状态,请保存您的文件后关闭!";
- return null;
- }
- //获取所有Sheet名称
- int intSheetCount = workBook.Worksheets.Count;
- //根据sheet个数,定义字串数组
- string[] SheetSet = new string[intSheetCount];
- //System.Collections.ArrayList al = new System.Collections.ArrayList();
- //获取Excel中的sheet名数组
- for (int i = 0; i < intSheetCount; i++)
- {
- SheetSet[i - 1] = ((Microsoft.Office.Interop.Excel.Worksheet)workBook.Worksheets[i]).Name;
- }
- //释放Excel相关对象资源
- workBook.Close(null, null, null);
- xlApp.Quit();
- if (workBook!=null)
- {
- //系统中包含有很多释放com对象/cache等常见的所有资源的方法
- System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
- workBook = null;
- }
- if (xlApp!=null)
- {
- //交由内存托管,马上释放资源(Interop互操作、Marshal整顿)
- System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
- xlApp = null;
- }
- //强制CLR执行内存回收
- GC.Collect();
- //获取了sheet数组后,作为数据源,将Excel中的数据读取到DataSet中
- DataSet ds = new DataSet();
- string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strFileUrl + ";
- Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
- using (OleDbConnection conn = new OleDbConnection(strConn))
- {
- conn.Open();
- OleDbDataAdapter da;
- for (int i = 0; i < intSheetCount; i++)
- {
- string sql = "Select × from ["+SheetSet[i-1]+"+$]";
- da = new OleDbDataAdapter(sql, conn);
- //将所有的数据集都填充到一个Table中
- da.Fill(ds, "Table");
- da.Dispose();
- }
- conn.Close();
- conn.Dispose();
- }
- ////TODO:销毁Excel进程
- Kill(xlApp);
- return ds;
- }
销毁进程:
- [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
- private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
- /// <summary>
- /// 销毁Excel线程
- /// </summary>
- /// <param name="excel"></param>
- private void Kill(Microsoft.Office.Interop.Excel.Application excel)
- {
- //得到这个句柄,具体作用是得到这块内存入口
- IntPtr t = new IntPtr(excel.Hwnd);
- int k = 0;
- //得到唯一标志k
- GetWindowThreadProcessId(t, out k);
- //k的引用
- System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);
- //关闭k
- p.Kill();
- }
以上是两种不同的实现,第二种更多的调用了操作系统的接口,这里只限于是Windows操作系统,包括销毁进程的方法,也是调用了系统的接口。统的接口。
相关新闻
- 小程序登录流程图理解 2020-08-18
- 在C#中获取web.config中的配置信息 2021-08-23
- 小程序open-data头像样式 2021-04-10
- 小程序rich-text 富文本解析图片过大和图片路径的问题 2020-11-25
- C#中去掉字符串的最后一个字符 2020-11-23