EXCEL批量匯入資料MVC
阿新 • • 發佈:2018-12-30
using NPOI.HSSF.UserModel; //批量匯入的頁面Action public ActionResult ExcelAppendData() { return View(); } /// /// 匯入Excel方法 /// 作者 劉建超:2017年10月16日17:32:11 /// /// [HttpPost] public JsonResult LeadInMethod() { HttpPostedFileBase file = Request.Files["files"]; try { string FileName; string savePath; //新增公有欄位,成功後傳給前臺,便於提示使用者:檔案匯入成功,不能重複匯入 string fileFullName; #region 檢查檔案/儲存檔案 if (file == null || file.ContentLength <= 0) { return Json(new { result = false, message = "檔案不能為空,請先瀏覽選擇需要匯入的耗材表Excel檔案!" }, JsonRequestBehavior.AllowGet); } else { string filename = Path.GetFileName(file.FileName); int filesize = file.ContentLength;//獲取上傳檔案的大小單位為位元組byte string fileEx = System.IO.Path.GetExtension(filename);//獲取上傳檔案的副檔名 string NoFileName = System.IO.Path.GetFileNameWithoutExtension(filename);//獲取無副檔名的檔名 int Maxsize = 20 * 1024 * 1024;//定義上傳檔案的最大空間大小為20M string FileType = ".xls,.xlsx";//定義上傳檔案的型別字串 FileName = NoFileName + DateTime.Now.ToString("yyyyMMddhhmmss") + fileEx; if (!FileType.Contains(fileEx)) { return Json(new { result = false, message = "檔案型別不對,只能匯入xls和xlsx格式的檔案" }, JsonRequestBehavior.AllowGet); } if (filesize >= Maxsize) { return Json(new { result = false, message = "上傳檔案超過20M,不能上傳" }, JsonRequestBehavior.AllowGet); } string path = AppDomain.CurrentDomain.BaseDirectory + @"\Files\Excel"; savePath = Path.Combine(path, FileName); fileFullName = filename; #region 檔案儲存到伺服器 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } file.SaveAs(savePath); #endregion } #endregion #region 將匯入的Excel轉換成Table 出現問題:不同IIS會出現版本問題,這裡註釋改成下面的相容性 //string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + savePath + ";" + "Extended Properties='Excel 12.0;IMEX=1'"; //OleDbConnection conn = new OleDbConnection(strConn); //conn.Open(); //OleDbDataAdapter myCommand = new OleDbDataAdapter("select * from [Sheet1$];", strConn); //DataSet myDataSet = new DataSet(); //myCommand.Fill(myDataSet, "Sheet1$"); //myCommand.Dispose(); //conn.Close(); //conn.Dispose(); ////將資料錶轉換成datatable //System.Data.DataTable table = myDataSet.Tables["Sheet1$"].DefaultView.ToTable(); #endregion System.Data.DataTable table = new DataTable(); if (file.FileName.Substring(file.FileName.LastIndexOf(".") + 1).ToLower() == "xlsx") { table = XlsxImport(savePath); } else { table = XlsImport(savePath); } if (table != null && table.Rows.Count > 0) { #region 判斷模板正確與否 var falseNum = 0;//判斷模板錯誤的列數 if (table.Columns.Count == 10)//判斷列數是否是十個 { HM_ConsumableModel models = new HM_ConsumableModel(); //models.ConsNo = models.ConsName = models.ConsSpecification = models.ConsUnit = models.ConsPrice = models.ConsPayPrice = models.ConsSupplier; string[] TemplateTitle = { "耗材編號", "耗材名稱", "耗材規格", "單位", "應售", "實售", "生產廠家", "拼音碼", "五筆碼", "自定義碼" }; string[] TemplateTitlel = { "ConsNo", "ConsName", "ConsSpecification", "ConsUnit", "ConsPrice", "ConsPayPrice", "ConsSupplier", "PYCode", "WBCode", "CustomCode" }; for (int k = 0; k < table.Columns.Count; k++) { if (TemplateTitle[k] != table.Columns[k].ColumnName.ToString().Trim())//判斷標題是否相同 { falseNum++; } else { table.Columns[k].ColumnName = TemplateTitlel[k];//更換標題 } } } else { falseNum++; } #endregion #region 資料處理 if (falseNum == 0) { #region 刪除空行資料(耗材名稱,耗材規格和單位都為空的時候刪除此行資料) List arrayRows = new List();//存放要刪除的行 for (int i = 0; i < table.Rows.Count; i++) { if (table.Rows[i][1].ToString() == "" && table.Rows[i][2].ToString() == "" && table.Rows[i][3].ToString() == "") { arrayRows.Add(i); } } if (arrayRows.Count > 0) { for (int i = 0; i < arrayRows.Count; i++) { table.Rows.RemoveAt(i);//移除索引的行 } } #endregion var tableRowsNum = table.Rows.Count;//初始行數 table.Columns.Add("IsValid", typeof(int));//加一列:有效 table.Columns.Add("HpId", typeof(int));//加一列:醫院ID table.Columns.Add("EpUid", typeof(Int64)); //加一列:企業使用者ID var hpID = Convert.ToInt32(currentLogin.HpId); var epuID = currentLogin.EpUid; //var hpID = 160; //var epuID = 1; #region 給table迴圈新增列和列的值 for (int i = 0; i < tableRowsNum; i++) { table.Rows[i]["IsValid"] = 1; table.Rows[i]["HpId"] = hpID; table.Rows[i]["EpUid"] = epuID; } #endregion #region BulkCopy SqlBulkCopyByDatatable(DBConfig.CustomerManage.HM_Consumable, table); #endregion return Json(new { result = true, message = "成功匯入" + tableRowsNum + "條資料!", fileFullName = fileFullName }, JsonRequestBehavior.AllowGet); } else { return Json(new { result = true, message = "模板錯誤請重新上傳!" }, JsonRequestBehavior.AllowGet); } #endregion } else { return Json(new { result = false, message = "模板無資料!" }, JsonRequestBehavior.AllowGet); } } catch (Exception ex) { var values = ex.Message.ToString(); var errorMessage = ""; if (values == "列“ConsNo”不允許 DBNull.Value。") { errorMessage += "匯入異常,原因是:耗材編號不能有空,請檢查模板資料表!"; } else if (values == "列“ConsPrice”不允許 DBNull.Value。" || values == "列“ConsPayPrice”不允許 DBNull.Value。") { errorMessage += "匯入異常,原因是:應售(或實售)不能有空,請檢查模板資料表!"; } else if (values == "列“ConsSupplier”不允許 DBNull.Value。") { errorMessage += "匯入異常,原因是:生產廠家不能有空,請檢查模板資料表!"; } else { errorMessage += values; } return Json(new { result = false, message = errorMessage }, JsonRequestBehavior.AllowGet); } } #endregion /// 讀取excel Xlsx /// 預設第一行為標頭 /// /// excel文件路徑 /// public static DataTable XlsxImport(string strFileName) { DataTable dt = new DataTable(); NPOI.XSSF.UserModel.XSSFWorkbook hssfworkbook; using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) { hssfworkbook = new NPOI.XSSF.UserModel.XSSFWorkbook(file); } var sheet = hssfworkbook.GetSheetAt(0); System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); var headerRow = sheet.GetRow(0); int cellCount = headerRow.LastCellNum; for (int j = 0; j < cellCount; j++) { var cell = headerRow.GetCell(j); dt.Columns.Add(cell.ToString()); } for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) { var row = sheet.GetRow(i); DataRow dataRow = dt.NewRow(); for (int j = row.FirstCellNum; j < cellCount; j++) { if (row.GetCell(j) != null) dataRow[j] = row.GetCell(j).ToString(); } dt.Rows.Add(dataRow); } return dt; } /// 讀取excel Xls /// 預設第一行為標頭 /// /// excel文件路徑 /// public static DataTable XlsImport(string strFileName) { DataTable dt = new DataTable(); HSSFWorkbook hssfworkbook; using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) { hssfworkbook = new HSSFWorkbook(file); } var sheet = hssfworkbook.GetSheetAt(0); System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); var headerRow = sheet.GetRow(0); int cellCount = headerRow.LastCellNum; for (int j = 0; j < cellCount; j++) { var cell = headerRow.GetCell(j); dt.Columns.Add(cell.ToString()); } for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) { var row = sheet.GetRow(i); DataRow dataRow = dt.NewRow(); for (int j = row.FirstCellNum; j < cellCount; j++) { if (row.GetCell(j) != null) dataRow[j] = row.GetCell(j).ToString(); } dt.Rows.Add(dataRow); } return dt; } /// /// SqlBulkCopy批量匯入資料 Attention:SqlBulkCopy中列的名稱受大小寫敏感限制,因此在構造DataTable的時候應請注意列名要與表一致。 /// /// 資料庫目標表 /// 源資料 private void SqlBulkCopyByDatatable(string TableName, System.Data.DataTable dt) { using (var dbConnection = SqlDbHelper.CreateConnection()) { var connectionString = ConfigurationManager.ConnectionStrings["SqlConnString"].ConnectionString; using (SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction)) { try { sqlbulkcopy.DestinationTableName = TableName; for (int i = 0; i < dt.Columns.Count; i++) { sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); } sqlbulkcopy.WriteToServer(dt); } catch (System.Exception ex) { throw ex; } } } }