diff --git a/backend/Tnsu.ApprovalRoute.Application/Reports/VacancyReportWorkbook.cs b/backend/Tnsu.ApprovalRoute.Application/Reports/VacancyReportWorkbook.cs index c950894..99ee23a 100644 --- a/backend/Tnsu.ApprovalRoute.Application/Reports/VacancyReportWorkbook.cs +++ b/backend/Tnsu.ApprovalRoute.Application/Reports/VacancyReportWorkbook.cs @@ -216,11 +216,16 @@ public static class VacancyReportWorkbook /// private static void FinishVacancyListSheet(XSSFSheet sheet, Styles styles, int lastDataRowIdx) { - // Даты — дефолтным стилем колонки, а не только по заполненным ячейкам: - // формат должен остаться и у строк, которые допишут руками. - foreach (var col in (int[])[ColSubmitDate, ColClosingDate, ColStartDate]) - sheet.SetDefaultColumnStyle(col, styles.DataDate); - + // ВАЖНО: даты НЕ переносятся сюда через SetDefaultColumnStyle — NPOI (в + // отличие от чистого OOXML, где стиль колонки должен уступать явному + // стилю ячейки) переписывает им стиль уже существующих ячеек колонки + // целиком, включая шапку: заголовки «Дата подачи заявки»/«Дата закрытия + // вакансии»/«Дата выхода» лишались синей заливки и получали формат даты + // вместо неё. Формат даты у самих дат и так стоит явно, ячейка за + // ячейкой (см. SetDate) — колонки, дописанные в файл руками ниже данных, + // формат не унаследуют, но это не тот случай, ради которого стоит опять + // ломать шапку. + // // Шапка закреплена — лист длинный, без этого при прокрутке не видно, // какая колонка какая. sheet.CreateFreezePane(0, HeaderRowIdx + 1); diff --git a/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/VacancyReportWorkbookTests.cs b/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/VacancyReportWorkbookTests.cs index 1b6bd2c..6861295 100644 --- a/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/VacancyReportWorkbookTests.cs +++ b/backend/tests/Tnsu.ApprovalRoute.IntegrationTests/ApplicationServices/VacancyReportWorkbookTests.cs @@ -90,6 +90,23 @@ public sealed class VacancyReportWorkbookTests IsEmptyAt(sheet, 1, 17).ShouldBeTrue(); } + [Fact(DisplayName = "Шапка колонок с датами закрашена так же, как остальная шапка")] + public void Header_DateColumns_SameStyleAsRestOfHeader() + { + // Регрессия: даты когда-то получали формат через SetDefaultColumnStyle, + // а он в NPOI переписывает стиль УЖЕ существующих ячеек колонки — + // включая шапку, которая от этого лишалась заливки (H1/I1/K1 получали + // DataDate вместо Header). Формат даты теперь ставится только на сами + // ячейки с датами (см. SetDate), шапки колонок с датами он не касается. + var sheet = BuildListSheet(new VacancyReportGroup("", [Row("Логист")])); + + // NPOI отдаёт на каждый вызов CellStyle новую обёртку — сравнивать + // нужно индекс стиля в книге, а не ссылки на объекты. + var headerStyleIndex = CellAt(sheet, 1, 3)!.CellStyle.Index; // «Вакансия» — заведомо обычная шапка. + foreach (var col in (int[])[8, 9, 11]) // H «Дата подачи заявки», I «Дата закрытия», K «Дата выхода» + CellAt(sheet, 1, col)!.CellStyle.Index.ShouldBe(headerStyleIndex); + } + [Fact(DisplayName = "Строка вакансии: значения в своих колонках, «Комментарии» пусты")] public void DataRow_Layout() {