using AsbCloudApp.Data; using ClosedXML.Excel; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.DailyReport { public class DailyReportMakerExcel { const string sheetNameSchedule = "Дневной отчёт"; const string sheetNameTvd = "ГГД"; const int maxChartsToWrap = 88; //Dictionary ParamsCellsIndexes = //new Dictionary() //ошибка int[,] ParamsCellsIndexes = new int[41,2] { {3,6},//название скважины {3,7},//название куста {4,4},//заказчик {5,4},//подрядчик {9,3},//дата рапорта {9,7},//глубина забоя на дату начала интервала {9,9},//глубина забоя на дату окончания интервала {13,3},//Глубина забоя по стволу на окончание отчетного периода {13,5},//Глубина забоя по вертикали на дату окончания отчетного периода {13,7},//Зeнитный угол на дату окончания отчетного периода {13,9},//Азимутальный угол на дату окончания отчетного периода {15,5},//ФИО бурильщиков {16,5},//ФИО бурильщиков {19,6},//Время работы АПД {20,6},//Время работы спин мастер {21,6},//Время работы торк мастер {19,7},//количество метров пробуренных с включенным АПД {20,7},//количество метров пробуренных с включенным Спин мастер {21,7},//количество метров пробуренных с включенным торк мастер {22,6},//Количество запусков МСЕ {24,3},//КНБК описание {43,5},//Нормативное время на одну операцию по подготовке ствола скважины к наращиванию {43,7},//Нормативное время на одну операцию по наращиванию {45,5},//Фактическое время проработок при подготовке ствола скважины к наращиванию. {45,7},//Фактическое время наращиваний {50,3},//Режимы бурения в роторе {51,3},//режимы бурения в слайде {55,3},//Количество метров пробуренных в роторе за отчетный период {55,4},//Количество часов бурения в роторе за отчетный период {55,6},//средний диф перепад в роторе за отчетный период {59,3},//количество метров пробуренных в слайде за отчетный период {59,4},//время бурения в роторе за отчетный период {59,6},//средний диф перепад в слайде за отчетный период {63,6},//Плановая МСП за секцию {70,7},//Общее время бурения за секцию {71,7},//Общая проходка за секцию {72,7},//Количество наращиваний за отчетный период {73,7},//Отклонение относительно ГГД {74,3},//указываются все причины, которые влияют на снижение МСП. {78,9},//ФИО Мастера буровой {80,9}//ФИО супервайзера }; public int AddBlockHead(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow, 3).Value = $"Суточная сводка бурения скважины №{reportDto.WellName}, куст: {reportDto.ClusterName}"; sheet.Cell(startRow + 1, 3).Value = $"Заказчик: {reportDto.Customer}"; sheet.Cell(startRow + 2, 3).Value = $"Подрядчик: {reportDto.Contractor}"; return startRow + 2; } public int AddBlockSlaughtersReport(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 4, 3).Value = $"{reportDto.ReportDate}"; sheet.Cell(startRow + 4, 5).Value = $"{reportDto.WellDepthIntervalStartDate}"; sheet.Cell(startRow + 4, 6).Value = $"{reportDto.WellDepthIntervalFinishDate}"; return startRow + 4; } public int AddBlockTrajectoryReport(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 4, 3).Value = $"{reportDto.BottomholeDepth}"; sheet.Cell(startRow + 4, 4).Value = $"{reportDto.VerticalDepth}"; sheet.Cell(startRow + 4, 5).Value = $"{reportDto.ZenithAngle}"; sheet.Cell(startRow + 4, 6).Value = $"{reportDto.AzimuthAngle}"; return startRow + 4; } public int AddBlockDrillers(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 2, 4).Value = $"{reportDto.FirstDriller}"; sheet.Cell(startRow + 3, 4).Value = $"{reportDto.SecondDriller}"; return startRow + 3; } public int AddBlockSAUB(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 3, 6).Value = $"{reportDto.WorkTimeSAUB}"; sheet.Cell(startRow + 4, 6).Value = $"{reportDto.WorkTimeSpinMaster}"; sheet.Cell(startRow + 5, 6).Value = $"{reportDto.WorkTimeTorkMaster}"; sheet.Cell(startRow + 3, 7).Value = $"{reportDto.PenetrationSAUB}"; sheet.Cell(startRow + 4, 7).Value = $"{reportDto.PenetrationSpinMaster}"; sheet.Cell(startRow + 5, 7).Value = $"{reportDto.PenetrationTorkMaster}"; sheet.Cell(startRow + 6, 6).Value = $"{reportDto.CountLaunchesMSE}"; return startRow + 6; } public int AddBlockBHA(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 3, 6).Value = $"{reportDto.WorkTimeSAUB}"; sheet.Cell(startRow + 4, 6).Value = $"{reportDto.WorkTimeSpinMaster}"; sheet.Cell(startRow + 5, 6).Value = $"{reportDto.WorkTimeTorkMaster}"; sheet.Cell(startRow + 3, 7).Value = $"{reportDto.PenetrationSAUB}"; sheet.Cell(startRow + 4, 7).Value = $"{reportDto.PenetrationSpinMaster}"; sheet.Cell(startRow + 5, 7).Value = $"{reportDto.PenetrationTorkMaster}"; sheet.Cell(startRow + 6, 6).Value = $"{reportDto.CountLaunchesMSE}"; return startRow + 6; } public int AddBlockBHADescription(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 2, 3).Value = $"{reportDto.BHADescription}"; return startRow + 6; } public int AddBlockOperations(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { return startRow + 7; } public int AddBlockTimeBalans(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { return startRow + 8; } public int AddBlockMeterlessWorks(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 4, 6).Value = $"{reportDto.StandardTimeBarrelPreparation}"; sheet.Cell(startRow + 4, 9).Value = $"{reportDto.StandardTimeExtension}"; sheet.Cell(startRow + 6, 6).Value = $"{reportDto.ActualTimeBarrelPreparation}"; sheet.Cell(startRow + 6, 9).Value = $"{reportDto.ActualTimeExtension}"; return startRow + 9; } public int AddBlockDrillingModes(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 2, 6).Value = $"{reportDto.RotorDrillingModes}"; sheet.Cell(startRow + 3, 9).Value = $"{reportDto.SlideDrillingModes}"; return startRow + 3; } public int AddBlockRotorDrilling(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 3, 3).Value = $"{reportDto.PenetrationInRotor}"; sheet.Cell(startRow + 3, 5).Value = $"{reportDto.NumberDrillingHours}"; sheet.Cell(startRow + 3, 9).Value = $"{reportDto.AVGDiffDropRotor}"; return startRow + 3; } public int AddBlockSlideDrilling(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 3, 3).Value = $"{reportDto.PenetrationInSlide}"; sheet.Cell(startRow + 3, 5).Value = $"{reportDto.DrillingTimeInRotor}"; sheet.Cell(startRow + 3, 9).Value = $"{reportDto.AVGDiffPressureSlide}"; return startRow + 3; } public int AddBlockROPPlan(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 3, 9).Value = $"{reportDto.SectionROPPlan}"; return startRow + 3; } public int AddBlockSummary(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 7, 7).Value = $"{reportDto.SectionDrillingTimeTotal}"; sheet.Cell(startRow + 8, 7).Value = $"{reportDto.SectionPenetrationTotal}"; sheet.Cell(startRow + 9, 7).Value = $"{reportDto.ExtensionsCount}"; sheet.Cell(startRow + 10, 7).Value = $"{reportDto.DeviationFromTVD}"; sheet.Cell(startRow + 11, 3).Value = $"{reportDto.DeclinesReasonsROP}"; return startRow + 13; } public int AddBlockSubscribes(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) { sheet.Cell(startRow + 3, 9).Value = $"{reportDto.DrillingMaster}"; sheet.Cell(startRow + 5, 9).Value = $"{reportDto.Supervisor}"; return startRow + 5; } public Stream GetExcelTemplateStream() { var assembly = System.Reflection.Assembly.GetAssembly(typeof(AsbCloudInfrastructure.IInfrastructureMarker)); var stream = assembly.GetManifestResourceStream("AsbCloudInfrastructure.Services.DailyReport.DailyReportTemplate.xlsx"); return stream; } public void FillScheduleSheetToWorkbook(XLWorkbook workbook, DailyReportDto reportDto, WellDto well) { var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameSchedule); if (sheet is null) return; const int headerRowsCount = 6; const int rowTitle = 3; const int columnRowNumber = 2; const int columnCaption = 3; const int columnWellDepthStartPlan = 4; const int columnWellDepthStartFact = 5; const int columnWellDepthStartPredict = 6; const int columnWellDepthEndPlan = 7; const int columnWellDepthEndFact = 8; const int columnWellDepthEndPredict = 9; const int columnDeltaWellDepthPerDay = 10; const int columnDurationPlan = 11; const int columnDurationFact = 12; const int columnDurationPredict = 13; const int columnDateStartPlan = 14; const int columnDateStartFact = 15; const int columnDateStartPredict = 16; const int columnDateEndPlan = 17; const int columnDateEndFact = 18; const int columnDateEndPredict = 19; const int columnGuilty = 20; const int columnNpt = 21; var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}"; sheet.Row(rowTitle).Cell(3).Value = subTitle; } public void FillTvdSheetToWorkbook(XLWorkbook workbook, DailyReportDto drd, WellDto well) { var sheet = workbook.Worksheets.FirstOrDefault(); //var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameTvd); //if (sheet is null) // return; //foreach (var item in ParamsCellsIndexes) //{ // SetCell(sheet.Row(item.Key), item.Value, "00"); //} //for (int i = 0; i < 41; i++) // { // SetCell(sheet.Row(ParamsCellsIndexes[i, 0]), ParamsCellsIndexes[i, 1], "00"); // } var activeRow = 3; activeRow = AddBlockHead(sheet, activeRow, drd); activeRow = AddBlockSlaughtersReport(sheet, activeRow, drd); activeRow = AddBlockTrajectoryReport(sheet, activeRow, drd); activeRow = AddBlockDrillers(sheet, activeRow, drd); activeRow = AddBlockSAUB(sheet, activeRow, drd); activeRow = AddBlockBHA(sheet, activeRow, drd); activeRow = AddBlockBHADescription(sheet, activeRow, drd); activeRow = AddBlockOperations(sheet, activeRow, drd); activeRow = AddBlockTimeBalans(sheet, activeRow, drd); activeRow = AddBlockMeterlessWorks(sheet, activeRow, drd); activeRow = AddBlockDrillingModes(sheet, activeRow, drd); activeRow = AddBlockRotorDrilling(sheet, activeRow, drd); activeRow = AddBlockSlideDrilling(sheet, activeRow, drd); activeRow = AddBlockROPPlan(sheet, activeRow, drd); activeRow = AddBlockSummary(sheet, activeRow, drd); activeRow = AddBlockSubscribes(sheet, activeRow, drd); } public static string GetColunmLetter(int columnNumber) { string letter = ""; while (columnNumber > 0) { int modulo = (columnNumber - 1) % 26; letter = Convert.ToChar('A' + modulo) + letter; columnNumber = (columnNumber - modulo) / 26; } return letter; } public static IXLStyle SetBorder(IXLStyle style) { style.Border.RightBorder = XLBorderStyleValues.Thin; style.Border.LeftBorder = XLBorderStyleValues.Thin; style.Border.TopBorder = XLBorderStyleValues.Thin; style.Border.BottomBorder = XLBorderStyleValues.Thin; style.Border.InsideBorder = XLBorderStyleValues.Thin; return style; } public static IXLCell SetDateTime(IXLCell cell) { cell.DataType = XLDataType.DateTime; cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS"; return cell; } public static IXLCell SetNumber(IXLCell cell) { cell.DataType = XLDataType.Number; cell.Style.NumberFormat.Format = "0.00"; return cell; } public static IXLCell SetCell(IXLRow row, int colunm, object value) { var cell = row.Cell(colunm); cell.Value = value; SetBorder(cell.Style); cell.Style.Alignment.WrapText = true; if (value is string valueString && valueString.Length > maxChartsToWrap) { var baseHeight = row.Height; row.Height = 0.82d * baseHeight * Math.Ceiling(1d + valueString.Length / maxChartsToWrap); } if (value is DateTime) { SetDateTime(cell); } else if (value is IFormattable) { SetNumber(cell); } return cell; } public Stream MakeReportAsync(DailyReportDto dailyReportDto, WellDto well) { var ecxelTemplateStream = GetExcelTemplateStream(); using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); FillScheduleSheetToWorkbook(workbook, dailyReportDto, well); FillTvdSheetToWorkbook(workbook, dailyReportDto, well); MemoryStream memoryStream = new MemoryStream(); workbook.SaveAs(memoryStream, new SaveOptions { }); memoryStream.Seek(0, SeekOrigin.Begin); return memoryStream; } } }