123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- using NPOI.SS.Formula.Functions;
- using NPOI.SS.UserModel;
- using NPOI.SS.Util;
- using NPOI.XSSF.UserModel;
- using System.Data;
- using YBEE.EQM.Core;
- namespace YBEE.EQM.Application;
- /// <summary>
- /// 统计报表之分数段报表服务
- /// </summary>
- public class ExamReportingAvgRangeService(
- IRepository rep,
- ISqlRepository sqlRep,
- IExamScoreRangeService examScoreRangeService,
- IExamGradeService examGradeService,
- IExamOrgService examOrgService,
- IExamCourseService examCourseService,
- IExportExcelService exportExcelService) : IExamReportingAvgRangeService, ITransient
- {
- #region 导出
- /// <summary>
- /// 导出全区分数段统计表
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <returns></returns>
- public async Task<(string, byte[])> ExportTotal(int examPlanId)
- {
- var examPlan = await rep.Change<ExamPlan>().DetachedEntities.ProjectToType<ExamPlanOutput>().FirstOrDefaultAsync(t => t.Id == examPlanId) ?? throw Oops.Oh(ErrorCode.E2001, "监测计划");
- var scoreRanges = await examScoreRangeService.GetList();
- var examGrades = await examGradeService.GetListByExamPlanId(examPlanId);
- var examCourses = await examCourseService.GetListByExamPlanId(examPlanId);
- // 临时存放目录
- string fileRoot = Path.Combine(FileUtil.GetTempFileRoot(), $"{Guid.NewGuid()}");
- Directory.CreateDirectory(fileRoot);
- string filePath = Path.Combine(fileRoot, $"{examPlan.Name}-区县报告-平均分及分数段统计");
- Directory.CreateDirectory(filePath);
- try
- {
- foreach (var examGrade in examGrades)
- {
- for (int i = 0; i < 2; i++)
- {
- string fn = i == 0 ? "区校合并" : "区级监测";
- string titlePrefix = $"{examPlan.Name}{fn}{examGrade.Grade.Name}";
- XSSFWorkbook wb = new();
- var cellStyles = exportExcelService.GetCellStyle(wb);
- ExamSampleType? sampleType = i == 1 ? ExamSampleType.DISTRICT : null;
- await ExportTotalTotalRange(titlePrefix, examPlanId, sampleType, examGrade.GradeId, scoreRanges.Where(t => t.Type == examGrade.ExamScoreRangeType).ToList(), wb, cellStyles);
- await ExportTotalCourseRange(titlePrefix, examPlanId, sampleType, examGrade.GradeId, scoreRanges, examCourses.Where(t => t.GradeId == examGrade.GradeId).ToList(), wb, cellStyles);
- await ExportTotalCourseAvgScore(titlePrefix, examPlanId, sampleType, examGrade.GradeId, examCourses.Where(t => t.GradeId == examGrade.GradeId).ToList(), wb, cellStyles);
- MemoryStream ms = new();
- wb.Write(ms, false);
- ms.Flush();
-
- await File.WriteAllBytesAsync(Path.Combine(filePath, $"{examGrade.Grade.Name}-{fn}-平均分及分数段统计.xlsx"), ms.ToArray());
- if (!examGrade.IsRequiredSample)
- {
- break;
- }
- }
- }
- string outFileName = $"{examPlan.Name}-区县报告-平均分及分数段统计-{DateTime.Now.Ticks}.zip";
- string outFilePath = Path.Combine(fileRoot, outFileName);
- ICSharpCode.SharpZipLib.Zip.FastZip zip = new();
- zip.CreateZip(outFilePath, filePath, true, string.Empty);
- var retBytes = await File.ReadAllBytesAsync(outFilePath);
- return (outFileName, retBytes);
- }
- catch (Exception ex)
- {
- throw new Exception("导出错误", ex);
- }
- finally
- {
- Directory.Delete(fileRoot, true);
- }
- }
- /// <summary>
- /// 导出各校分数段统计表
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- public async Task<(string, byte[])> ExportOrg(int examPlanId)
- {
- var examPlan = await rep.Change<ExamPlan>().DetachedEntities.ProjectToType<ExamPlanOutput>().FirstOrDefaultAsync(t => t.Id == examPlanId) ?? throw Oops.Oh(ErrorCode.E2001, "监测计划");
- var scoreRanges = await examScoreRangeService.GetList();
- var examGrades = await examGradeService.GetListByExamPlanId(examPlanId);
- var examCourses = await examCourseService.GetListByExamPlanId(examPlanId);
- var examOrgs = (await examOrgService.GetListByExamPlanId(examPlanId)).Where(t => t.IsRequiredExam).ToList();
- // 临时存放目录
- string fileRoot = Path.Combine(FileUtil.GetTempFileRoot(), $"{Guid.NewGuid()}");
- Directory.CreateDirectory(fileRoot);
- string filePath = Path.Combine(fileRoot, $"{examPlan.Name}-学校报告-平均分及分数段统计");
- Directory.CreateDirectory(filePath);
- // 学段目录
- string eduStageFilePath = Path.Combine(filePath, examPlan.EducationStage.GetDescription());
- Directory.CreateDirectory(eduStageFilePath);
- try
- {
- // 年级
- foreach (var examGrade in examGrades)
- {
- var ecourses = examCourses.Where(t => t.GradeId == examGrade.GradeId).OrderBy(t => t.CourseId).ToList();
- for (int i = 0; i < 2; i++)
- {
- string fn = i == 0 ? "区校合并" : "区级监测";
- string titlePrefix = $"{fn}{examGrade.Grade.Name}";
- ExamSampleType? sampleType = i == 1 ? ExamSampleType.DISTRICT : null;
- // 平均分
- var listAvgScore = await GetAvgScoreList(examPlanId, examGrade.GradeId, sampleType);
- // 总分分数段
- var listTotalScoreRange = await GetTotalRangeList(examPlanId, examGrade.GradeId, sampleType);
- // 学科分数段
- var listCourseScoreRange = await GetCourseRangeList(examPlanId, examGrade.GradeId, sampleType);
- // 学校
- foreach (var org in examOrgs)
- {
- // 学校目录
- string orgFilePath = Path.Combine(eduStageFilePath, org.SysOrg.FullName, "学校报告", "1-6 平均分及分数段统计");
- if (!Directory.Exists(orgFilePath))
- {
- Directory.CreateDirectory(orgFilePath);
- }
- XSSFWorkbook wb = new();
- var cellStyles = exportExcelService.GetCellStyle(wb);
- // 平均分
- var orgAvgScoreList = listAvgScore.Where(t => t.SysOrgId == org.SysOrgId || t.DataScopeType > 1 || (t.DataScopeType == 1 && t.UrbanRuralType == UrbanRuralType.NONE))
- .OrderBy(t => t.DataScopeType).ThenBy(t => t.SysOrgId).ThenBy(t => t.UrbanRuralType).ThenBy(t => t.CourseId)
- .ToList();
- ExportOrgCourseAvgScore(titlePrefix, org.SysOrg.Name, orgAvgScoreList, ecourses, wb, cellStyles);
- // 总分分数段
- var orgTotalScoreRangeList = listTotalScoreRange.Where(t => t.SysOrgId == org.SysOrgId).OrderByDescending(t => t.ExamScoreRangeId).ToList();
- ExportOrgScoreRange(titlePrefix, org.SysOrg.Name, "总分", orgTotalScoreRangeList, scoreRanges.Where(t => t.Type == examGrade.ExamScoreRangeType).ToList(), wb, cellStyles);
- // 学科分数段
- foreach (var ecourse in ecourses)
- {
- var orgCourseScoreRangeList = listCourseScoreRange.Where(t => t.SysOrgId == org.SysOrgId && t.CourseId == ecourse.CourseId).ToList();
- ExportOrgScoreRange(titlePrefix, org.SysOrg.Name, ecourse.Course.Name, orgCourseScoreRangeList, scoreRanges.Where(t => t.Type == ecourse.ExamScoreRangeType).ToList(), wb, cellStyles);
- }
- MemoryStream ms = new();
- wb.Write(ms, false);
- ms.Flush();
- await File.WriteAllBytesAsync(Path.Combine(orgFilePath, $"{examGrade.Grade.Name}-{fn}-平均分及分数段统计.xlsx"), ms.ToArray());
- }
- if (!examGrade.IsRequiredSample)
- {
- break;
- }
- }
- }
- string outFileName = $"{examPlan.Name}-学校报告-平均分及分数段统计-{DateTime.Now.Ticks}.zip";
- string outFilePath = Path.Combine(fileRoot, outFileName);
- ICSharpCode.SharpZipLib.Zip.FastZip zip = new();
- zip.CreateZip(outFilePath, filePath, true, string.Empty);
- var retBytes = await File.ReadAllBytesAsync(outFilePath);
- return (outFileName, retBytes);
- }
- catch (Exception ex)
- {
- throw new Exception("导出错误", ex);
- }
- finally
- {
- Directory.Delete(fileRoot, true);
- }
- }
- #endregion
- #region 导出全区表格私有方法
- /// <summary>
- /// 导出总分分数段
- /// </summary>
- /// <param name="titlePrefix"></param>
- /// <param name="examPlanId"></param>
- /// <param name="sampleType"></param>
- /// <param name="gradeId"></param>
- /// <param name="ranges"></param>
- /// <param name="wb"></param>
- /// <param name="cellStyles"></param>
- /// <returns></returns>
- private async Task ExportTotalTotalRange(string titlePrefix, int examPlanId, ExamSampleType? sampleType, short gradeId, List<ExamScoreRangeOutput> ranges, XSSFWorkbook wb, ExportExcelCellStyle cellStyles)
- {
- ISheet sheet = wb.CreateSheet("总分分数段");
- sheet.DisplayGridlines = false;
- sheet.CreateFreezePane(0, 2);
- int rowNum = 0;
- #region 标题
- IRow titleRow = sheet.CreateRow(rowNum++);
- titleRow.HeightInPoints = 40;
- int ci = 0;
- exportExcelService.AddCell($"{titlePrefix}总分分数段统计", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- foreach (var r in ranges)
- {
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, ci - 1));
- #endregion
- #region 列头
- IRow headerRow = sheet.CreateRow(rowNum++);
- headerRow.HeightInPoints = 30;
- ci = 0;
- exportExcelService.AddCell("学校", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 20);
- exportExcelService.AddCell("类别", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 6);
- exportExcelService.AddCell("实考\r\n人数", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 6);
- foreach (var r in ranges)
- {
- exportExcelService.AddCell(r.NickName, headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 6);
- }
- #endregion
- #region 数据
- var list = await GetTotalRangeList(examPlanId, gradeId, sampleType);
- var urGroup = list.GroupBy(t => t.UrbanRuralType).OrderBy(t => t.Key).ToList();
- foreach (var urg in urGroup)
- {
- var orgGroup = urg.GroupBy(t => new { t.SysOrgId, t.TotalCount }).ToList();//.OrderByDescending(t => t.Key.TotalCount).ToList();
- foreach (var orgg in orgGroup)
- {
- IRow row = sheet.CreateRow(rowNum++);
- row.HeightInPoints = 20;
- ci = 0;
- var forg = orgg.First();
- exportExcelService.AddCell(forg.SysOrgName, row, ci++, cellStyles.LeftCellStyle);
- exportExcelService.AddCell(forg.UrbanRuralType.GetDescription(), row, ci++, cellStyles.CenterCellStyle);
- exportExcelService.AddCell(forg.TotalCount, row, ci++, cellStyles.CenterCellStyle);
- foreach (var r in ranges)
- {
- var sr = orgg.FirstOrDefault(t => t.ExamScoreRangeId == r.Id);
- exportExcelService.AddCell(sr?.RangeCount, row, ci++, cellStyles.CenterCellStyle);
- }
- }
- }
- #endregion
- #region 合计
- IRow totalRow = sheet.CreateRow(rowNum++);
- totalRow.HeightInPoints = 20;
- ci = 0;
- exportExcelService.AddCell("合计", totalRow, ci++, cellStyles.ColumnHeaderStyle);
- exportExcelService.AddCell("", totalRow, ci++, cellStyles.ColumnHeaderStyle);
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, 1));
- exportExcelService.AddCell($"SUM(C3:C{rowNum - 1})", totalRow, ci++, cellStyles.ColumnHeaderStyle, cellType: CellType.Formula);
- foreach (var r in ranges)
- {
- var cn = ExcelUtil.GetColumnNameByIndex(ci);
- exportExcelService.AddCell($"SUM({cn}3:{cn}{rowNum - 1})", totalRow, ci++, cellStyles.ColumnHeaderStyle, cellType: CellType.Formula);
- }
- #endregion
- }
- /// <summary>
- /// 导出学科分数段
- /// </summary>
- /// <param name="titlePrefix"></param>
- /// <param name="examPlanId"></param>
- /// <param name="sampleType"></param>
- /// <param name="gradeId"></param>
- /// <param name="ranges"></param>
- /// <param name="examCourses"></param>
- /// <param name="wb"></param>
- /// <param name="cellStyles"></param>
- /// <returns></returns>
- private async Task ExportTotalCourseRange(string titlePrefix, int examPlanId, ExamSampleType? sampleType, short gradeId, List<ExamScoreRangeOutput> ranges, List<ExamCourseOutput> examCourses, XSSFWorkbook wb, ExportExcelCellStyle cellStyles)
- {
- ISheet sheet = wb.CreateSheet("学科分数段");
- sheet.DisplayGridlines = false;
- int rowNum = 0;
- foreach (var examCourse in examCourses)
- {
- var list = await GetCourseRangeList(examPlanId, gradeId, examCourse.CourseId, sampleType);
- if (list.Count == 0)
- {
- continue;
- }
- var courseRanges = ranges.Where(t => t.Type == examCourse.ExamScoreRangeType).ToList();
- #region 标题
- IRow titleRow = sheet.CreateRow(rowNum++);
- titleRow.HeightInPoints = 40;
- int ci = 0;
- exportExcelService.AddCell($"{titlePrefix}{examCourse.Course.Name}分数段统计", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- foreach (var r in courseRanges)
- {
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, ci - 1));
- #endregion
- #region 列头
- IRow headerRow = sheet.CreateRow(rowNum++);
- headerRow.HeightInPoints = 20;
- ci = 0;
- exportExcelService.AddCell("学校", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 20);
- exportExcelService.AddCell("类别", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 6);
- exportExcelService.AddCell("实考人数", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 10);
- foreach (var r in courseRanges)
- {
- exportExcelService.AddCell(r.NickName, headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 10);
- }
- #endregion
- #region 数据
- int rc = 0;
- var urGroup = list.GroupBy(t => t.UrbanRuralType).OrderBy(t => t.Key).ToList();
- foreach (var urg in urGroup)
- {
- var orgGroup = urg.GroupBy(t => new { t.SysOrgId, t.TotalCount }).ToList();//.OrderByDescending(t => t.Key.TotalCount).ToList();
- foreach (var orgg in orgGroup)
- {
- rc++;
- IRow row = sheet.CreateRow(rowNum++);
- row.HeightInPoints = 20;
- ci = 0;
- var forg = orgg.First();
- exportExcelService.AddCell(forg.SysOrgName, row, ci++, cellStyles.LeftCellStyle);
- exportExcelService.AddCell(forg.UrbanRuralType.GetDescription(), row, ci++, cellStyles.CenterCellStyle);
- exportExcelService.AddCell(forg.TotalCount, row, ci++, cellStyles.CenterCellStyle);
- foreach (var r in courseRanges)
- {
- var sr = orgg.FirstOrDefault(t => t.ExamScoreRangeId == r.Id);
- exportExcelService.AddCell(sr?.RangeCount, row, ci++, cellStyles.CenterCellStyle);
- }
- }
- }
- #endregion
- #region 合计
- IRow totalRow = sheet.CreateRow(rowNum++);
- totalRow.HeightInPoints = 20;
- ci = 0;
- exportExcelService.AddCell("合计", totalRow, ci++, cellStyles.ColumnHeaderStyle);
- exportExcelService.AddCell("", totalRow, ci++, cellStyles.ColumnHeaderStyle);
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, 1));
- exportExcelService.AddCell($"SUM(C{rowNum - rc}:C{rowNum - 1})", totalRow, ci++, cellStyles.ColumnHeaderStyle, cellType: CellType.Formula);
- foreach (var r in courseRanges)
- {
- var cn = ExcelUtil.GetColumnNameByIndex(ci);
- exportExcelService.AddCell($"SUM({cn}{rowNum - rc}:{cn}{rowNum - 1})", totalRow, ci++, cellStyles.ColumnHeaderStyle, cellType: CellType.Formula);
- }
- #endregion
- rowNum += 2;
- }
- }
- /// <summary>
- /// 导出学科平均分
- /// </summary>
- /// <param name="titlePrefix"></param>
- /// <param name="examPlanId"></param>
- /// <param name="sampleType"></param>
- /// <param name="gradeId"></param>
- /// <param name="examCourses"></param>
- /// <param name="wb"></param>
- /// <param name="cellStyles"></param>
- /// <returns></returns>
- private async Task ExportTotalCourseAvgScore(string titlePrefix, int examPlanId, ExamSampleType? sampleType, short gradeId, List<ExamCourseOutput> examCourses, XSSFWorkbook wb, ExportExcelCellStyle cellStyles)
- {
- var courses = examCourses.Select(t => t.Course).ToList();
- courses.Insert(0, new CourseLiteOutput() { Id = 0, Name = "总分" });
- ISheet sheet = wb.CreateSheet("学科平均分");
- sheet.DisplayGridlines = false;
- //sheet.CreateFreezePane(0, 2);
- var cellStyleNumberP2Blod = wb.CreateCellStyle();
- cellStyleNumberP2Blod.CloneStyleFrom(cellStyles.NumberCellStyleP2);
- //var font = cellStyleNumberP2Blod.GetFont(wb);
- //font.IsBold = true;
- IFont bFont = wb.CreateFont();
- bFont.IsBold = true;
- bFont.FontName = cellStyles.TitleFontName;
- bFont.FontHeightInPoints = 10;
- cellStyleNumberP2Blod.SetFont(bFont);
- int rowNum = 0;
- #region 标题
- IRow titleRow = sheet.CreateRow(rowNum++);
- titleRow.HeightInPoints = 40;
- int ci = 0;
- exportExcelService.AddCell($"{titlePrefix}各学科均分统计", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- foreach (var r in courses)
- {
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, ci - 1));
- #endregion
- #region 列头
- IRow headerRow1 = sheet.CreateRow(rowNum++);
- headerRow1.HeightInPoints = 20;
- ci = 0;
- exportExcelService.AddCell("学校", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 20);
- exportExcelService.AddCell("类别", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- exportExcelService.AddCell("实考\r\n人数", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- foreach (var r in courses)
- {
- exportExcelService.AddCell(r.Name, headerRow1, ci++, cellStyles.ColumnFillHeaderStyle);
- exportExcelService.AddCell("", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle);
- exportExcelService.AddCell("", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle);
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, ci - 3, ci - 1));
- }
- IRow headerRow2 = sheet.CreateRow(rowNum++);
- headerRow2.HeightInPoints = 30;
- ci = 0;
- exportExcelService.AddCell("", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle);
- exportExcelService.AddCell("", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle);
- exportExcelService.AddCell("", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle);
- foreach (var r in courses)
- {
- exportExcelService.AddCell("平均分", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- exportExcelService.AddCell("名次", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 5);
- exportExcelService.AddCell("与最高\r\n分差距", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 2, rowNum - 1, 0, 0));
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 2, rowNum - 1, 1, 1));
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 2, rowNum - 1, 2, 2));
- #endregion
- #region 数据
- var list = await GetAvgScoreList(examPlanId, gradeId, sampleType);
- // 过滤掉最高分
- list = list.Where(t => !(t.DataScopeType == 1 && t.UrbanRuralType == UrbanRuralType.NONE)).ToList();
- // 城乡分组
- var urGroup = list.GroupBy(t => t.UrbanRuralType).OrderBy(t => t.Key == UrbanRuralType.NONE ? 99 : (short)t.Key).ToList();
- foreach (var urg in urGroup)
- {
- // 机构
- //var orgGroup = urg.GroupBy(t => t.SysOrgId).OrderBy(t => t.FirstOrDefault()?.DataScopeType).ThenByDescending(t => t.FirstOrDefault(c => c.CourseId == 0)?.TotalCount).ToList();
- var orgGroup = urg.GroupBy(t => t.SysOrgId).OrderBy(t => t.FirstOrDefault()?.DataScopeType).ThenBy(t => t.FirstOrDefault(c => c.CourseId == 0)?.OrderInTotal).ToList();
- foreach (var orgg in orgGroup)
- {
- IRow row = sheet.CreateRow(rowNum++);
- row.HeightInPoints = 20;
- ci = 0;
- var forg = orgg.FirstOrDefault(t => t.CourseId == 0);
- if (forg.DataScopeType > 1)
- {
- var txt = forg?.SysOrgName ?? "";
- if (forg?.UrbanRuralType != UrbanRuralType.NONE)
- {
- txt = $"{forg?.UrbanRuralType?.GetDescription()}{txt}";
- }
- exportExcelService.AddCell(txt, row, ci++, cellStyles.ColumnHeaderStyle);
- exportExcelService.AddCell("", row, ci++, cellStyles.ColumnHeaderStyle);
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, ci - 2, ci - 1));
- }
- else
- {
- exportExcelService.AddCell(forg?.SysOrgName, row, ci++, cellStyles.LeftCellStyle);
- exportExcelService.AddCell(forg?.UrbanRuralType.GetDescription(), row, ci++, cellStyles.CenterCellStyle);
- }
- exportExcelService.AddCell(forg?.TotalCount, row, ci++, forg?.DataScopeType != 1 ? cellStyles.ColumnHeaderStyle : cellStyles.CenterCellStyle);
- foreach (var r in courses)
- {
- var sr = orgg.FirstOrDefault(t => t.CourseId == r.Id);
- exportExcelService.AddCell(sr?.AvgScore, row, ci++, (sr?.DataScopeType != 1 || sr.AvgScoreDiff == 0) ? cellStyleNumberP2Blod : cellStyles.NumberCellStyleP2);
- exportExcelService.AddCell(sr?.DataScopeType != 1 ? null : sr?.OrderInTotal, row, ci++, cellStyles.CenterCellStyle);
- exportExcelService.AddCell(sr?.AvgScoreDiff, row, ci++, sr?.DataScopeType != 1 ? cellStyleNumberP2Blod : cellStyles.NumberCellStyleP2);
- }
- }
- }
- #endregion
- //#region 合计
- //IRow totalRow = sheet.CreateRow(rowNum++);
- //totalRow.HeightInPoints = 20;
- //ci = 0;
- //exportExcelService.AddCell("合计", totalRow, ci++, cellStyles.ColumnHeaderStyle);
- //exportExcelService.AddCell("", totalRow, ci++, cellStyles.ColumnHeaderStyle);
- //sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(rowNum - 1, rowNum - 1, 0, 1));
- //exportExcelService.AddCell($"SUM(C3:C{rowNum - 1})", totalRow, ci++, cellStyles.ColumnHeaderStyle, cellType: CellType.Formula);
- //foreach (var r in ranges)
- //{
- // var cn = ExcelUtil.GetColumnNameByIndex(ci);
- // exportExcelService.AddCell($"SUM({cn}3:{cn}{rowNum - 1})", totalRow, ci++, cellStyles.ColumnHeaderStyle, cellType: CellType.Formula);
- //}
- //#endregion
- }
- #endregion
- #region 导出学校表格私有方法
- /// <summary>
- /// 导出学校学科平均分统计表
- /// </summary>
- /// <param name="titlePrefix"></param>
- /// <param name="orgName"></param>
- /// <param name="list"></param>
- /// <param name="examCourses"></param>
- /// <param name="wb"></param>
- /// <param name="cellStyles"></param>
- /// <returns></returns>
- private void ExportOrgCourseAvgScore(string titlePrefix, string orgName, List<ExamScoreAvgExportDto> list, List<ExamCourseOutput> examCourses, XSSFWorkbook wb, ExportExcelCellStyle cellStyles)
- {
- var courses = examCourses.Select(t => t.Course).ToList();
- courses.Insert(0, new CourseLiteOutput() { Id = 0, Name = "总分" });
- ISheet sheet = wb.CreateSheet("学科平均分");
- sheet.DisplayGridlines = false;
- var cellStyleNumberP2Blod = wb.CreateCellStyle();
- cellStyleNumberP2Blod.CloneStyleFrom(cellStyles.NumberCellStyleP2);
- IFont bFont = wb.CreateFont();
- bFont.IsBold = true;
- bFont.FontName = cellStyles.TitleFontName;
- bFont.FontHeightInPoints = 10;
- cellStyleNumberP2Blod.SetFont(bFont);
- int rowNum = 0;
- #region 标题
- IRow titleRow = sheet.CreateRow(rowNum++);
- titleRow.HeightInPoints = 60;
- int ci = 0;
- exportExcelService.AddCell($"{orgName}{titlePrefix}各学科均分统计", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- foreach (var r in courses)
- {
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, ci - 1));
- #endregion
- #region 列头
- IRow headerRow1 = sheet.CreateRow(rowNum++);
- headerRow1.HeightInPoints = 20;
- ci = 0;
- exportExcelService.AddCell("学校", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 20);
- exportExcelService.AddCell("实考\r\n人数", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- foreach (var r in courses)
- {
- exportExcelService.AddCell(r.Name, headerRow1, ci++, cellStyles.ColumnFillHeaderStyle);
- exportExcelService.AddCell("", headerRow1, ci++, cellStyles.ColumnFillHeaderStyle);
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, ci - 2, ci - 1));
- }
- IRow headerRow2 = sheet.CreateRow(rowNum++);
- headerRow2.HeightInPoints = 30;
- ci = 0;
- exportExcelService.AddCell("", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle);
- exportExcelService.AddCell("", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle);
- foreach (var r in courses)
- {
- exportExcelService.AddCell("平均分", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- exportExcelService.AddCell("与最高\r\n分差距", headerRow2, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 8);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 2, rowNum - 1, 0, 0));
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 2, rowNum - 1, 1, 1));
- #endregion
- #region 数据
- // 城乡分组
- var urGroup = list.GroupBy(t => t.UrbanRuralType).OrderBy(t => t.Key).ToList();
- foreach (var urg in urGroup)
- {
- // 机构
- var orgGroup = urg.GroupBy(t => t.SysOrgId).OrderBy(t => t.FirstOrDefault()?.DataScopeType).ThenBy(t => t.Key).ThenBy(t => t.FirstOrDefault().UrbanRuralType).ToList();
- foreach (var orgg in orgGroup)
- {
- IRow row = sheet.CreateRow(rowNum++);
- row.HeightInPoints = 20;
- ci = 0;
- var forg = orgg.FirstOrDefault(t => t.CourseId == 0);
- var isMax = forg.DataScopeType == 1 && forg.UrbanRuralType == UrbanRuralType.NONE;
- if (forg.DataScopeType > 1)
- {
- var txt = forg?.SysOrgName ?? "";
- if (forg?.UrbanRuralType != UrbanRuralType.NONE)
- {
- txt = $"{forg?.UrbanRuralType?.GetDescription()}学校";
- }
- exportExcelService.AddCell(txt, row, ci++, cellStyles.LeftCellStyle);
- }
- else
- {
- exportExcelService.AddCell(forg?.SysOrgName, row, ci++, isMax ? cellStyles.ColumnHeaderStyle : cellStyles.LeftCellStyle);
- }
- exportExcelService.AddCell(isMax ? null : forg?.TotalCount, row, ci++, isMax ? cellStyles.ColumnHeaderStyle : cellStyles.CenterCellStyle);
- foreach (var r in courses)
- {
- var sr = orgg.FirstOrDefault(t => t.CourseId == r.Id);
- exportExcelService.AddCell(sr?.AvgScore, row, ci++, isMax ? cellStyleNumberP2Blod : cellStyles.NumberCellStyleP2);
- exportExcelService.AddCell((isMax || forg.DataScopeType > 1) ? null : sr?.AvgScoreDiff, row, ci++, isMax ? cellStyleNumberP2Blod : cellStyles.NumberCellStyleP2);
- }
- }
- }
- #endregion
- }
- /// <summary>
- /// 导出学校学科分数段统计图表
- /// </summary>
- /// <param name="titlePrefix"></param>
- /// <param name="orgName"></param>
- /// <param name="courseName"></param>
- /// <param name="list"></param>
- /// <param name="ranges"></param>
- /// <param name="wb"></param>
- /// <param name="cellStyles"></param>
- private void ExportOrgScoreRange(string titlePrefix, string orgName, string courseName, List<ExamScoreRangeExportDto> list, List<ExamScoreRangeOutput> ranges, XSSFWorkbook wb, ExportExcelCellStyle cellStyles)
- {
- ISheet sheet = wb.CreateSheet(courseName);
- sheet.DisplayGridlines = false;
- int rowNum = 0;
- #region 标题
- IRow titleRow = sheet.CreateRow(rowNum++);
- titleRow.HeightInPoints = 60;
- int ci = 0;
- exportExcelService.AddCell($"{orgName}{titlePrefix}{courseName}分数段统计", titleRow, ci++, cellStyles.TitleStyle);
- for (; ci < 15; ci++)
- {
- exportExcelService.AddCell("", titleRow, ci++, cellStyles.TitleStyle);
- }
- sheet.AddMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 0, ci - 1));
- #endregion
- #region 列头
- IRow headerRow = sheet.CreateRow(rowNum++);
- ci = 0;
- exportExcelService.AddCell("分数段", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 14);
- exportExcelService.AddCell("本段人数", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 10);
- exportExcelService.AddCell("累计人数", headerRow, ci++, cellStyles.ColumnFillHeaderStyle, sheet, 10);
- #endregion
- #region 数据
- decimal scount = 0;
- foreach (var r in ranges)
- {
- var sr = list.FirstOrDefault(t => t.ExamScoreRangeId == r.Id);
- IRow row = sheet.CreateRow(rowNum++);
- int rci = 0;
- exportExcelService.AddCell(r.NickName, row, rci++, cellStyles.CenterCellStyle);
- scount += sr?.RangeCount ?? 0;
- exportExcelService.AddCell(sr?.RangeCount ?? 0, row, rci++, cellStyles.CenterCellStyle);
- exportExcelService.AddCell(scount, row, rci++, cellStyles.CenterCellStyle);
- }
- #endregion
- #region 图表
- const int CHART_ROW_COUNT = 18;
- XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch();
- int startRow = 1;
- int endRow = startRow + CHART_ROW_COUNT;
- XSSFClientAnchor anchor = (XSSFClientAnchor)drawing.CreateAnchor(0, 0, 0, 0, ci + 1, startRow, ci + 12, endRow);
- exportExcelService.CreateBarChart(sheet, drawing, anchor, 2, ranges.Count + 1, 1, $"{titlePrefix}{courseName}分数段统计", orgName, "人数", "分数段");
- #endregion
- }
- #endregion
- #region 数据获取私有方法
- /// <summary>
- /// 获取总分分数段数据
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <param name="gradeId"></param>
- /// <param name="sampleType"></param>
- /// <returns></returns>
- private async Task<List<ExamScoreRangeExportDto>> GetTotalRangeList(int examPlanId, short gradeId, ExamSampleType? sampleType)
- {
- var items = await sqlRep.SqlQueriesAsync<ExamScoreRangeExportDto>($@"
- SELECT T2.urban_rural_type, T2.`name` AS sys_org_name, T3.`name` AS exam_score_range_name, T3.nick_name AS exam_score_range_nick_name, T1.*
- FROM
- (
- SELECT T1.sys_org_id, T1.exam_score_range_id, COUNT(T1.exam_student_id) AS range_count, MAX(T1.total_count) AS total_count
- FROM
- (
- SELECT T1.sys_org_id, T1.exam_score_range_id, T1.exam_student_id, COUNT(T1.exam_student_id) OVER (PARTITION BY T1.sys_org_id) AS total_count
- FROM exam_score_total AS T1
- WHERE exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.is_excluded = 0 AND T1.score > 0 AND (T1.exam_sample_type = @examSampleType OR @examSampleType = 0)
- ) AS T1
- GROUP BY T1.sys_org_id, T1.exam_score_range_id
- ) AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- JOIN exam_score_range AS T3 ON T1.exam_score_range_id = T3.id
- ;
- ", new { ExamPlanId = examPlanId, GradeId = gradeId, ExamSampleType = sampleType.HasValue ? (short)sampleType : 0 });
- return items;
- }
- /// <summary>
- /// 获取单科分数段数据
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <param name="gradeId"></param>
- /// <param name="courseId"></param>
- /// <param name="sampleType"></param>
- /// <returns></returns>
- private async Task<List<ExamScoreRangeExportDto>> GetCourseRangeList(int examPlanId, short gradeId, short courseId, ExamSampleType? sampleType)
- {
- var items = await sqlRep.SqlQueriesAsync<ExamScoreRangeExportDto>($@"
- SELECT T2.urban_rural_type, T2.`name` AS sys_org_name, T3.`name` AS exam_score_range_name, T3.nick_name AS exam_score_range_nick_name, T1.*
- FROM
- (
- SELECT T1.sys_org_id, T1.exam_score_range_id, COUNT(T1.exam_student_id) AS range_count, MAX(T1.total_count) AS total_count
- FROM
- (
- SELECT T1.sys_org_id, T1.exam_score_range_id, T1.exam_student_id, COUNT(T1.exam_student_id) OVER (PARTITION BY T1.sys_org_id) AS total_count
- FROM exam_score AS T1
- WHERE exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.course_id = @courseId AND T1.is_excluded = 0 AND T1.score > 0 AND (T1.exam_sample_type = @examSampleType OR @examSampleType = 0)
- ) AS T1
- GROUP BY T1.sys_org_id, T1.exam_score_range_id
- ) AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- JOIN exam_score_range AS T3 ON T1.exam_score_range_id = T3.id
- ;
- ", new { ExamPlanId = examPlanId, GradeId = gradeId, CourseId = courseId, ExamSampleType = sampleType.HasValue ? (short)sampleType : 0 });
- return items;
- }
- /// <summary>
- /// 获取单科分数段数据
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <param name="gradeId"></param>
- /// <param name="sampleType"></param>
- /// <returns></returns>
- private async Task<List<ExamScoreRangeExportDto>> GetCourseRangeList(int examPlanId, short gradeId, ExamSampleType? sampleType)
- {
- var items = await sqlRep.SqlQueriesAsync<ExamScoreRangeExportDto>($@"
- SELECT T2.urban_rural_type, T2.`name` AS sys_org_name, T3.`name` AS exam_score_range_name, T3.nick_name AS exam_score_range_nick_name, T1.*
- FROM
- (
- SELECT T1.sys_org_id, T1.course_id, T1.exam_score_range_id, COUNT(T1.exam_student_id) AS range_count, MAX(T1.total_count) AS total_count
- FROM
- (
- SELECT T1.sys_org_id, T1.course_id, T1.exam_score_range_id, T1.exam_student_id, COUNT(T1.exam_student_id) OVER (PARTITION BY T1.sys_org_id, T1.course_id) AS total_count
- FROM exam_score AS T1
- WHERE exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.is_excluded = 0 AND T1.score > 0 AND (T1.exam_sample_type = @examSampleType OR @examSampleType = 0)
- ) AS T1
- GROUP BY T1.sys_org_id, T1.course_id, T1.exam_score_range_id
- ) AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- JOIN exam_score_range AS T3 ON T1.exam_score_range_id = T3.id
- ;
- ", new { ExamPlanId = examPlanId, GradeId = gradeId, ExamSampleType = sampleType.HasValue ? (short)sampleType : 0 });
- return items;
- }
- /// <summary>
- /// 获取平均分数据
- /// </summary>
- /// <param name="examPlanId"></param>
- /// <param name="gradeId"></param>
- /// <param name="sampleType"></param>
- /// <returns></returns>
- private async Task<List<ExamScoreAvgExportDto>> GetAvgScoreList(int examPlanId, short gradeId, ExamSampleType? sampleType)
- {
- var items = await sqlRep.SqlQueriesAsync<ExamScoreAvgExportDto>($@"
- SELECT T1.*
- FROM
- (
- -- 总分
- SELECT 1 AS data_scope_type, T2.urban_rural_type, T2.`name` AS sys_org_name, T1.*,
- RANK() OVER(ORDER BY T1.avg_score DESC) AS order_in_total,
- RANK() OVER(PARTITION BY T2.urban_rural_type ORDER BY T1.avg_score DESC) AS order_in_same,
- T1.avg_score - T3.score_max AS avg_score_diff,
- T3.score_max
- FROM
- (
- SELECT sys_org_id, 0 AS course_id, COUNT(exam_student_id) AS total_count, AVG(score) AS avg_score
- FROM exam_score_total
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY sys_org_id
- ) AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- JOIN
- (
- SELECT MAX(T.avg_score) AS score_max
- FROM
- (
- SELECT sys_org_id, AVG(score) AS avg_score
- FROM exam_score_total
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY sys_org_id
- ) AS T
- ) AS T3
- -- 单科
- UNION ALL
- SELECT 1 AS data_scope_type, T2.urban_rural_type, T2.`name` AS sys_org_name, T1.*,
- RANK() OVER(PARTITION BY T1.course_id ORDER BY T1.avg_score DESC) AS order_in_total,
- RANK() OVER(PARTITION BY T1.course_id, T2.urban_rural_type ORDER BY T1.avg_score DESC) AS order_in_same,
- T1.avg_score - T3.score_max AS avg_score_diff,
- T3.score_max
- FROM
- (
- SELECT sys_org_id, course_id, COUNT(exam_student_id) AS total_count, AVG(score) AS avg_score
- FROM exam_score
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY sys_org_id, course_id
- ) AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- JOIN
- (
- SELECT T.course_id, MAX(T.avg_score) AS score_max
- FROM
- (
- SELECT sys_org_id, course_id, AVG(score) AS avg_score
- FROM exam_score
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY sys_org_id, course_id
- ) AS T
- GROUP BY T.course_id
- ) AS T3 ON T1.course_id = T3.course_id
- -- 同类小计
- UNION ALL
- SELECT 2 AS data_scope_type, T1.*,
- NULL AS order_in_total,
- NULL AS order_in_same,
- T1.avg_score - T3.score_max AS avg_score_diff,
- T3.score_max
- FROM
- (
- SELECT T2.urban_rural_type, '小计' AS sys_org_name, 99999998 AS sys_org_id, 0 AS course_id, COUNT(T1.exam_student_id) AS total_count, AVG(T1.score) AS avg_score
- FROM exam_score_total AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- WHERE T1.exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.is_excluded = 0 AND T1.score > 0 AND (T1.exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY T2.urban_rural_type
- ) AS T1
- JOIN
- (
- SELECT MAX(score) AS score_max FROM exam_score_total WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- ) AS T3
-
- -- 单科同类小计
- UNION ALL
- SELECT 2 AS data_scope_type, T1.*,
- NULL AS order_in_total,
- NULL AS order_in_same,
- T1.avg_score - T3.score_max AS avg_score_diff,
- T3.score_max
- FROM
- (
- SELECT T2.urban_rural_type, '小计' AS sys_org_name, 99999998 AS sys_org_id, T1.course_id, COUNT(T1.exam_student_id) AS total_count, AVG(T1.score) AS avg_score
- FROM exam_score AS T1
- JOIN sys_org AS T2 ON T1.sys_org_id = T2.id
- WHERE T1.exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.is_excluded = 0 AND T1.score > 0 AND (T1.exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY T2.urban_rural_type, T1.course_id
- ) AS T1
- JOIN (
- SELECT course_id, MAX(score) AS score_max
- FROM exam_score
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY course_id
- ) AS T3 ON T1.course_id = T3.course_id
-
- -- 全部合计
- UNION ALL
- SELECT 3 AS data_scope_type, T1.*,
- NULL AS order_in_total,
- NULL AS order_in_same,
- T1.avg_score - T3.score_max AS avg_score_diff,
- T3.score_max
- FROM
- (
- SELECT 0 AS urban_rural_type, '合计' AS sys_org_name, 99999999 AS sys_org_id, 0 AS course_id, COUNT(T1.exam_student_id) AS total_count, AVG(T1.score) AS avg_score
- FROM exam_score_total AS T1
- WHERE T1.exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.is_excluded = 0 AND T1.score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- ) AS T1
- JOIN
- (
- SELECT MAX(score) AS score_max FROM exam_score_total WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- ) AS T3
-
- -- 单科全部合计
- UNION ALL
- SELECT 3 AS data_scope_type, T1.*,
- NULL AS order_in_total,
- NULL AS order_in_same,
- T1.avg_score - T3.score_max AS avg_score_diff,
- T3.score_max
- FROM
- (
- SELECT 0 AS urban_rural_type, '合计' AS sys_org_name, 99999999 AS sys_org_id, T1.course_id, COUNT(T1.exam_student_id) AS total_count, AVG(T1.score) AS avg_score
- FROM exam_score AS T1
- WHERE T1.exam_plan_id = @examPlanId AND T1.grade_id = @gradeId AND T1.is_excluded = 0 AND T1.score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY T1.course_id
- ) AS T1
- JOIN (
- SELECT course_id, MAX(score) AS score_max
- FROM exam_score
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY course_id
- ) AS T3 ON T1.course_id = T3.course_id
-
- -- 总分最高平均分
- UNION ALL
- SELECT 1 AS data_scope_type,
- 0 AS urban_rural_type,
- '全区最高分' AS sys_org_name,
- 99999999 AS sys_org_id,
- 0 AS course_id,
- NULL AS total_count,
- MAX(T.avg_score) AS avg_score,
- NULL AS order_in_total,
- NULL AS order_in_same,
- NULL AS avg_score_diff,
- NULL AS score_max
- FROM
- (
- SELECT sys_org_id, AVG(score) AS avg_score
- FROM exam_score_total
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY sys_org_id
- ) AS T
-
- -- 单科最高平均分
- UNION ALL
- SELECT 1 AS data_scope_type,
- 0 AS urban_rural_type,
- '全区最高分' AS sys_org_name,
- 99999999 AS sys_org_id,
- T.course_id,
- NULL AS total_count,
- MAX(T.avg_score) AS avg_score,
- NULL AS order_in_total,
- NULL AS order_in_same,
- NULL AS avg_score_diff,
- NULL AS score_max
- FROM
- (
- SELECT sys_org_id, course_id, AVG(score) AS avg_score
- FROM exam_score
- WHERE exam_plan_id = @examPlanId AND grade_id = @gradeId AND is_excluded = 0 AND score > 0 AND (exam_sample_type = @examSampleType OR @examSampleType = 0)
- GROUP BY sys_org_id, course_id
- ) AS T
- GROUP BY T.course_id
- ) AS T1
- ORDER BY T1.data_scope_type, T1.urban_rural_type, T1.course_id, T1.order_in_total, T1.sys_org_id, T1.total_count
- ;
- ", new { ExamPlanId = examPlanId, GradeId = gradeId, ExamSampleType = sampleType.HasValue ? (short)sampleType : 0 });
- return items;
- }
- #endregion
- }
|