using Asp.Versioning; using MediatR; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; using Mirea.Api.Dto.Requests; using Mirea.Api.Endpoint.Configuration.Model; using OfficeOpenXml; using System; using System.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; namespace Mirea.Api.Endpoint.Controllers.V1; [ApiVersion("1.0")] public class ImportController(IMediator mediator, IOptionsSnapshot config) : BaseController { // todo: transfer data to storage private static string GetFaculty(char c) => c switch { 'У' => "ИТУ", 'Б' => "ИКБ", 'Х' => "ИТХТ", 'Э' => "ИПТИП", 'Т' => "ИПТИП", 'Р' => "ИРИ", 'К' => "ИИИ", 'И' => "ИИТ", 'П' => "ИИТ", _ => throw new ArgumentOutOfRangeException(nameof(c), c, null) }; /// /// Creates an Excel file based on a schedule filter /// /// The request object containing filter criteria. /// Excel file [HttpPost("ImportToExcel")] [Produces("application/vnd.ms-excel")] public async Task ImportToExcel([FromBody] ScheduleRequest request) { var result = (await mediator.Send(new GetScheduleListQuery { IsEven = request.IsEven, DisciplineIds = request.Disciplines, GroupIds = request.Groups, LectureHallIds = request.LectureHalls, ProfessorIds = request.Professors })).Schedules; if (result.Count == 0) return NoContent(); ExcelPackage.LicenseContext = LicenseContext.NonCommercial; using var package = new ExcelPackage(); var worksheet = package.Workbook.Worksheets.Add("Расписание"); int row = 1; int col = 1; worksheet.Cells[row, col++].Value = "День"; worksheet.Cells[row, col++].Value = "Пара"; worksheet.Cells[row, col++].Value = "Неделя"; worksheet.Cells[row, col++].Value = "Время"; worksheet.Cells[row, col++].Value = "Группа"; worksheet.Cells[row, col++].Value = "Институт"; worksheet.Cells[row, col++].Value = "Курс"; worksheet.Cells[row, col++].Value = "Дисциплина"; worksheet.Cells[row, col++].Value = "Преподаватель"; worksheet.Cells[row, col++].Value = "Вид"; worksheet.Cells[row, col++].Value = "Кампус"; worksheet.Cells[row, col].Value = "Ауд."; row++; col = 1; var pairsDictionary = config.Value.ScheduleSettings!.PairPeriod; var ruCulture = new CultureInfo("ru-RU"); foreach (var dto in result.GroupBy(s => new { s.DayOfWeek, s.PairNumber, s.IsEven, s.DisciplineId, TypeOfOccupations = string.Join(',', s.TypeOfOccupations.OrderBy(x => x)), LectureHalls = string.Join(',', s.LectureHalls.OrderBy(x => x)), Campus = string.Join(',', s.Campus.OrderBy(x => x)), Professors = string.Join(',', s.Professors.OrderBy(x => x)) }) .Select(g => new { g.Key.DayOfWeek, g.Key.PairNumber, g.Key.IsEven, g.First().Discipline, g.First().LectureHalls, g.First().Campus, g.First().Professors, Groups = string.Join('\n', g.Select(x => x.Group)), IsExclude = g.First().IsExcludedWeeks, g.First().TypeOfOccupations, g.First().Weeks }) .ToList()) { // День worksheet.Cells[row, col++].Value = $"{(int)dto.DayOfWeek} [{ruCulture.DateTimeFormat.GetAbbreviatedDayName(dto.DayOfWeek).ToUpper()}]"; // Пара worksheet.Cells[row, col++].Value = dto.PairNumber + " п"; // Неделя worksheet.Cells[row, col++].Value = $"[{(dto.IsEven ? 2 : 1)}] {(dto.IsEven ? "Четная" : "Нечетная")}"; // Время worksheet.Cells[row, col++].Value = pairsDictionary[dto.PairNumber].Start.ToString(ruCulture); // Группа worksheet.Cells[row, col].Style.WrapText = true; worksheet.Cells[row, col++].Value = dto.Groups; var groupTemplate = dto.Groups.Split('\n')[0]; // Институт worksheet.Cells[row, col++].Value = GetFaculty(groupTemplate[0]); // Курс worksheet.Cells[row, col++].Value = groupTemplate[2] == 'М' ? 'М' : (24 - int.Parse(groupTemplate.Split(' ')[0].Split('-').TakeLast(1).ElementAt(0)) + 1).ToString(); var disciplineAdditional = string.Empty; if (dto.IsExclude.HasValue && dto.Weeks != null && dto.Weeks.Any()) disciplineAdditional += $"{(dto.IsExclude.Value ? "Кр. " : "")}{string.Join(", ", dto.Weeks.OrderBy(x => x))} н. "; // Дисциплина worksheet.Cells[row, col++].Value = disciplineAdditional + dto.Discipline; // Преподаватель worksheet.Cells[row, col++].Value = dto.Professors; // Вид worksheet.Cells[row, col++].Value = dto.TypeOfOccupations.FirstOrDefault(); // Кампус worksheet.Cells[row, col++].Value = dto.Campus.FirstOrDefault()?.Replace("С-20", "С20").Replace("В-78", "В78"); // Ауд. worksheet.Cells[row, col].Value = dto.LectureHalls; col = 1; row++; } worksheet.Cells[1, 1, 1, 12].AutoFilter = true; worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns(); var stream = new MemoryStream(); await package.SaveAsAsync(stream); stream.Position = 0; return File(stream, "application/vnd.ms-excel", "data.xlsx"); } }