2023-10-09 17:04:05 +05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using AsbCloudApp.Data.ProcessMaps.Report;
|
|
|
|
|
using AsbCloudApp.Services;
|
2023-10-16 13:45:29 +05:00
|
|
|
|
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
2023-10-09 17:04:05 +05:00
|
|
|
|
using ClosedXML.Excel;
|
|
|
|
|
|
2023-10-17 10:20:27 +05:00
|
|
|
|
namespace AsbCloudInfrastructure.Services.ProcessMaps.Report;
|
2023-10-09 17:04:05 +05:00
|
|
|
|
|
2023-10-16 13:45:29 +05:00
|
|
|
|
public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDrillingExportService
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
const int firstColumn = 2;
|
|
|
|
|
const int lastColumn = 42;
|
|
|
|
|
|
|
|
|
|
const int headerRowsCount = 5;
|
|
|
|
|
|
|
|
|
|
private readonly IWellService wellService;
|
2023-10-12 15:26:37 +05:00
|
|
|
|
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService;
|
2023-10-09 17:04:05 +05:00
|
|
|
|
|
2023-10-16 13:45:29 +05:00
|
|
|
|
public ProcessMapReportWellDrillingExportService(IWellService wellService,
|
2023-10-12 15:26:37 +05:00
|
|
|
|
IProcessMapReportWellDrillingService processMapReportWellDrillingService)
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
this.wellService = wellService;
|
2023-10-12 15:26:37 +05:00
|
|
|
|
this.processMapReportWellDrillingService = processMapReportWellDrillingService;
|
2023-10-09 17:04:05 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<(string Name, Stream File)?> ExportAsync(int idWell, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken);
|
|
|
|
|
|
|
|
|
|
if (well is null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var stream = GetExcelTemplateStream();
|
|
|
|
|
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
|
|
|
|
|
2023-10-12 15:26:37 +05:00
|
|
|
|
var data = await processMapReportWellDrillingService.GetAsync(idWell, cancellationToken);
|
2023-10-09 17:04:05 +05:00
|
|
|
|
|
|
|
|
|
FillProcessMapToWorkbook(workbook, data);
|
|
|
|
|
|
|
|
|
|
MemoryStream memoryStream = new();
|
|
|
|
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
|
|
|
|
|
var name = $"РТК бурение. Отчёт по скважине {well.Caption} куст {well.Cluster}.xlsx";
|
|
|
|
|
|
|
|
|
|
return (name, memoryStream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void FillProcessMapToWorkbook(XLWorkbook workbook,
|
2023-10-12 15:26:37 +05:00
|
|
|
|
IEnumerable<ProcessMapReportWellDrillingDto> data)
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
var sheet = workbook.Worksheets.FirstOrDefault();
|
|
|
|
|
if (sheet is null)
|
|
|
|
|
return;
|
|
|
|
|
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
|
|
|
|
FillSheet(sheet, dataBySections);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void FillSheet(IXLWorksheet sheet,
|
2023-10-12 15:26:37 +05:00
|
|
|
|
IEnumerable<IGrouping<int, ProcessMapReportWellDrillingDto>> dataBySections)
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
var startRow = headerRowsCount + 1;
|
|
|
|
|
foreach (var sectionData in dataBySections)
|
|
|
|
|
{
|
|
|
|
|
if (sectionData.Any())
|
|
|
|
|
startRow = FillSection(sheet, sectionData, startRow);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-12 15:26:37 +05:00
|
|
|
|
private static int FillSection(IXLWorksheet sheet, IGrouping<int, ProcessMapReportWellDrillingDto> sectionData,
|
2023-10-09 17:04:05 +05:00
|
|
|
|
int row)
|
|
|
|
|
{
|
|
|
|
|
var rowStart = row;
|
|
|
|
|
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
|
|
|
|
|
?? sectionData.Key.ToString();
|
|
|
|
|
|
|
|
|
|
sheet.Range(row, firstColumn, row, lastColumn)
|
|
|
|
|
.Merge()
|
|
|
|
|
.FirstCell()
|
|
|
|
|
.SetVal(sectionName)
|
|
|
|
|
.Style
|
|
|
|
|
.Fill.SetBackgroundColor(XLColor.LightGray);
|
|
|
|
|
row++;
|
|
|
|
|
foreach (var interval in sectionData)
|
|
|
|
|
row = FillIntervalData(sheet, interval, row);
|
|
|
|
|
|
|
|
|
|
var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastColumn).Style;
|
|
|
|
|
SetBorders(sectionStyle);
|
|
|
|
|
return row;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-12 15:26:37 +05:00
|
|
|
|
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportWellDrillingDto interval, int row)
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
const int columnDepth = firstColumn + 1;
|
|
|
|
|
const int columnDate = firstColumn + 2;
|
|
|
|
|
const int columnRopTime = firstColumn + 3;
|
|
|
|
|
const int columnMode = firstColumn + 4;
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, firstColumn)
|
|
|
|
|
.SetVal(interval.DepthStart, "0.0");
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnDepth)
|
|
|
|
|
.SetVal(interval.DepthEnd, "0.0");
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnDate)
|
|
|
|
|
.SetVal(interval.DateStart);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnRopTime)
|
|
|
|
|
.SetVal(interval.MechDrillingHours);
|
|
|
|
|
|
|
|
|
|
row = FillIntervalModeData(sheet, interval, columnMode, row);
|
|
|
|
|
|
|
|
|
|
return row;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-12 15:26:37 +05:00
|
|
|
|
private static int FillIntervalModeData(IXLWorksheet sheet, ProcessMapReportWellDrillingDto modeData,
|
2023-10-09 17:04:05 +05:00
|
|
|
|
int column, int row)
|
|
|
|
|
{
|
|
|
|
|
int columnDeltaDepth = column + 1;
|
|
|
|
|
int columnPressure = columnDeltaDepth + 1;
|
|
|
|
|
int columnLoad = columnPressure + 5;
|
|
|
|
|
int columnTorque = columnLoad + 5;
|
|
|
|
|
int columnSpeed = columnTorque + 5;
|
|
|
|
|
int columnUsagePlan = columnSpeed + 5;
|
|
|
|
|
int columnUsageFact = columnUsagePlan + 1;
|
|
|
|
|
int columnRop = columnUsageFact + 12;
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column)
|
|
|
|
|
.SetVal(modeData.DrillingMode);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnDeltaDepth)
|
|
|
|
|
.SetVal(modeData.DeltaDepth);
|
|
|
|
|
|
|
|
|
|
FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
|
|
|
|
|
FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
|
|
|
|
|
FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
|
|
|
|
|
FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnUsagePlan)
|
|
|
|
|
.SetVal(modeData.UsagePlan);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnUsageFact)
|
|
|
|
|
.SetVal(modeData.UsageFact);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, columnRop)
|
2023-11-09 15:01:29 +05:00
|
|
|
|
.SetVal(modeData.Rop.Fact);
|
2023-10-09 17:04:05 +05:00
|
|
|
|
|
|
|
|
|
return row + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void FillIntervalModeDataParam(IXLWorksheet sheet,
|
2023-10-12 15:26:37 +05:00
|
|
|
|
ProcessMapReportWellDrillingParamsDto dataParam, int column, int row)
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
const int columnOffsetSpPlan = 0;
|
|
|
|
|
const int columnOffsetSpFact = 1;
|
|
|
|
|
const int columnOffsetFact = 2;
|
|
|
|
|
const int columnOffsetLimit = 3;
|
|
|
|
|
const int columnOffsetPercent = 4;
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetSpPlan)
|
|
|
|
|
.SetVal(dataParam.SetpointPlan);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetSpFact)
|
|
|
|
|
.SetVal(dataParam.SetpointFact);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetFact)
|
|
|
|
|
.SetVal(dataParam.Fact);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetLimit)
|
|
|
|
|
.SetVal(dataParam.Limit);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetPercent)
|
|
|
|
|
.SetVal(dataParam.SetpointUsage, format: "0.0");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet,
|
2023-10-12 15:26:37 +05:00
|
|
|
|
ProcessMapReportWellDrillingParamsDto dataParam, int column, int row)
|
2023-10-09 17:04:05 +05:00
|
|
|
|
{
|
|
|
|
|
const int columnOffsetSpPlan = 0;
|
|
|
|
|
const int columnOffsetSpFact = 1;
|
|
|
|
|
const int columnOffsetFact = 2;
|
|
|
|
|
const int columnOffsetLimit = 3;
|
|
|
|
|
const int columnOffsetPercent = 4;
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetSpPlan)
|
|
|
|
|
.SetVal(dataParam.SetpointPlan);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetSpFact)
|
|
|
|
|
.SetVal(dataParam.SetpointFact);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetFact)
|
|
|
|
|
.SetVal(dataParam.Fact);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetLimit)
|
|
|
|
|
.SetVal(dataParam.Limit);
|
|
|
|
|
|
|
|
|
|
sheet.Cell(row, column + columnOffsetPercent)
|
|
|
|
|
.SetVal(dataParam.SetpointUsage, format: "0.0");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Stream GetExcelTemplateStream()
|
|
|
|
|
{
|
|
|
|
|
var stream = Assembly.GetExecutingAssembly()
|
|
|
|
|
.GetManifestResourceStream(
|
2023-10-17 10:20:27 +05:00
|
|
|
|
"AsbCloudInfrastructure.Services.ProcessMaps.Report.ProcessMapReportTemplate.xlsx");
|
|
|
|
|
|
2023-10-09 17:04:05 +05:00
|
|
|
|
return stream!;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SetBorders(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;
|
|
|
|
|
}
|
|
|
|
|
}
|