使用NPOI解析Excel、SqlSugar 批量入庫\更新、SqlBulkCopy入庫
阿新 • • 發佈:2022-12-02
public ActionResult testImport(string path) { string[] columnsStr = new string[] {"dataType", "customerCode", "factory", "projectNo", "countrieType", "productCategory", "modelName", "version", "scene", "remark" }; Stopwatch watch = new Stopwatch(); watch.Start(); //開始監視程式碼執行時間 FileStream fileStream = new FileStream(path, FileMode.Open); IWorkbook workbook = null; DataSet dataSet = new DataSet(); bool boolRow = false;//標記資料行 if (fileStream.Name.EndsWith(".xlsx")) workbook = new XSSFWorkbook(fileStream); else workbook = new HSSFWorkbook(fileStream); var DayValueStartColumn = DemandPlanLineDataService.DayValueStartColumn-1; for (int i = 0; i < workbook.NumberOfSheets; i++) { DataTable dataTable = new DataTable();//構建一個DataTable 對應一個Sheet 新增 DataTable updateTable = new DataTable();//構建一個DataTable 對應一個Sheet 更新 bool isExstisTable = false; bool isClonTable = true;//是否存在 匯入資料中既有更新又有新增,將原始的新增Table行拷貝到更新Table行中 Dictionary<int, Dictionary<string, object>> dicfileValues = new Dictionary<int, Dictionary<string, object>>(); ISheet sheet = workbook.GetSheetAt(i); string dateBaseTable = "DemandPlanLine_" + planMain.Month.Replace("-", "_"); dataTable.TableName = dateBaseTable + "@Insert";//sheet.SheetName;//頁簽名為DataTable名 updateTable.TableName = dateBaseTable + "@Update";//sheet.SheetName;//頁簽名為DataTable名 var checkTable = SugarClient.Default.Context.Ado.SqlQuerySingle<string>($"select id from sysObjects where Id=OBJECT_ID(N'{dateBaseTable}') and xtype='U'");//返回動態型別 dynamic dateBaseModel = null; List<dynamic> checkBaseDate = null; if (checkTable!=null) { checkBaseDate = SugarClient.Default.Context.Ado.SqlQuery<dynamic>($"select Id,LineKey from {dateBaseTable} where _IsDeleted=0");//返回動態型別 isExstisTable = true; } //取資料 #region 取資料 int firtRowNum = sheet.FirstRowNum; int lastRowNum = sheet.LastRowNum; List<string> updateColumnName = new List<string>(); //處理行 for (int j = firtRowNum; j < lastRowNum; j++) { IRow row = sheet.GetRow(j); DataRow dataRow = isExstisTable ? updateTable.NewRow() : dataTable.NewRow(); if (row == null) row = sheet.CreateRow(j); int firstCellNum = row.FirstCellNum; int lastCellNum = row.LastCellNum; Dictionary<string, object> keyValues = new Dictionary<string, object>(); //處理單元格 for (int k = firstCellNum; k < lastCellNum; k++) { if (j == 21) { } object cellValue = null; ICell cell = row.GetCell(k); if (cell == null) cell = row.CreateCell(k); switch (cell.CellType) { case CellType.Unknown: cellValue = cell.StringCellValue; break; case CellType.Numeric: if (DateUtil.IsCellDateFormatted(cell)) cellValue = cell.DateCellValue; else cellValue = cell.NumericCellValue; break; case CellType.String: cellValue = cell.StringCellValue; break; case CellType.Formula: cellValue = cell.StringCellValue; break; case CellType.Blank: cellValue = cell.StringCellValue; break; case CellType.Boolean: cellValue = cell.StringCellValue; break; case CellType.Error: cellValue = cell.StringCellValue; break; default: cellValue = cell.StringCellValue; break; } Type type = cellValue.GetType(); if (j == firtRowNum) { if (cellValue.ToString().IsNullOrWhiteSpace()) continue; if (isExstisTable) { if (k >= DayValueStartColumn) updateTable.Columns.Add("dateId_" + cellValue.ToString().Replace("-", ""), Type.GetType("System.String")); else updateTable.Columns.Add(columnsStr[k], Type.GetType("System.String")); } else { if (k >= DayValueStartColumn) dataTable.Columns.Add("dateId_" + cellValue.ToString().Replace("-", ""), Type.GetType("System.String")); else dataTable.Columns.Add(columnsStr[k], Type.GetType("System.String")); } } else { if (k < DayValueStartColumn) { keyValues.Add(columnsStr[k], cellValue); if (dicfileValues.ContainsKey(j)) dicfileValues[j] = keyValues; else dicfileValues.Add(j, keyValues); } if (cellValue.ToString().IsNullOrWhiteSpace()) continue; if (k >= DayValueStartColumn) dataRow[k] = Convert.ToInt32(cellValue); else dataRow[k] = cellValue; boolRow = true; } } if (j != firtRowNum) { string LineKey = null; if (!dicfileValues.ContainsKey(j)) continue; LineKey = dicfileValues[j]["factory"].ToString() + "@" + dicfileValues[j]["customerCode"] + "@" + dicfileValues[j]["projectNo"] + "@" + dicfileValues[j]["modelName"]; if ("@@@".Equals(LineKey.Trim(' '))) continue; if (isExstisTable) { dateBaseModel = checkBaseDate.Find(s => s.LineKey == LineKey); //var KAKAK= dataRow; //= dataTable.NewRow(); } } if (isExstisTable && boolRow) { if (dateBaseModel == null) { if (isClonTable) { dataTable = updateTable.Clone(); isClonTable = false; } dataTable.TableName = dateBaseTable + "@Insert"; dataTable.Rows.Add(dataRow.ItemArray); } else updateTable.Rows.Add(dataRow); } else { if (boolRow) dataTable.Rows.Add(dataRow); } } #endregion if (isExstisTable) { if (updateTable.Rows.Count > 0) dataSet.Tables.Add(updateTable); if (dataTable.Rows.Count>0) dataSet.Tables.Add(dataTable); } else dataSet.Tables.Add(dataTable); SqlBulkCopyHelper.BulkCopy(dataSet, planMain, CurrentUser, checkBaseDate, dateBaseTable, isExstisTable); } watch.Stop(); //停止監視 TimeSpan timespan = watch.Elapsed; //獲取當前例項測量得出的總時間 Trace.WriteLine(string.Format("開啟視窗程式碼執行時間:{0}(毫秒)", timespan.TotalMilliseconds)); //總毫秒數 return null; } public static class SqlBulkCopyHelper { public static void BulkCopy(DataSet dataSet, DemandPlan demandplan, SysUser user,List<dynamic> checkBaseDate, string dateBaseTable, bool isExstisTable=false) { List<string> dataTableNames = new List<string>(); for (int g = 0; g < dataSet.Tables.Count; g++) { string TableName = dataSet.Tables[g].TableName; dataTableNames.Add(TableName); dataSet.Tables[g].Columns.Add("LineKey", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("_UpdateTime", Type.GetType("System.DateTimeOffset")); dataSet.Tables[g].Columns.Add("_UpdatedBy", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("OperateFlag", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("Id", Type.GetType("System.Int64")).SetOrdinal(0); dataSet.Tables[g].Columns.Add("DemandPlanId", Type.GetType("System.Int64")).SetOrdinal(1); dataSet.Tables[g].Columns.Add("GroupKey", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("Month", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("Seq", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("_CreateTime", Type.GetType("System.DateTimeOffset")); dataSet.Tables[g].Columns.Add("_CreatedBy", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("_IsDeleted", Type.GetType("System.Boolean")); dataSet.Tables[g].Columns.Add("_DeletedBy", Type.GetType("System.String")); dataSet.Tables[g].Columns.Add("_DeleteTime", Type.GetType("System.DateTimeOffset")); dataSet.Tables[g].Columns.Add("Timestamp", Type.GetType("System.Int64")); long GroupKey = long.MinValue; List<dynamic> updateList = new List<dynamic>(); try { for (int i = 0; i < dataSet.Tables[g].Rows.Count; i++) { dynamic dateBaseModel = null; string LineKey = dataSet.Tables[g].Rows[i]["factory"].ToString() + "@" + dataSet.Tables[g].Rows[i]["customerCode"] + "@" + dataSet.Tables[g].Rows[i]["projectNo"] + "@" + dataSet.Tables[g].Rows[i]["modelName"]; if (isExstisTable) dateBaseModel = checkBaseDate.Find(s => s.LineKey == LineKey); dataSet.Tables[g].Rows[i]["Id"] = TableName.Contains("Update")? dateBaseModel.Id : SnowFlakeSingle.Instance.NextId(); dataSet.Tables[g].Rows[i]["DemandPlanId"] = demandplan.Id; if (i % 3 == 0) { GroupKey = long.Parse(dataSet.Tables[g].Rows[i]["Id"].ToString()); } dataSet.Tables[g].Rows[i]["GroupKey"] = GroupKey; dataSet.Tables[g].Rows[i]["LineKey"] = LineKey; dataSet.Tables[g].Rows[i]["Month"] = demandplan.Month; dataSet.Tables[g].Rows[i]["OperateFlag"] = EntityCode.DemandPlanDataOperateFlag.Create; dataSet.Tables[g].Rows[i]["_CreateTime"] = DateTimeOffset.Now; dataSet.Tables[g].Rows[i]["_CreatedBy"] = user._CreatedBy; dataSet.Tables[g].Rows[i]["_IsDeleted"] = false; } } catch (Exception ex) { throw; } } DataTable InsertTable = dataSet.Tables[dataTableNames.Where(s => s.Contains("Insert")).FirstOrDefault()]; DataTable UpdateTable = dataSet.Tables[dataTableNames.Where(s => s.Contains("Update")).FirstOrDefault()]; if (!isExstisTable) { StringBuilder sqlCreate = new StringBuilder(); List<string> columnName = new List<string>(); if (UpdateTable ==null&& InsertTable != null && InsertTable.Rows.Count > 0) { for (int i = 0; i < InsertTable.Columns.Count; i++) { switch (InsertTable.Columns[i].ColumnName) { case "Id": columnName.Add("[Id] [bigint] NOT NULL primary key"); break; case "DemandPlanId": columnName.Add("[DemandPlanId] [bigint] NOT NULL FOREIGN KEY REFERENCES [dbo].[DemandPlan](Id)"); break; default: if (InsertTable.Columns[i].DataType == Type.GetType("System.Int64")) columnName.Add($"[{InsertTable.Columns[i].ColumnName}] [bigint] NULL"); else if (InsertTable.Columns[i].DataType == Type.GetType("System.DateTimeOffset")) columnName.Add($"[{InsertTable.Columns[i].ColumnName}] [datetimeoffset](7) NULL"); else if (InsertTable.Columns[i].DataType == Type.GetType("System.Boolean")) columnName.Add("[" + InsertTable.Columns[i].ColumnName + "] [bit] NULL"); else columnName.Add("[" + InsertTable.Columns[i].ColumnName + "] [nvarchar](255) NULL"); break; } } sqlCreate.Append($" CREATE TABLE {dateBaseTable}(").Append(string.Join(",", columnName)).Append($")"); SugarClient.Default.Context.Ado.ExecuteCommand(sqlCreate.ToString()); var defaultDbStr = App.GetService<IConfiguration>(); string sqlConnection = defaultDbStr.GetConnectionString(DbNames.DefaultDb.ToString()); using (var bulk = new SqlBulkCopy(sqlConnection)) { bulk.DestinationTableName = dateBaseTable; bulk.WriteToServer(InsertTable); } } if (UpdateTable != null && InsertTable != null) SqlSugarBulkUpdate(InsertTable, UpdateTable, dateBaseTable); } else SqlSugarBulkUpdate(InsertTable, UpdateTable, dateBaseTable); } /// <summary> /// SqlSugar 批量更新/新增 /// </summary> /// <param name="InsertTable">新增資料的DataTable</param> /// <param name="UpdateTable">更新資料的DataTable</param> /// <param name="dateBaseTableName">目標資料庫表名</param> public static void SqlSugarBulkUpdate(DataTable InsertTable, DataTable UpdateTable, string dateBaseTableName) { try { if (InsertTable != null && InsertTable.Rows.Count > 0) { SugarClient.Default.Context.Fastest<DataTable>().AS(dateBaseTableName).BulkCopy(dateBaseTableName, InsertTable); } if (UpdateTable != null && UpdateTable.Rows.Count > 0) SugarClient.Default.Context.Fastest<DataTable>().AS(dateBaseTableName).BulkUpdate(UpdateTable, new string[] { "Id" }); } catch (Exception ex) { throw; } } }