1. 程式人生 > 其它 >使用NPOI解析Excel、SqlSugar 批量入庫\更新、SqlBulkCopy入庫

使用NPOI解析Excel、SqlSugar 批量入庫\更新、SqlBulkCopy入庫

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;
            }
        }

    }