using Furion.JsonSerialization; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Data; using YBEE.EQM.Core; namespace YBEE.EQM.Application; /// /// 缺测替补管理服务(用于中心管理) /// public class ExamAbsentReplaceCenterService( IRepository rep, IExportExcelService exportExcelService, ICourseService courseService, IExamPlanService examPlanService ) : IExamAbsentReplaceCenterService, ITransient { /// /// 分页查询监测缺测替补列表 /// /// /// public async Task> QueryPageList(ExamAbsentReplacePageInput input) { var query = GetQueryBase(input); var ret = await query.OrderBy(t => t.SysOrgId).ThenBy(t => t.GradeId).ThenBy(t => t.ClassNumber).ThenBy(t => t.Id) .ProjectToType() .ToADPagedListAsync(input.PageIndex, input.PageSize); return ret; } /// /// 获取状态数量 /// /// public async Task> QueryStatusCount(ExamAbsentReplacePageInput input) { var query = GetQueryBase(input); if (query == null) { return []; } var counts = await query.GroupBy(t => t.Status).Select(t => new StatusCount { Status = (int)t.Key, Count = t.Count() }).ToListAsync(); return counts; } /// /// 导出数据表格(简表) /// /// /// public async Task<(string fileName, byte[] fileBytes)> ExportSimple(ExamAbsentReplacePageInput input) { var examPlan = await examPlanService.GetById(input.ExamPlanId); var query = GetQueryBase(input); var items = await query.OrderBy(t => t.SysOrgId).ThenBy(t => t.GradeId).ThenBy(t => t.ClassNumber).ThenBy(t => t.Id) .ProjectToType() .ToListAsync(); // 科目列表 var courses = await courseService.GetAllLiteList(); // 科目字典 var courseDicts = courses.ToDictionary(t => t.Name); XSSFWorkbook wb = new(); ISheet sheet = wb.CreateSheet("缺测替补名单"); sheet.DisplayGridlines = false; var cellStyle = exportExcelService.GetCellStyle(wb); // 行索引号 int rowNum = 0; #region 列头 IRow headerRow = sheet.CreateRow(rowNum++); int ci = 0; exportExcelService.AddCell("学校", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 20); exportExcelService.AddCell("年级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8); exportExcelService.AddCell("班级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8); exportExcelService.AddCell("缺测姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12); exportExcelService.AddCell("缺测考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16); exportExcelService.AddCell("有无替补", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 10); exportExcelService.AddCell("替补姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12); exportExcelService.AddCell("替补考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16); exportExcelService.AddCell("缺测替补科目", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 50); exportExcelService.AddCell("状态", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8); sheet.CreateFreezePane(0, rowNum); #endregion #region 数据 foreach (var item in items) { IRow row = sheet.CreateRow(rowNum++); int rci = 0; exportExcelService.AddCell(item.SysOrg.Name, row, rci++, cellStyle.LeftCellStyle); exportExcelService.AddCell(item.ExamGrade.Grade.Name, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.ClassNumber, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.AbsentName, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.AbsentExamNumber, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.IsReplaced ? "是" : "否", row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.ReplaceName, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.ReplaceExamNumber, row, rci++, cellStyle.CenterCellStyle); var cs = JSON.Deserialize>(item.AbsentCourses); var cns = string.Join("、", cs.Select(t => t.Name)); exportExcelService.AddCell(cns, row, rci++, cellStyle.LeftCellStyle); exportExcelService.AddCell(item.Status.GetDescription(), row, rci++, cellStyle.CenterCellStyle); } #endregion MemoryStream ms = new(); wb.Write(ms, false); ms.Flush(); return ($"{examPlan.Name}-缺测替补名单.xlsx", ms.ToArray()); } /// /// 导出数据表格(完整) /// /// /// public async Task<(string fileName, byte[] fileBytes)> ExportFull(ExamAbsentReplacePageInput input) { var examPlan = await examPlanService.GetById(input.ExamPlanId); var query = GetQueryBase(input); var items = await query.OrderBy(t => t.SysOrgId).ThenBy(t => t.GradeId).ThenBy(t => t.ClassNumber).ThenBy(t => t.Id) .ProjectToType() .ToListAsync(); // 科目列表 var courses = await courseService.GetAllLiteList(); // 科目字典 var courseDicts = courses.ToDictionary(t => t.Name); XSSFWorkbook wb = new(); ISheet sheet = wb.CreateSheet("缺测替补名单"); sheet.DisplayGridlines = false; var cellStyle = exportExcelService.GetCellStyle(wb); // 行索引号 int rowNum = 0; #region 列头 IRow headerRow = sheet.CreateRow(rowNum++); int ci = 0; exportExcelService.AddCell("学校", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 20); exportExcelService.AddCell("年级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8); exportExcelService.AddCell("班级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8); exportExcelService.AddCell("缺测姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12); exportExcelService.AddCell("缺测考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16); exportExcelService.AddCell("有无替补", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 10); exportExcelService.AddCell("替补姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12); exportExcelService.AddCell("替补考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16); exportExcelService.AddCell("缺测替补科目", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 50); exportExcelService.AddCell("状态", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8); exportExcelService.AddCell("缺测原因", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 40); exportExcelService.AddCell("家长电话", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12); sheet.CreateFreezePane(0, rowNum); #endregion #region 数据 foreach (var item in items) { IRow row = sheet.CreateRow(rowNum++); int rci = 0; exportExcelService.AddCell(item.SysOrg.Name, row, rci++, cellStyle.LeftCellStyle); exportExcelService.AddCell(item.ExamGrade.Grade.Name, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.ClassNumber, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.AbsentName, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.AbsentExamNumber, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.IsReplaced ? "是" : "否", row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.ReplaceName, row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.ReplaceExamNumber, row, rci++, cellStyle.CenterCellStyle); var cs = JSON.Deserialize>(item.AbsentCourses); var cns = string.Join("、", cs.Select(t => t.Name)); exportExcelService.AddCell(cns, row, rci++, cellStyle.LeftCellStyle); exportExcelService.AddCell(item.Status.GetDescription(), row, rci++, cellStyle.CenterCellStyle); exportExcelService.AddCell(item.AbsentReason, row, rci++, cellStyle.LeftWrapCellStyle); exportExcelService.AddCell(item.PatriarchTel, row, rci++, cellStyle.CenterCellStyle); } #endregion MemoryStream ms = new(); wb.Write(ms, false); ms.Flush(); return ($"{examPlan.Name}-缺测替补名单.xlsx", ms.ToArray()); } #region 私有方法 /// /// 构建查询 /// /// /// private IQueryable GetQueryBase(ExamAbsentReplacePageInput input) { var absentName = !string.IsNullOrEmpty(input.AbsentName?.Trim()); var absentExamNumber = !string.IsNullOrEmpty(input.AbsentExamNumber?.Trim()); var absentReason = !string.IsNullOrEmpty(input.AbsentReason?.Trim()); var replaceName = !string.IsNullOrEmpty(input.ReplaceName?.Trim()); var replaceExamNumber = !string.IsNullOrEmpty(input.ReplaceExamNumber?.Trim()); var patriarchTel = !string.IsNullOrEmpty(input.PatriarchTel?.Trim()); var remark = !string.IsNullOrEmpty(input.Remark?.Trim()); var query = rep.DetachedEntities.Where(t => t.ExamPlanId == input.ExamPlanId) .Where((absentName, u => EF.Functions.Like(u.AbsentName, $"%{input.AbsentName.Trim()}%"))) .Where((absentExamNumber, u => EF.Functions.Like(u.AbsentExamNumber, $"%{input.AbsentExamNumber.Trim()}%"))) .Where((absentReason, u => EF.Functions.Like(u.AbsentReason, $"%{input.AbsentReason.Trim()}%"))) .Where((replaceName, u => EF.Functions.Like(u.ReplaceName, $"%{input.ReplaceName.Trim()}%"))) .Where((replaceExamNumber, u => EF.Functions.Like(u.ReplaceExamNumber, $"%{input.ReplaceExamNumber.Trim()}%"))) .Where((patriarchTel, u => EF.Functions.Like(u.PatriarchTel, $"%{input.PatriarchTel.Trim()}%"))) .Where((remark, u => EF.Functions.Like(u.Remark, $"%{input.Remark.Trim()}%"))) .Where((input.AbentCourseId.HasValue, u => EF.Functions.Like(u.AbsentCourses, $"%{input.AbentCourseId}%"))) .Where(input.Status.HasValue, t => t.Status == input.Status) .Where(input.IsReplaced.HasValue, t => t.IsReplaced == input.IsReplaced) .Where(input.GradeId.HasValue, t => t.GradeId == input.GradeId) .Where(input.ClassNumber.HasValue, t => t.ClassNumber == input.ClassNumber) .Where(input.SysOrgId.HasValue, t => t.SysOrgId == input.SysOrgId) .Where(input.SysOrgBranchId.HasValue, t => t.SchoolClass.SysOrgBranchId == input.SysOrgBranchId); return query; } #endregion }