many bug fixes and features added
This commit is contained in:
192
src/SportsDivision.Web/Reports/ReportExcelExporter.cs
Normal file
192
src/SportsDivision.Web/Reports/ReportExcelExporter.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using ClosedXML.Excel;
|
||||
using SportsDivision.Application.DTOs;
|
||||
using SportsDivision.Application.DTOs.ReportDtos;
|
||||
|
||||
namespace SportsDivision.Web.Reports;
|
||||
|
||||
/// <summary>
|
||||
/// Builds Microsoft Excel (.xlsx) workbooks for each report. One worksheet per
|
||||
/// report, with a title, subtitle (tournament name), a styled header row, and
|
||||
/// flattened data rows for the nested reports.
|
||||
/// </summary>
|
||||
public static class ReportExcelExporter
|
||||
{
|
||||
public const string MimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
|
||||
private static int WriteHeader(IXLWorksheet ws, string title, string subtitle, string[] columns)
|
||||
{
|
||||
ws.Cell(1, 1).Value = title;
|
||||
ws.Cell(1, 1).Style.Font.Bold = true;
|
||||
ws.Cell(1, 1).Style.Font.FontSize = 14;
|
||||
ws.Range(1, 1, 1, Math.Max(1, columns.Length)).Merge();
|
||||
|
||||
ws.Cell(2, 1).Value = subtitle;
|
||||
ws.Cell(2, 1).Style.Font.Italic = true;
|
||||
ws.Range(2, 1, 2, Math.Max(1, columns.Length)).Merge();
|
||||
|
||||
const int headerRow = 4;
|
||||
for (int i = 0; i < columns.Length; i++)
|
||||
{
|
||||
var c = ws.Cell(headerRow, i + 1);
|
||||
c.Value = columns[i];
|
||||
c.Style.Font.Bold = true;
|
||||
c.Style.Fill.BackgroundColor = XLColor.FromHtml("#003366");
|
||||
c.Style.Font.FontColor = XLColor.White;
|
||||
}
|
||||
return headerRow + 1;
|
||||
}
|
||||
|
||||
private static byte[] Finish(XLWorkbook wb, params IXLWorksheet[] sheets)
|
||||
{
|
||||
foreach (var ws in sheets)
|
||||
{
|
||||
ws.SheetView.FreezeRows(4);
|
||||
ws.Columns().AdjustToContents();
|
||||
}
|
||||
using var ms = new MemoryStream();
|
||||
wb.SaveAs(ms);
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private static void SetInt(IXLCell cell, int? v) { if (v.HasValue) cell.Value = v.Value; else cell.Value = "-"; }
|
||||
private static void SetDec(IXLCell cell, decimal? v) { if (v.HasValue) cell.Value = v.Value; else cell.Value = "-"; }
|
||||
|
||||
public static byte[] PopularEvents(IEnumerable<PopularEventsReportDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Popular Events");
|
||||
int r = WriteHeader(ws, "Popular Events Report", tournamentName,
|
||||
new[] { "Event", "Category", "Total", "Male", "Female" });
|
||||
foreach (var e in data)
|
||||
{
|
||||
ws.Cell(r, 1).Value = e.EventName;
|
||||
ws.Cell(r, 2).Value = e.Category;
|
||||
ws.Cell(r, 3).Value = e.RegistrationCount;
|
||||
ws.Cell(r, 4).Value = e.MaleCount;
|
||||
ws.Cell(r, 5).Value = e.FemaleCount;
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
|
||||
public static byte[] RegistrationByGender(IEnumerable<RegistrationByGenderReportDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Registration by Gender");
|
||||
int r = WriteHeader(ws, "Registration by Gender", tournamentName,
|
||||
new[] { "Event", "Level", "Male", "Female", "Total" });
|
||||
foreach (var e in data)
|
||||
{
|
||||
ws.Cell(r, 1).Value = e.EventName;
|
||||
ws.Cell(r, 2).Value = e.EventLevelName;
|
||||
ws.Cell(r, 3).Value = e.MaleCount;
|
||||
ws.Cell(r, 4).Value = e.FemaleCount;
|
||||
ws.Cell(r, 5).Value = e.TotalCount;
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
|
||||
public static byte[] EventSchoolReport(IEnumerable<EventSchoolReportDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Event School Report");
|
||||
int r = WriteHeader(ws, "Event School Report", tournamentName,
|
||||
new[] { "Event", "Level", "School", "Student", "Performance", "Placement", "Points" });
|
||||
foreach (var ev in data)
|
||||
foreach (var school in ev.Schools)
|
||||
foreach (var s in school.Students)
|
||||
{
|
||||
ws.Cell(r, 1).Value = ev.EventName;
|
||||
ws.Cell(r, 2).Value = ev.EventLevelName;
|
||||
ws.Cell(r, 3).Value = school.SchoolName;
|
||||
ws.Cell(r, 4).Value = s.StudentName;
|
||||
SetDec(ws.Cell(r, 5), s.RawPerformance);
|
||||
SetInt(ws.Cell(r, 6), s.Placement);
|
||||
ws.Cell(r, 7).Value = s.PlacementPoints;
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
|
||||
public static byte[] StudentsBySchool(IEnumerable<StudentsBySchoolReportDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Students by School");
|
||||
int r = WriteHeader(ws, "Students by School", tournamentName,
|
||||
new[] { "School", "Zone", "Student", "Sex", "Events" });
|
||||
foreach (var school in data)
|
||||
foreach (var s in school.Students)
|
||||
{
|
||||
ws.Cell(r, 1).Value = school.SchoolName;
|
||||
ws.Cell(r, 2).Value = school.ZoneName;
|
||||
ws.Cell(r, 3).Value = s.StudentName;
|
||||
ws.Cell(r, 4).Value = s.Sex;
|
||||
ws.Cell(r, 5).Value = string.Join(", ", s.Events);
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
|
||||
public static byte[] ScoresByEvent(IEnumerable<ScoresByEventReportDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Scores by Event");
|
||||
int r = WriteHeader(ws, "Scores by Event", tournamentName,
|
||||
new[] { "Event", "Level", "Category", "Placement", "Student", "School", "Performance", "WA Points", "Placement Points" });
|
||||
foreach (var ev in data)
|
||||
foreach (var s in ev.Scores)
|
||||
{
|
||||
ws.Cell(r, 1).Value = ev.EventName;
|
||||
ws.Cell(r, 2).Value = ev.EventLevelName;
|
||||
ws.Cell(r, 3).Value = ev.Category;
|
||||
SetInt(ws.Cell(r, 4), s.Placement);
|
||||
ws.Cell(r, 5).Value = s.StudentName;
|
||||
ws.Cell(r, 6).Value = s.SchoolName;
|
||||
ws.Cell(r, 7).Value = s.RawPerformance;
|
||||
ws.Cell(r, 8).Value = s.CalculatedPoints;
|
||||
ws.Cell(r, 9).Value = s.PlacementPoints;
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
|
||||
public static byte[] StudentPoints(IEnumerable<StudentPointsReportDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Student Points");
|
||||
int r = WriteHeader(ws, "Student Points", tournamentName,
|
||||
new[] { "Student", "School", "Sex", "Total Placement Points", "Events" });
|
||||
foreach (var s in data)
|
||||
{
|
||||
ws.Cell(r, 1).Value = s.StudentName;
|
||||
ws.Cell(r, 2).Value = s.SchoolName;
|
||||
ws.Cell(r, 3).Value = s.Sex;
|
||||
ws.Cell(r, 4).Value = s.TotalPlacementPoints;
|
||||
ws.Cell(r, 5).Value = s.EventCount;
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
|
||||
public static byte[] SchoolStandings(IEnumerable<SchoolPointsSummaryDto> data, string tournamentName)
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("School Standings");
|
||||
int r = WriteHeader(ws, "School Standings", tournamentName,
|
||||
new[] { "Rank", "School", "Short Name", "Total Points", "1st Place", "2nd Place", "3rd Place" });
|
||||
int rank = 1;
|
||||
foreach (var s in data)
|
||||
{
|
||||
ws.Cell(r, 1).Value = rank++;
|
||||
ws.Cell(r, 2).Value = s.SchoolName;
|
||||
ws.Cell(r, 3).Value = s.ShortName ?? string.Empty;
|
||||
ws.Cell(r, 4).Value = s.TotalPoints;
|
||||
ws.Cell(r, 5).Value = s.FirstPlaceCount;
|
||||
ws.Cell(r, 6).Value = s.SecondPlaceCount;
|
||||
ws.Cell(r, 7).Value = s.ThirdPlaceCount;
|
||||
r++;
|
||||
}
|
||||
return Finish(wb, ws);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user