using JNPF.Common.Configuration; using JNPF.Common.Core.Manager; using JNPF.Common.Core.Manager.Files; using JNPF.Common.Models; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.Systems.Common; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.SS.Util; using NPOI.XSSF.UserModel; using SqlSugar; using Tnb.PerMgr.Entities; using Tnb.PerMgr.Interfaces; namespace Tnb.PerMgr { /// /// 工艺标准 /// [ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 700)] [Route("api/[area]/[controller]/[action]")] public class PerProcessStandardsService : IPerProcessStandardsService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _repository; private readonly IUserManager _userManager; private readonly FileManager _fileManager; private readonly FileService _fileService; public PerProcessStandardsService(ISqlSugarRepository repository, FileService fileService, FileManager fileManager, IUserManager userManager) { _userManager = userManager; _repository = repository; _fileManager = fileManager; _fileService = fileService; } [AllowAnonymous] [HttpGet] public async Task ExportTemplate() { try { var db = _repository.AsSugarClient(); string[] perProcessParamTypes = await db.Queryable().OrderBy(x => x.ordinal).Select(x => x.name).ToArrayAsync(); string[] perProcessParams = await db.Queryable().OrderBy(x => x.ordinal).Select(x => x.name).ToArrayAsync(); XSSFWorkbook workbook = new XSSFWorkbook(); NPOI.SS.UserModel.ISheet sheet = workbook.CreateSheet("BOM详情"); IRow row1 = sheet.CreateRow(0); string[] titles = new[] { "工艺参数类型", "工艺参数", "设定值" }; for (int i = 0; i < titles.Length; i++) { ICell cell1 = row1.CreateCell(i); cell1.SetCellValue(titles[i]); sheet.SetColumnWidth(i, 15 * 256); } // int rowIndex = 1; // var column = sheet.GetColumn(0); // 设置下拉项 var validationHelper = sheet.GetDataValidationHelper(); var constraint = validationHelper.CreateExplicitListConstraint(perProcessParamTypes); var region = new CellRangeAddressList(1, 1000, 0, 0); var validation = validationHelper.CreateValidation(constraint, region); sheet.AddValidationData(validation); var constraint2 = validationHelper.CreateExplicitListConstraint(perProcessParams); var region2 = new CellRangeAddressList(1, 1000, 1, 1); var validation2 = validationHelper.CreateValidation(constraint2, region2); sheet.AddValidationData(validation2); MemoryStream ms = new MemoryStream(); workbook.Write(ms); MemoryStream ms2 = new MemoryStream(ms.ToArray()); ms2.Position = 0; FileStreamResult fileStreamResult = new FileStreamResult(ms2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "template.xlsx" }; return fileStreamResult; } catch (Exception e) { Console.WriteLine(e); throw Oops.Bah("导出失败"); } } [HttpPost] public async Task> Import([FromForm] string id, [FromForm] ChunkModel input) { int rowIndex = 1; bool flag = false; IWorkbook? workbook = null; try { using (Stream stream = input.file.OpenReadStream()) { // 2007版本 if (input.fileName.IndexOf(".xlsx") > 0) workbook = new XSSFWorkbook(stream); else if (input.fileName.IndexOf(".xls") > 0) workbook = new HSSFWorkbook(stream); ISheet? sheet = workbook?.GetSheetAt(0); if (workbook == null || sheet == null) throw Oops.Bah("无导入数据"); if (sheet?.LastRowNum <= 1) throw Oops.Bah("无导入数据"); var db = _repository.AsSugarClient(); List perProcessParamTypes = await db.Queryable().ToListAsync(); List perProcessParams = await db.Queryable().ToListAsync(); int errorColumnIndex = 5; ICellStyle style = workbook.CreateCellStyle(); IFont font = workbook.CreateFont(); font.Color = IndexedColors.Red.Index; // 将字体颜色设置为红色 style.SetFont(font); List list = new List() { }; for (rowIndex = 1; rowIndex <= sheet?.LastRowNum; rowIndex++) { IRow row = sheet.GetRow(rowIndex); ICell cell0 = row.GetCell(0); ICell cell1 = row.GetCell(1); ICell cell2 = row.GetCell(2); PerProcessStandardsD item = new PerProcessStandardsD(); item.process_standards_id = id; PerProcessParamType? perProcessParamType = perProcessParamTypes.FirstOrDefault(x => x.name == cell0.StringCellValue); if (perProcessParamType != null) { item.process_param_type_id = perProcessParamType.id; } else { ICell errorCell = row.GetCell(errorColumnIndex) ?? row.CreateCell(errorColumnIndex); errorCell.SetCellValue(",无该工艺参数类型"); errorCell.CellStyle = style; flag = true; } PerProcessParam? perProcessParam = perProcessParams.FirstOrDefault(x => x.name == cell1.StringCellValue); if (perProcessParam != null) { item.process_param_id = perProcessParam.id; } else { ICell errorCell = row.GetCell(errorColumnIndex) ?? row.CreateCell(errorColumnIndex); errorCell.SetCellValue(errorCell.StringCellValue + ",无该工艺参数"); errorCell.CellStyle = style; flag = true; } if (!TrySetNumberCellValue(cell2, ref item)) { ICell errorCell = row.GetCell(errorColumnIndex) ?? row.CreateCell(errorColumnIndex); errorCell.SetCellValue(errorCell.StringCellValue + ",设定值不是数字"); errorCell.CellStyle = style; flag = true; } else { list.Add(item); } if (row.GetCell(errorColumnIndex) != null) { row.GetCell(errorColumnIndex).SetCellValue(row.GetCell(errorColumnIndex).StringCellValue.Substring(1)); } } foreach (var item in list) { PerProcessStandardsD oldData = await _repository.AsSugarClient().Queryable() .FirstAsync(x => x.process_param_id == item.process_param_id && x.process_param_type_id == item.process_param_type_id && x.process_standards_id == id); if (oldData != null) { if (oldData.value != item.value) { PerProcessStandardsH perProcessStandardsH = await _repository.AsSugarClient().Queryable().SingleAsync(x => x.id == oldData.process_standards_id); PerProcessParam processParam = await _repository.AsSugarClient().Queryable().SingleAsync(x => x.id == oldData.process_param_id); await _repository.AsSugarClient().Updateable() .SetColumns(x => x.value == item.value) .Where(x => x.id == oldData.id).ExecuteCommandAsync(); PerProcessParamEditRecord record = new PerProcessParamEditRecord { process_param_id = item.process_param_id, old_value = oldData.value, new_value = item.value, modify_id = _userManager.UserId, modify_time = DateTime.Now, org_id = _userManager.GetUserInfo().Result.organizeId, equip_id = perProcessStandardsH.equip_id, process_param_name = processParam.name }; await _repository.AsSugarClient().Insertable(record).ExecuteCommandAsync(); } } else { await _repository.AsSugarClient().Insertable(item).ExecuteCommandAsync(); } } if (flag) { MemoryStream ms = new MemoryStream(); workbook?.Write(ms); string fileName = $"工艺标准导入报错{DateTime.Now.Ticks}.xlsx"; using (MemoryStream ms2 = new MemoryStream(ms.ToArray())) { ms2.Position = 0; await _fileManager.UploadFileByType(ms2, FileVariable.TemporaryFilePath, fileName); } return new Dictionary() { ["isSuccess"] = "false", ["msg"] = "部分数据导入失败", ["fileName"] = fileName, }; } else { return new Dictionary() { ["isSuccess"] = "true", ["msg"] = "导入成功", }; } } } catch (Exception e) { Console.WriteLine(e.Message); JNPF.Logging.Log.Error("工艺标准导入失败", e); throw Oops.Bah("导入失败"); } } private bool TrySetNumberCellValue(ICell cell, ref PerProcessStandardsD item) { try { item.value = cell.CellType == CellType.Numeric ? (decimal)cell.NumericCellValue : cell.CellType == CellType.String ? Convert.ToDecimal(cell.StringCellValue) : 0; return true; } catch (Exception e) { Console.WriteLine(e); return false; } } } }