using ClosedXML.Excel; namespace Eis.Infrastructure.Administration; internal static class AdminArrangementExporter { private static readonly string[] InformationHeaders = [ "考生学校", "班级", "报名号", "姓名", "证件号码", "考试代码", "考试名称", "准考证号", "考点代码", "考点名称", "考点详细地址", "科目", "日期", "时间", "考试考场序号", "考场通用名称", "物理场地代码", "楼栋", "楼层", "座位号" ]; public static byte[] AdmitCardInformation( IReadOnlyList rows, string subtitle) { using var workbook = new XLWorkbook(); var sheet = workbook.Worksheets.Add("准考证信息"); ConfigureTable( sheet, $"准考证信息台账|{subtitle}", InformationHeaders, rows.Select(InformationValues).ToArray()); return Save(workbook); } public static byte[] CenterMaterials( IReadOnlyList rows, string subtitle) { using var workbook = new XLWorkbook(); var sorted = rows .OrderBy(item => item.CenterCode, StringComparer.Ordinal) .ThenBy(item => item.SubjectDate, StringComparer.Ordinal) .ThenBy(item => item.SubjectTime, StringComparer.Ordinal) .ThenBy(item => item.ExamRoomCode, StringComparer.Ordinal) .ThenBy(item => item.Seat, StringComparer.Ordinal) .ToArray(); AddDeskStickers(workbook.Worksheets.Add("桌贴"), sorted); var doors = sorted .GroupBy( item => new { item.ExamCode, item.SubjectName, item.CenterCode, item.ExamRoomCode, item.RoomCode }) .Select(group => (Row: group.First(), Count: group.Count())) .ToArray(); ConfigureTable( workbook.Worksheets.Add("门贴"), $"考场门贴|{subtitle}", [ "考试", "科目", "日期", "时间", "考点", "考试考场序号", "考场通用名称", "场地代码", "楼栋", "楼层", "人数" ], doors.Select(item => new object[] { item.Row.ExamName, item.Row.SubjectName, item.Row.SubjectDate, item.Row.SubjectTime, item.Row.CenterName, item.Row.ExamRoomCode, item.Row.RoomName, item.Row.RoomCode, item.Row.Building, item.Row.Floor, item.Count }).ToArray()); ConfigureTable( workbook.Worksheets.Add("考场签名单"), $"考场考生签名单|{subtitle}", [ "考试", "科目", "日期", "时间", "考试考场序号", "考场通用名称", "楼栋", "楼层", "座位号", "准考证号", "姓名", "考生学校", "班级", "考生签名" ], sorted.Select(item => new object[] { item.ExamName, item.SubjectName, item.SubjectDate, item.SubjectTime, item.ExamRoomCode, item.RoomName, item.Building, item.Floor, item.Seat, item.CardNumber, item.CandidateName, item.SchoolName, item.ClassName, "" }).ToArray()); return Save(workbook); } private static void AddDeskStickers( IXLWorksheet sheet, IReadOnlyList rows) { sheet.ShowGridLines = false; for (var column = 1; column <= 7; column++) sheet.Column(column).Width = column == 4 ? 3 : 14.5; for (var index = 0; index < rows.Count; index++) { var item = rows[index]; var slot = index % 2; var group = index / 2; var startRow = group * 9 + 1; var startColumn = slot == 0 ? 1 : 5; var values = new[] { item.ExamName, $"{item.SubjectName}|{item.SubjectDate} {item.SubjectTime}", "考试考场序号", item.ExamRoomCode, $"座位号 {item.Seat}", $"{item.RoomName}(场地 {item.RoomCode})|{item.Building} {item.Floor}", $"{item.CandidateName}|{item.SchoolName} {item.ClassName}", $"{item.CenterName}|准考证号 {item.CardNumber}" }; for (var offset = 0; offset < values.Length; offset++) { var range = sheet.Range( startRow + offset, startColumn, startRow + offset, startColumn + 2); range.Merge(); range.Value = values[offset]; range.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; range.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; range.Style.Alignment.WrapText = true; range.Style.Border.OutsideBorder = XLBorderStyleValues.Medium; range.Style.Border.InsideBorder = XLBorderStyleValues.Hair; sheet.Row(startRow + offset).Height = 28; } var title = sheet.Range(startRow, startColumn, startRow, startColumn + 2); title.Style.Fill.BackgroundColor = XLColor.FromHtml("#173F60"); title.Style.Font.FontColor = XLColor.White; title.Style.Font.Bold = true; var room = sheet.Range(startRow + 3, startColumn, startRow + 3, startColumn + 2); room.Style.Font.FontSize = 24; room.Style.Font.Bold = true; var seat = sheet.Range(startRow + 4, startColumn, startRow + 4, startColumn + 2); seat.Style.Fill.BackgroundColor = XLColor.FromHtml("#FFF1C7"); seat.Style.Font.FontColor = XLColor.FromHtml("#8A4B08"); seat.Style.Font.FontSize = 18; seat.Style.Font.Bold = true; } sheet.PageSetup.PageOrientation = XLPageOrientation.Portrait; sheet.PageSetup.FitToPages(1, 0); sheet.PageSetup.Margins.SetLeft(0.25); sheet.PageSetup.Margins.SetRight(0.25); sheet.PageSetup.Margins.SetTop(0.25); sheet.PageSetup.Margins.SetBottom(0.25); } private static void ConfigureTable( IXLWorksheet sheet, string title, IReadOnlyList headers, IReadOnlyList rows) { sheet.ShowGridLines = false; var lastColumn = headers.Count; var titleRange = sheet.Range(1, 1, 1, lastColumn); titleRange.Merge(); titleRange.Value = title; titleRange.Style.Fill.BackgroundColor = XLColor.FromHtml("#173F60"); titleRange.Style.Font.FontColor = XLColor.White; titleRange.Style.Font.FontSize = 16; titleRange.Style.Font.Bold = true; titleRange.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; sheet.Row(1).Height = 28; for (var column = 0; column < headers.Count; column++) { var cell = sheet.Cell(2, column + 1); cell.Value = headers[column]; cell.Style.Fill.BackgroundColor = XLColor.FromHtml("#2C7080"); cell.Style.Font.FontColor = XLColor.White; cell.Style.Font.Bold = true; cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; cell.Style.Alignment.WrapText = true; } for (var rowIndex = 0; rowIndex < rows.Count; rowIndex++) { for (var column = 0; column < headers.Count; column++) { var value = column < rows[rowIndex].Length ? rows[rowIndex][column] : ""; var cell = sheet.Cell(rowIndex + 3, column + 1); if (value is int integer) cell.Value = integer; else if (value is double number) cell.Value = number; else cell.Value = Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture) ?? ""; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; cell.Style.Alignment.WrapText = true; cell.Style.Border.BottomBorder = XLBorderStyleValues.Hair; cell.Style.Border.BottomBorderColor = XLColor.FromHtml("#D8E2E7"); } } sheet.SheetView.FreezeRows(2); if (rows.Count > 0) sheet.Range(2, 1, rows.Count + 2, lastColumn).SetAutoFilter(); sheet.Columns().AdjustToContents(8, 40); sheet.PageSetup.PageOrientation = XLPageOrientation.Landscape; sheet.PageSetup.FitToPages(1, 0); sheet.PageSetup.SetRowsToRepeatAtTop(1, 2); } private static object[] InformationValues(ArrangementExportRow item) => [ item.SchoolName, item.ClassName, item.CandidateNumber, item.CandidateName, item.IdNumber, item.ExamCode, item.ExamName, item.CardNumber, item.CenterCode, item.CenterName, item.CenterAddress, item.SubjectName, item.SubjectDate, item.SubjectTime, item.ExamRoomCode, item.RoomName, item.RoomCode, item.Building, item.Floor, item.Seat ]; private static byte[] Save(XLWorkbook workbook) { using var stream = new MemoryStream(); workbook.SaveAs(stream); return stream.ToArray(); } }