From 2c4fa252ebb8d77d0f0f624dc615cfaf52bfdf09 Mon Sep 17 00:00:00 2001 From: xiaochanghai Date: Thu, 23 May 2024 17:16:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EExcel=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/CommonController.cs | 16 + Tiobon.Core.Api/Tiobon.Core.xml | 10 + Tiobon.Core.DataAccess/ReportHelper.cs | 791 +++++++++++++++++- Tiobon.Core.IServices/ICommonServices.cs | 5 +- Tiobon.Core.Services/BASE/BaseServices.cs | 8 +- Tiobon.Core.Services/CommonServices.cs | 19 + 6 files changed, 825 insertions(+), 24 deletions(-) diff --git a/Tiobon.Core.Api/Controllers/CommonController.cs b/Tiobon.Core.Api/Controllers/CommonController.cs index 8eeaeb3a..20d0b592 100644 --- a/Tiobon.Core.Api/Controllers/CommonController.cs +++ b/Tiobon.Core.Api/Controllers/CommonController.cs @@ -87,4 +87,20 @@ public class CommonController : BaseApiController return await _commonServices.DownImportTemplateAsync(param); } #endregion + + #region Excel导入 + /// + /// Excel导入 + /// + /// 文件 + /// 菜单编号 + /// 用户ID + /// 多语 + /// + [HttpPost, Route("ImportExcel")] + public async Task> ImportExcelAsync(IFormFile file, string menuName, int userId, int langId = 1) + { + return await _commonServices.ImportExcelAsync(file, menuName, langId, userId); + } + #endregion } \ No newline at end of file diff --git a/Tiobon.Core.Api/Tiobon.Core.xml b/Tiobon.Core.Api/Tiobon.Core.xml index 76d9be3c..30a5ca4f 100644 --- a/Tiobon.Core.Api/Tiobon.Core.xml +++ b/Tiobon.Core.Api/Tiobon.Core.xml @@ -272,6 +272,16 @@ + + + Excel导入 + + 文件 + 菜单编号 + 用户ID + 多语 + + 构造函数 diff --git a/Tiobon.Core.DataAccess/ReportHelper.cs b/Tiobon.Core.DataAccess/ReportHelper.cs index 151cc51c..e5803809 100644 --- a/Tiobon.Core.DataAccess/ReportHelper.cs +++ b/Tiobon.Core.DataAccess/ReportHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data; @@ -7,8 +8,6 @@ using System.Linq; using System.Linq.Dynamic.Core; using System.Text; using System.Threading.Tasks; -using Google.Protobuf.Collections; -using Microsoft.AspNetCore.Mvc.ModelBinding; using NPOI.HSSF.UserModel; using NPOI.OpenXmlFormats.Spreadsheet; using NPOI.SS.UserModel; @@ -16,7 +15,6 @@ using NPOI.SS.Util; using NPOI.XSSF.UserModel; using SqlSugar; using Tiobon.Core.Common; -using Tiobon.Core.Common.DB.Dapper; using Tiobon.Core.Common.Extensions; using Tiobon.Core.Model.Models; @@ -294,22 +292,6 @@ public static class ReportHelper } } - ////月排班维护写入下拉数据 - //if (menuName == "F_SchedulePeriodSetup") - //{ - // string listSql = @" select ParaDetailNo 日期类别编号,ParaDetailName 日期类别名称 from Ghrs_ParaDetail where ParaMasterNo = 'DateType' and IsEnable = 1; - // select ShiftNo 班次编号,ShiftName 班次名称 from Ghrb_Shift where IsEnable = 1; - // select ShiftGroupNo 班组编号,ShiftGroupName 班组名称 from Ghrb_ShiftGroup where IsEnable = 1; "; - // InsertExcelList(sheet2, listSql); - //} - //// 生成部门Sheet - //if (tableColumn.Rows.Cast().Any(x => x["dataSource"].ToString().StartsWith("OrgTreeWith"))) - //{ - // ISheet sheetDept = fileWorkbook.CreateSheet("部门数据"); - // string listSql = @" select DeptNo 部门编号,DeptName 部门名称 from Ghro_Dept where IsEnable = 1 and convert(date,getdate()) between BeginDate and ISNULL(EndDate,'2099-12-31') "; - // InsertExcelList(sheetDept, listSql); - //} - // Sheet 更改列为自适应宽度 for (int col = 0; col <= ColNums; col++) { @@ -523,6 +505,726 @@ public static class ReportHelper return IsBool; } + /// + /// 是否隐藏首行 + /// + public static bool IsHideTopRow = false; + + /// + /// 读取Excel写入临时表,逻辑在存储过程里写 + /// + /// + public static async Task ExcelToDataTable(ISqlSugarClient Db, string FilePath, string menuName, int LangID, int UserID, string doType = null, string procName = null) + { + string result = string.Empty; + int ErrorNum = 0; + int SuccessNum = 0; + DataTable mydt = GetDataTable(FilePath, 0, null); + if (mydt.Columns["Comments"] == null) + { + mydt.Columns.Add("Comments", typeof(string)); + } + mydt.Rows[0]["Comments"] = "提示信息"; + + //从第二行开始读取 + int FirstI = 1; + IsHideTopRow = true; + //创建GUID; + string guidN = Guid.NewGuid().ToString("N"); + + DataTable edt = new DataTable(); + edt.Columns.Add("ExcelNums", typeof(int));// + edt.Columns.Add("GID", typeof(string));// + edt.Columns.Add("LangID", typeof(int));// + edt.Columns.Add("UserID", typeof(int));// + edt.Columns.Add("DoType", typeof(string));// + edt.Columns.Add("ProcName", typeof(string));// + edt.Columns.Add("MenuName", typeof(string));// + edt.Columns.Add("JsonColumns", typeof(string));// + + // 获取对应的字段设定 + DataSet ds = new DataSet(); + if (menuName != "F_SchedulePeriodSetup") + ds = await GetTableColumn(Db, LangID, UserID, menuName, null); + DataTable tableColumn = ds.Tables.Count > 0 ? ds.Tables[0] : new DataTable(); + + List dataSourceLists = new List(); + foreach (DataRow dr in tableColumn.Rows) + { + // 验证导入列是否一致 + if (!mydt.Columns.Contains(dr["field"].ToString()) && doType != "Update") + { + throw new Exception("导入模板不匹配或模板字段已更新,请重新下载导入模板"); + } + + string dataSource = dr["dataSource"].ToString(); + string field = dr["field"].ToString(); + if (!string.IsNullOrEmpty(dataSource)) + { + List dataSourceList = GetDataSourceLists(Db, field, dataSource); + dataSourceLists.AddRange(dataSourceList); + } + } + int AllNums = 0; + // 判断是否为流程,流程直接返回对应信息 + string IsFlow = "N"; + + + StringBuilder jsonListBuilder = new StringBuilder(); + jsonListBuilder.Append("["); + + //循环读取的Excel行 + for (int i = FirstI; i < mydt.Rows.Count; i++) + { + AllNums++; + StringBuilder jsonBuilder = new StringBuilder(); + jsonBuilder.Append("{"); + string errorMsg = string.Empty; + //// 遍历列 + foreach (DataColumn dc in mydt.Columns) + { + if (dc.ColumnName != "Process" && dc.ColumnName != "Comments" && dc.ColumnName != "" && dc.ColumnName != "ExcelNums") + { + string value = mydt.Rows[i][dc.ColumnName].ToString(); + string value_label = value; + + //判断对应的字段设定 + DataRow[] rows = ds.Tables.Count > 0 ? tableColumn.Select(" field = '" + dc.ColumnName + "' ") : null; + + if (rows != null && rows.Length > 0) + { + DataRow fieldRow = rows[0]; + // 必填字段为空 + if (fieldRow["required"].ToString() == "true" && string.IsNullOrEmpty(value)) + { + errorMsg = errorMsg + fieldRow["label"].ToString() + "不能为空;"; + } + string dataSource = fieldRow["dataSource"].ToString(); + + //下拉数据反读值 + //if (!string.IsNullOrEmpty(dataSource) && !string.IsNullOrEmpty(value) + // // 默认值处理 + // && !(value == "*" && menuName.StartsWith("F_StaffChange"))) + //{ + // //// Dept + // if (dataSource.StartsWith("OrgTreeWith")) + // { + // string DeptID = string.Empty; + // // 部门需要一级一级写入,不判断父级层级 + // if (menuName != "F_AllDept" && menuName != "F_Dept") + // { + // try + // { + // //验证部门编号填写是否错误 + // string DeptTest = string.Format(@"select STUFF((select ','+value + // from dbo.Fs1_GHR30_SplitString('{0}',',') + // where value != '' and value not in (select DeptNo from Ghro_Dept where ISEnable=1) + // for XML path(''),type).value('.','nvarchar(max)'),1,1,'');", + // value); + // DeptTest = DataAccess.SelectSingleValueNotKey("SqlGhr30" + "Demo", DeptTest).ToString(); + // if (!String.IsNullOrEmpty(DeptTest)) + // { + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值(" + DeptTest + ")错误;"; + // } + // else + // { + // string deptExists = string.Format(@"select stuff((select ',' + CONVERT(nvarchar(10),DeptID) + // from Ghro_Dept + // where IsEnable=1 + // and DeptNo in (select value from dbo.Fs1_GHR30_SplitString('{0}',',')) + // for XML path(''),type).value('.','nvarchar(max)'),1,1,'');", + // value); + // DeptID = DataAccess.SelectSingleValueNotKey("SqlGhr30" + "Demo", deptExists).ToString(); + // value = DeptID; + // //if (String.IsNullOrEmpty(value)) + // // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值错误;"; + // } + // } + // catch (Exception) + // { + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值错误;"; + // } + // } + // } + // //// Staff + // else if (dataSource.StartsWith("StaffWith")) + // { + // string StaffID = string.Empty; + // try + // { + // //验证工号填写是否错误 + // string StaffTest = string.Format(@"select STUFF((select ','+value + // from dbo.Fs1_GHR30_SplitString('{0}',',') + // where value != '' and value not in (select StaffNo from Ghra_Staff where ISEnable=1) + // for XML path(''),type).value('.','nvarchar(max)'),1,1,'');", + // value); + // StaffTest = DataAccess.SelectSingleValueNotKey("SqlGhr30" + "Demo", StaffTest).ToString(); + // if (!String.IsNullOrEmpty(StaffTest)) + // { + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值(" + StaffTest + ")错误;"; + // } + // else + // { + // string staffExists = string.Format(@"select stuff((select ',' + CONVERT(nvarchar(10),StaffID) + // from Ghra_Staff + // where IsEnable=1 + // and StaffNo in (select value from dbo.Fs1_GHR30_SplitString('{0}',',')) + // for XML path(''),type).value('.','nvarchar(max)'),1,1,'');", + // value); + + // StaffID = DataAccess.SelectSingleValueNotKey("SqlGhr30" + "Demo", staffExists).ToString(); + // value = StaffID; + // if (String.IsNullOrEmpty(value)) + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值错误;"; + // } + // } + // catch (Exception) + // { + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值错误;"; + // } + // } + // else + // { + // try + // { + // // 多选 + // if (fieldRow["elementType"].ToString().LastIndexOf("multiple") == -1) + // { + // DataSourceList nList = dataSourceLists.First(t => t.name == value && t.field == dc.ColumnName); + // if (nList != null) + // { + // if (String.IsNullOrEmpty(nList.id)) + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值错误;"; + // else + // value = nList.id; + // } + // } + // else + // { + // string errorValue = string.Empty; + // string newValue = "["; + // foreach (var sp in value.Split(',')) + // { + // DataSourceList nList = dataSourceLists.First(t => t.name == sp && t.field == dc.ColumnName); + + // if (nList != null) + // { + // if (String.IsNullOrEmpty(nList.id)) + // errorValue = errorValue + fieldRow["label"].ToString() + ","; + // else + // newValue = newValue + "\"" + nList.id + "\","; + // } + // else + // { + // errorValue = errorValue + fieldRow["label"].ToString() + ","; + // } + // } + // if (!string.IsNullOrEmpty(errorValue)) + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值(" + errorValue + ")错误;"; + // else + // value = newValue.TrimEnd(',') + "]"; + // } + // } + // catch (Exception) + // { + // errorMsg = errorMsg + fieldRow["label"].ToString() + "输入值错误;"; + // value = "0"; + // } + // } + //} + // 部门需要一级一级写入,不判断父级层级 + if (menuName != "F_AllDept" && menuName != "F_Dept" + && fieldRow["field"].ToString().IndexOf("ParentDeptID") > 0 + && !(value == "*" && menuName.StartsWith("F_StaffChange")) + ) + { + // 是否输入整型 + if (fieldRow["dataType"].ToString() == "int" && !string.IsNullOrEmpty(value)) + { + int nums1; + if (!int.TryParse(value, out nums1)) + errorMsg = errorMsg + fieldRow["label"].ToString() + "需为整数;"; + } + // 是否输入数值 + if ((fieldRow["dataType"].ToString() == "decimal" || fieldRow["dataType"].ToString() == "number") + && !string.IsNullOrEmpty(value)) + { + double nums2; + if (!double.TryParse(value, out nums2)) + errorMsg = errorMsg + fieldRow["label"].ToString() + "需为数值;"; + } + } + // 是否输入日期 + if (fieldRow["dataType"].ToString().StartsWith("date") + && !(value == "*" && menuName.StartsWith("F_StaffChange")) + ) + { + if (!string.IsNullOrEmpty(value)) + { + try + { + DateTime date1; + if (!DateTime.TryParse(value, out date1)) + errorMsg = errorMsg + fieldRow["label"].ToString() + "需为日期格式;"; + else if (fieldRow["dataType"].ToString() == "date") + { + value = date1.ToString("yyyy-MM-dd"); + } + } + catch (Exception) + { + errorMsg = errorMsg + fieldRow["label"].ToString() + "(" + value + ")需为日期格式;"; + } + } + else + { + + } + } + if (fieldRow["elementType"].ToString().LastIndexOf("multiple") == -1) + { + jsonBuilder.AppendFormat("\"{0}\":\"{1}\",", + dc.ColumnName, value.Replace('"', '‘').Replace("'", "‘").Trim()); + } + else + { + jsonBuilder.AppendFormat("\"{0}\":{1},", + dc.ColumnName, string.IsNullOrEmpty(value.Trim()) ? "null" : value.Trim()); + } + } + else + { + jsonBuilder.AppendFormat("\"{0}\":\"{1}\",", + dc.ColumnName, value.Replace('"', '‘').Replace("'", "‘").Trim()); + } + + // ESS申请 下拉返回label 值 + if (IsFlow == "Y") + { + jsonBuilder.AppendFormat("\"{0}\":\"{1}\",", + dc.ColumnName + "_Label", value_label.Trim()); + } + } + } + + if (jsonBuilder.Length > 1) + jsonBuilder.Remove(jsonBuilder.Length - 1, 1); + jsonBuilder.Append("}"); + + //判断 是否有错误 + if (!string.IsNullOrEmpty(errorMsg)) + { + mydt.Rows[i]["Comments"] = errorMsg; + ErrorNum++; + } + else + { + DataRow ndr = edt.NewRow(); + ndr["ExcelNums"] = mydt.Rows[i]["ExcelNums"].ToString(); + ndr["GID"] = guidN; + ndr["LangID"] = LangID; + ndr["UserID"] = UserID; + ndr["DoType"] = doType; + ndr["ProcName"] = procName; + ndr["MenuName"] = menuName; + ndr["JsonColumns"] = jsonBuilder.ToString(); + edt.Rows.Add(ndr); + // 写入正确的json + jsonListBuilder.Append(jsonBuilder); + jsonListBuilder.Append(","); + } + } + if (jsonListBuilder.Length > 1) + jsonListBuilder.Remove(jsonListBuilder.Length - 1, 1); + jsonListBuilder.Append("]"); + + + + // 写入Excel待读取 + string createTempSQL = "ExcelNums int,GID nvarchar(100),LangID int,UserID int,DoType nvarchar(200),ProcName nvarchar(200),MenuName nvarchar(200),JsonColumns nvarchar(max)"; + string updateSQL = @"insert into [dbo].[Ghrs_ExcelImportWait] + ([GID],[LangID],[UserID],[DoType], [ProcName], [MenuName], [JsonColumns],[SortNo]) + select[GID],[LangID],[UserID],[DoType], [ProcName],[MenuName] ,[JsonColumns],ExcelNums + from #CTemplateTable"; + + Other.BulkUpdateData("SqlGhr30" + "Demo", edt, createTempSQL, updateSQL); + //Db.Ado.GetDataTable("SqlGhr30" + "Demo", edt, createTempSQL, updateSQL); + + string EssResult = string.Empty; + //调用存储过程 + // GHR 导入 + if (IsFlow == "N") + { + string ReadSQL = string.Format(@"exec[dbo].[PT_GHR30_ReadExcelData] '{0}',{1},{2} ", guidN, LangID, UserID); + await Db.Ado.ExecuteCommandAsync("SqlGhr30" + "Demo", ReadSQL); + + string resultSQL = string.Format(@"select SortNo,ErrorMsg,WarningMsg,SuccessMsg + from Ghrs_ExcelImportResult + where GID = '{0}' + and ISNULL(ErrorMsg,'') != '' ", guidN); + DataTable resultDt = await Db.Ado.GetDataTableAsync(resultSQL); + //写入错误信息 + foreach (DataRow resultDR in resultDt.Rows) + { + string SortNo = resultDR["SortNo"].ToString(); + string ErrorMsg = ""; + ErrorMsg = resultDR["ErrorMsg"].ToString(); + mydt.Select(@"ExcelNums = '" + SortNo + "'")[0]["Comments"] = ErrorMsg; + ErrorNum++; + } + } + else + { + string ReadSQL = string.Format(@"exec[dbo].[PT_GHR30_EssFlowReadExcelData] '{0}',{1},{2} ", guidN, LangID, UserID); + DataTable resultDt = await Db.Ado.GetDataTableAsync(ReadSQL); + + StringBuilder jsonBuilder = new StringBuilder(); + jsonBuilder.Append("["); + + foreach (DataRow resultDR in resultDt.Rows) + { + jsonBuilder.Append(resultDR["ResultJson"].ToString() + ","); + string SortNo = resultDR["SortNo"].ToString(); + string ErrorMsg = ""; + ErrorMsg = resultDR["FlowApplyDetailInfo"].ToString(); + if (ErrorMsg != String.Empty) + { + ErrorNum++; + mydt.Select(@"ExcelNums = '" + SortNo + "'")[0]["Comments"] = ErrorMsg; + } + } + + if (jsonBuilder.Length > 1) + jsonBuilder.Remove(jsonBuilder.Length - 1, 1); + jsonBuilder.Append("]"); + + EssResult = jsonBuilder.ToString(); + } + + SuccessNum = AllNums - ErrorNum; + File.Delete(FilePath); //先删除,再保存。 + //将写入结果导出为Excel + GetExcelByDataTable(mydt, FilePath); + + // 流程直接返回读取信息 + if (IsFlow == "Y") + { // 流程直接返回读取信息 + return EssResult; + } + try + { + DataTable ErrorTable = mydt;// GetNewDataTable(mydt, "Process = '' ", ""); + //DataRow[] foundRow; + //foundRow = ErrorTable.Select("Comments != ''"); + //if (foundRow != null && foundRow.Count() > 0) + //{ + // foreach (DataRow row in foundRow) + // { + // ErrorTable.Rows.Remove(row); + // } + //} + //ErrorTable.AcceptChanges();//对DataTable(全部)操作完之后,一定要执行这一步,否则结果不保存 + + //if (ErrorTable.Rows.Count > 0) + //result = GHR.Common.DBCommon.ToJson(ErrorTable); + } + catch (Exception ex) + { + result = "[{\"readerror\":\"" + ex.Message + "\"}]"; + } + return result; + } + + /// + /// 根据Excel和Sheet返回DataTable + /// + /// Excel文件地址 + /// Sheet索引 + /// DataTable + public static DataTable GetDataTable(string filePath, int sheetIndex, Dictionary NameContrast) + { + return GetDataSet(filePath, sheetIndex, NameContrast).Tables[0]; + } + + /// + /// 根据Excel返回DataSet + /// + /// Excel文件地址 + /// Sheet索引,可选,默认返回所有Sheet + /// DataSet + public static DataSet GetDataSet(string filePath, int? sheetIndex, Dictionary NameContrast) + { + DataSet ds = new DataSet(); + IWorkbook fileWorkbook; + string FileExt = Path.GetExtension(filePath); + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + if (FileExt == ".xls") + { + try + { + //fileWorkbook = new HSSFWorkbook(fs); + fileWorkbook = new NPOI.HSSF.UserModel.HSSFWorkbook(fs); + } + catch (Exception ex) + { + throw ex; + } + } + else if (FileExt == ".xlsx") + { + try + { + fileWorkbook = new NPOI.XSSF.UserModel.XSSFWorkbook(fs); + } + catch (Exception ex) + { + throw ex; + } + } + else fileWorkbook = null; + } + + for (int i = 0; i < fileWorkbook.NumberOfSheets; i++) + { + if (sheetIndex != null && sheetIndex != i) + continue; + DataTable dt = new DataTable(); + ISheet sheet = fileWorkbook.GetSheetAt(i); + + //表头 + IRow header = sheet.GetRow(sheet.FirstRowNum); + List columns = new List(); + for (int j = 0; j < header.LastCellNum; j++) + { + object obj = new object(); + if (FileExt == ".xls") + { + obj = GetValueTypeForXLS(header.GetCell(j) as HSSFCell); + } + else if (FileExt == ".xlsx") + { + obj = GetValueTypeForXLS(header.GetCell(j) as XSSFCell); + } + else { obj = null; } + + if (obj == null || obj.ToString() == string.Empty) + { + dt.Columns.Add(new DataColumn("Columns" + j.ToString())); + } + else + { + dt.Columns.Add(new DataColumn(obj.ToString())); + //try + //{ + // dt.Columns.Add(new DataColumn(NameContrast[obj.ToString()].ToString())); + //} + //catch (Exception) + //{ + // dt.Columns.Add(new DataColumn(obj.ToString())); + //} + } + columns.Add(j); + } + //数据 + IEnumerator rows = sheet.GetEnumerator(); + int n = sheet.FirstRowNum + 1; + while (rows.MoveNext()) + { + DataRow dr = dt.NewRow(); + bool hasValue = false; + foreach (int K in columns) + { + try + { + dr[K] = GetValueTypeForXLS(sheet.GetRow(n).GetCell(K) as HSSFCell); + if (FileExt == ".xls") + { + dr[K] = GetValueTypeForXLS(sheet.GetRow(n).GetCell(K) as HSSFCell); + } + else if (FileExt == ".xlsx") + { + dr[K] = GetValueTypeForXLS(sheet.GetRow(n).GetCell(K) as XSSFCell); + } + else dr[K] = null; + if (dr[K] != null && dr[K].ToString() != string.Empty) + { + hasValue = true; + } + } + catch + { + hasValue = false; + } + } + if (hasValue) + { + dt.Rows.Add(dr); + } + n++; + } + ds.Tables.Add(dt); + } + + return ds; + } + + /// + /// 根据DataTable导出Excel + /// + /// DataTable + /// 保存地址 + public static bool GetExcelByDataTable(DataTable dt, string file) + { + DataSet ds = new DataSet(); + DataTable NewDT = dt.Copy(); + ds.Tables.Add(NewDT); + return GetExcelByDataSet(ds, file); + } + + /// + /// 根据DataSet导出Excel + /// + /// DataSet + /// 保存地址 + public static bool GetExcelByDataSet(DataSet ds, string file) + { + try + { + IWorkbook fileWorkbook; + if (Path.GetExtension(file) == ".xls") + { + fileWorkbook = new HSSFWorkbook(); + } + else + { + fileWorkbook = new XSSFWorkbook(); + } + int index = 0; + foreach (DataTable dt in ds.Tables) + { + index++; + ISheet sheet = fileWorkbook.CreateSheet("Sheet" + index); + + //表头 + IRow row = sheet.CreateRow(0); + for (int i = 0; i < dt.Columns.Count; i++) + { + ICell cell = row.CreateCell(i); + cell.SetCellValue(dt.Columns[i].ColumnName); + } + // 隐藏首行 + if (IsHideTopRow) + row.HeightInPoints = 1; + + //数据 + for (int i = 0; i < dt.Rows.Count; i++) + { + IRow row1 = sheet.CreateRow(i + 1); + for (int j = 0; j < dt.Columns.Count; j++) + { + ICell cell = row1.CreateCell(j); + cell.SetCellValue(dt.Rows[i][j].ToString()); + } + } + } + + //转为字节数组 + MemoryStream stream = new MemoryStream(); + fileWorkbook.Write(stream); + var buf = stream.ToArray(); + + //保存为Excel文件 + using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write)) + { + fs.Write(buf, 0, buf.Length); + fs.Flush(); + } + return true; + } + catch (Exception ex) + { + return false; + } + } + /// + /// 获取新增表的字段设定(导入需要) + /// + /// + /// + public static async Task GetTableColumn(ISqlSugarClient Db, int langId, int userId, string menuName, string jsonParam) + { + string SQL = String.Format(@"exec [PT_GHR30_GetExcelEditColumn] '{1}',0,{2},{3}, '{0}','Import'", menuName, jsonParam, langId, userId); + // 第一张表 表头设定 + // 第二张表 写入默认值 + DataSet ds = await Db.Ado.GetDataSetAllAsync("SqlGhr30" + "Demo", SQL); + + return ds; + } + + /// + /// 根据单元格将内容返回为对应类型的数据 + /// + /// 单元格 + /// 数据 + private static object GetValueTypeForXLS(HSSFCell cell) + { + if (cell == null) + return null; + switch (cell.CellType) + { + case CellType.Blank: //BLANK: + return null; + case CellType.Boolean: //BOOLEAN: + return cell.BooleanCellValue; + case CellType.Numeric: //NUMERIC: + { + if (DateUtil.IsCellDateFormatted(cell)) + return cell.DateCellValue.Value.ToString("yyyy-MM-dd HH:mm"); + else + return cell.NumericCellValue; + } + case CellType.String: //STRING: + return cell.StringCellValue; + case CellType.Error: //ERROR: + return cell.ErrorCellValue; + case CellType.Formula: //FORMULA: + default: + return "=" + cell.CellFormula; + } + } + /// + /// 根据单元格将内容返回为对应类型的数据 + /// + /// 单元格 + /// 数据 + private static object GetValueTypeForXLS(XSSFCell cell) + { + if (cell == null) + return null; + switch (cell.CellType) + { + case CellType.Blank: //BLANK: + return null; + case CellType.Boolean: //BOOLEAN: + return cell.BooleanCellValue; + case CellType.Numeric: //NUMERIC: + { + if (DateUtil.IsCellDateFormatted(cell)) + return cell.DateCellValue.Value.ToString("yyyy-MM-dd HH:mm"); + else + return cell.NumericCellValue; + } + case CellType.String: //STRING: + return cell.StringCellValue; + case CellType.Error: //ERROR: + return cell.ErrorCellValue; + case CellType.Formula: //FORMULA: + default: + return "=" + cell.CellFormula; + } + } + #region 其他 public class Other @@ -558,6 +1260,57 @@ public static class ReportHelper return Num2ABCletter(front) + Level[remainder]; } } + + /// + /// SqlBulkCopy 批量更新数据 + /// + /// 数据集 + /// 临时表创建字段 + /// 更新语句 + public static void BulkUpdateData(string con, DataTable dataTable, string crateTemplateSql, string updateSql) + { + + // ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); + //using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings[con].ConnectionString)) + //{ + // using (var command = new SqlCommand("", conn)) + // { + // try + // { + // conn.Open(); + + // //数据库并创建一个临时表来保存数据表的数据 + // Random ran = new Random(); + // int n = ran.Next(100, 1000); + // command.CommandText = String.Format(" CREATE TABLE #CTemplateTable" + n.ToString() + " ({0})", crateTemplateSql); + // command.ExecuteNonQuery(); + + // //使用SqlBulkCopy 加载数据到临时表中 + // using (var bulkCopy = new SqlBulkCopy(conn)) + // { + // foreach (DataColumn dcPrepped in dataTable.Columns) + // { + // bulkCopy.ColumnMappings.Add(dcPrepped.ColumnName, dcPrepped.ColumnName); + // } + + // bulkCopy.BulkCopyTimeout = 660; + // bulkCopy.DestinationTableName = "#CTemplateTable" + n.ToString(); + // bulkCopy.WriteToServer(dataTable); + // bulkCopy.Close(); + // } + // updateSql = updateSql.Replace("#CTemplateTable", "#CTemplateTable" + n.ToString()); + // // 执行Command命令 使用临时表的数据去更新目标表中的数据 然后删除临时表 + // command.CommandTimeout = 300; + // command.CommandText = updateSql; + // command.ExecuteNonQuery(); + // } + // finally + // { + // conn.Close(); + // } + // } + //} + } } #endregion diff --git a/Tiobon.Core.IServices/ICommonServices.cs b/Tiobon.Core.IServices/ICommonServices.cs index 29040470..f28f367b 100644 --- a/Tiobon.Core.IServices/ICommonServices.cs +++ b/Tiobon.Core.IServices/ICommonServices.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Tiobon.Core.Common; using Tiobon.Core.IServices.BASE; using Tiobon.Core.Model; @@ -26,4 +27,6 @@ public interface ICommonServices : IBaseServices> Task> ExportExcelAsync(QueryExport param); Task> DownImportTemplateAsync(QueryExport param); + + Task> ImportExcelAsync(IFormFile file, string menuName, int langId, int userId); } diff --git a/Tiobon.Core.Services/BASE/BaseServices.cs b/Tiobon.Core.Services/BASE/BaseServices.cs index 23293855..dac278e1 100644 --- a/Tiobon.Core.Services/BASE/BaseServices.cs +++ b/Tiobon.Core.Services/BASE/BaseServices.cs @@ -347,7 +347,7 @@ public class BaseServices : IBaseServ /// /// 更新实体数据 /// - /// 博文实体类 + /// 实体类 /// public async Task Update(long Id, TEditDto editModel) { @@ -393,7 +393,7 @@ public class BaseServices : IBaseServ /// /// 更新实体数据 /// - /// 博文实体类 + /// 实体类 /// public async Task Update(List listEntity) { @@ -434,7 +434,7 @@ public class BaseServices : IBaseServ /// /// 根据实体删除一条数据 /// - /// 博文实体类 + /// 实体类 /// public async Task Delete(TEntity entity) { @@ -732,7 +732,7 @@ public class BaseServices : IBaseServ /// /// 根据实体删除一条数据 /// - /// 博文实体类 + /// 实体类 /// public async Task DeleteSplit(TEntity entity, DateTime dateTime) { diff --git a/Tiobon.Core.Services/CommonServices.cs b/Tiobon.Core.Services/CommonServices.cs index 1ef2728c..f663308a 100644 --- a/Tiobon.Core.Services/CommonServices.cs +++ b/Tiobon.Core.Services/CommonServices.cs @@ -1282,4 +1282,23 @@ public partial class CommonServices : BaseServices>, ICommon } #endregion + #region Excel数据导入 + + public async Task> ImportExcelAsync(IFormFile file, string menuName, int langId, int userId) + { + var fid = SnowFlakeSingle.Instance.NextId(); + var path = $"{$"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}upload{Path.DirectorySeparatorChar}{fid}{Path.DirectorySeparatorChar}"}"; + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + using (var stream = new FileStream(path + file.FileName, FileMode.Create)) + { + await file.CopyToAsync(stream); + } + + var result = new QueryExportReturn(); + + await ReportHelper.ExcelToDataTable(Db, path, menuName, langId, userId); + return new ServiceResult() { Success = true, Message = "查询成功", Data = result, }; + } + #endregion }