feat: enhance Excel export functionality with improved styling and download handling
All checks were successful
Publish Container / publish (push) Successful in 5m39s

This commit is contained in:
Marco 2026-05-20 11:34:54 +02:00
commit 8438a63bd8
3 changed files with 128 additions and 57 deletions

View file

@ -42,6 +42,43 @@ public sealed class MonthlyTimesheetExcelExporterTests
Assert.Equal("TOTALE", worksheet.Cell("AH1").GetString());
}
[Fact]
public void Export_ForMonthWhereSecondDayIsWeekend_OnlyHighlightsWeekendAndHolidayDays()
{
var exporter = new MonthlyTimesheetExcelExporter();
var timesheet = CreateTimesheet(new DateOnly(2026, 5, 1), new HashSet<DateOnly>
{
new(2026, 5, 4)
});
var templatePath = GetTemplatePath();
using var templateStream = File.OpenRead(templatePath);
var workbookBytes = exporter.Export(timesheet, templateStream);
using var workbook = new XLWorkbook(new MemoryStream(workbookBytes));
var worksheet = workbook.Worksheet(1);
var headerRegularFill = GetFillSignature(worksheet.Cell("C1"));
var headerSaturdayFill = GetFillSignature(worksheet.Cell("D1"));
var headerSundayFill = GetFillSignature(worksheet.Cell("E1"));
var headerHolidayFill = GetFillSignature(worksheet.Cell("F1"));
var headerNextWeekdayFill = GetFillSignature(worksheet.Cell("G1"));
Assert.NotEqual(headerRegularFill, headerSaturdayFill);
Assert.NotEqual(headerRegularFill, headerSundayFill);
Assert.Equal(headerSundayFill, headerHolidayFill);
Assert.Equal(headerRegularFill, headerNextWeekdayFill);
var bodyRegularFill = GetFillSignature(worksheet.Cell("C4"));
var bodySaturdayFill = GetFillSignature(worksheet.Cell("D4"));
var bodyHolidayFill = GetFillSignature(worksheet.Cell("F4"));
var bodyNextWeekdayFill = GetFillSignature(worksheet.Cell("G4"));
Assert.NotEqual(bodyRegularFill, bodySaturdayFill);
Assert.Equal(bodySaturdayFill, bodyHolidayFill);
Assert.Equal(bodyRegularFill, bodyNextWeekdayFill);
}
private static MonthlyTimesheetModel CreateTimesheet(DateOnly monthStart, ISet<DateOnly> holidays)
{
var lastDay = monthStart.AddMonths(1).AddDays(-1);
@ -116,4 +153,26 @@ public sealed class MonthlyTimesheetExcelExporterTests
throw new DirectoryNotFoundException("Unable to locate the WorkTracker repository root.");
}
private static string GetFillSignature(IXLCell cell)
{
var fill = cell.Style.Fill;
return string.Join(
"|",
fill.PatternType,
DescribeColor(fill.BackgroundColor),
DescribeColor(fill.PatternColor));
}
private static string DescribeColor(XLColor color)
{
return color.ColorType switch
{
XLColorType.Color => $"rgb:{color.Color.ToArgb()}",
XLColorType.Indexed => $"indexed:{color.Indexed}",
XLColorType.Theme => $"theme:{color.ThemeColor}:{Math.Round(color.ThemeTint, 12)}",
_ => color.ColorType.ToString()
};
}
}