diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/ContentListSheet.cs b/AsbCloudInfrastructure/Services/DrillingProgram/ContentListSheet.cs new file mode 100644 index 00000000..e49f3443 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DrillingProgram/ContentListSheet.cs @@ -0,0 +1,41 @@ +using AsbCloudApp.Data; +using ClosedXML.Excel; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudInfrastructure.Services.DrillingProgram +{ +#nullable enable + public class ContentListSheet + { + private readonly List parts; + + public ContentListSheet(IEnumerable parts) + { + this.parts = parts.ToList(); + } + + public void Draw(IXLWorksheet sheet) + { + sheet.Style.Font.FontName = "Calibri"; + sheet.Style.Font.FontSize = 12; + + sheet.Cell(2, 2) + .SetValue("Содержание") + .Style + .Font.SetBold(true) + .Font.SetFontSize(14); + + for (int i = 0; i < parts.Count; i++) + { + sheet.Cell(4 + i, 1) + .SetValue(i + 1); + + sheet.Cell(4 + i, 2) + .SetValue(parts[i].Name); + } + } + } +#nullable disable +} diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramMaker.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramMaker.cs index f4248a73..dae5ff4f 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramMaker.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramMaker.cs @@ -10,9 +10,18 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram { private const int maxAllowedColumns = 256; - public static void UniteExcelFiles(IEnumerable excelFilesNames, string resultExcelPath) + public static void UniteExcelFiles(IEnumerable excelFilesNames, string resultExcelPath, IEnumerable parts, AsbCloudApp.Data.WellDto well) { var resultExcelFile = new XLWorkbook(XLEventTracking.Disabled); + + var titleSheet = resultExcelFile.AddWorksheet("Титульный лист"); + var marks = parts.SelectMany(p => p.File.FileMarks); + var titleSheetMaker = new TitleListSheet(marks, well); + titleSheetMaker.Draw(titleSheet); + + var contentSheet = resultExcelFile.AddWorksheet("Содержание"); + var contentListSheetMaker = new ContentListSheet(parts); + contentListSheetMaker.Draw(contentSheet); var filteredFileNames = excelFilesNames.Distinct(); diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs index e3c90574..47bb3779 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs @@ -109,6 +109,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram var partEntities = await context.DrillingProgramParts .Include(p => p.RelatedUsers) .ThenInclude(r => r.User) + .ThenInclude(u => u.Company) .Where(p => p.IdWell == idWell) .ToListAsync(token); @@ -481,7 +482,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram using var context = new AsbCloudDbContext(contextOptions); var fileService = new FileService(context); var files = state.Parts.Select(p => fileService.GetUrl(p.File)); - DrillingProgramMaker.UniteExcelFiles(files, tempResultFilePath); + DrillingProgramMaker.UniteExcelFiles(files, tempResultFilePath, state.Parts, well); await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token); } diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs b/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs new file mode 100644 index 00000000..591b6c15 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs @@ -0,0 +1,160 @@ +using AsbCloudApp.Data; +using ClosedXML.Excel; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudInfrastructure.Services.DrillingProgram +{ +#nullable enable + public class TitleListSheet + { + private const string directionDirectorPositionName = "Руководитель направления по ТСБ"; + + private readonly DateTime totalDate; + private readonly FileMarkDto? acceptDirectionDirector; + private readonly List acceptsOthers; + private readonly WellDto well; + + public TitleListSheet(IEnumerable fileMarks, WellDto well) + { + totalDate = fileMarks.Max(f => f.DateCreated); + acceptDirectionDirector = fileMarks + .OrderByDescending(f => f.DateCreated) + .FirstOrDefault(f => f.User.Position == directionDirectorPositionName); + acceptsOthers = fileMarks + .Where(f => f.Id != acceptDirectionDirector?.Id) + .OrderBy(f => f.DateCreated) + .ToList(); + this.well = well; + } + + public void Draw(IXLWorksheet sheet) + { + const double santimetr = 0.393701; + sheet.Style.Font.FontName = "Calibri"; + sheet.Style.Font.FontSize = 12; + sheet.PageSetup.PaperSize = XLPaperSize.A4Paper; + sheet.PageSetup.Margins + .SetTop(santimetr) + .SetLeft(2 * santimetr) + .SetBottom(santimetr) + .SetRight(santimetr); + + DrawTopRightSign(sheet); + DrawMainTilte(sheet); + DrawOtherAcceptors(sheet); + + sheet.Range(51, 1, 51, 5) + .Merge() + .SetValue($"{totalDate.Year:00}") + .Style.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center); + + var k = 4.95867768595041; + sheet.Column(1).Width = k*2.3; + sheet.Column(2).Width = k*6; + sheet.Column(3).Width = k*0.53; + sheet.Column(4).Width = k*2.3; + sheet.Column(5).Width = k*6; + } + + private void DrawTopRightSign(IXLWorksheet sheet) + { + if (acceptDirectionDirector is null) + return; + + var user = acceptDirectionDirector.User; + + sheet.Cell(1, 5) + .SetValue("Согласовано:"); + + sheet.Cell(2, 5) + .SetValue(user.Position); + + sheet.Cell(3, 5) + .SetValue(user.Company?.Caption); + + sheet.Cell(4, 5) + .SetValue($"{user.Surname} {user.Name} {user.Patronymic}"); + + sheet.Cell(5, 5) + .SetValue(FormatDate(acceptDirectionDirector.DateCreated)); + + sheet.Range(1,5, 5,5).Style.Alignment + .SetHorizontal(XLAlignmentHorizontalValues.Right); + } + + private void DrawMainTilte(IXLWorksheet sheet) + { + sheet.Range(11, 1, 11, 5) + .Merge() + .SetValue($"Программа на бурение скважины №{well.Caption}, куст №{well.Cluster}"); + + sheet.Range(12, 1, 12, 5) + .Merge() + .SetValue($"{well.Deposit} месторождения"); + + sheet.Range(11, 1, 12, 5).Style + .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center) + .Font.SetFontSize(14) + .Font.SetBold(true); + } + + private void DrawOtherAcceptors(IXLWorksheet sheet) + { + const int baseRow = 16; + const int deltaRow = 7; + (int row, int col)[] addresses = + { + (baseRow + 4 * deltaRow, 4), (baseRow + 4 * deltaRow, 1), + (baseRow + 3 * deltaRow, 4), (baseRow + 3 * deltaRow, 1), + (baseRow + 2 * deltaRow, 4), (baseRow + 2 * deltaRow, 1), + (baseRow + 1 * deltaRow, 4), (baseRow + 1 * deltaRow, 1), + (baseRow + 0 * deltaRow, 4), (baseRow + 0 * deltaRow, 1), + }; + var i = 0; + for (; i < acceptsOthers.Count && i < 10; i++) + DrawAccept(sheet, acceptsOthers[i], addresses[i]); + + sheet.Cell(addresses[i-1].row - 2, 1) + .SetValue("Утверждаю:"); + } + + private void DrawAccept(IXLWorksheet sheet, FileMarkDto mark, (int row, int col) startAddress) + { + int startRow = startAddress.row; + int startCol = startAddress.col; + var user = mark.User; + sheet.Cell(startRow, startCol) + .SetValue("Должность"); + + sheet.Range(startRow, startCol + 1, startRow + 1, startCol + 1) + .Merge() + .SetValue(user.Position); + + sheet.Cell(startRow + 2, startCol) + .SetValue("Компания"); + + sheet.Range(startRow + 2, startCol + 1, startRow + 3, startCol + 1) + .Merge() + .SetValue(user.Company?.Caption); + + sheet.Range(startRow + 4, startCol, startRow + 4, startCol + 1) + .Merge() + .SetValue($"{user.Surname} {user.Name} {user.Patronymic}"); + + sheet.Range(startRow + 5, startCol, startRow + 5, startCol + 1) + .Merge() + .SetValue(FormatDate(mark.DateCreated)); + + sheet.Range(startRow, startCol, startRow + 5, startCol + 1) + .Style.Border.SetOutsideBorder(XLBorderStyleValues.Thin) + .Alignment.SetVertical(XLAlignmentVerticalValues.Top) + .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Left); + } + + private static string FormatDate(DateTime dateTime) + => $"{dateTime.Day:00}.{dateTime.Month:00}.{dateTime.Year:00}"; + } +#nullable disable +} diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/TitleTemplate.xlsx b/AsbCloudInfrastructure/Services/DrillingProgram/TitleTemplate.xlsx new file mode 100644 index 00000000..589263b2 Binary files /dev/null and b/AsbCloudInfrastructure/Services/DrillingProgram/TitleTemplate.xlsx differ