DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportMakerService.cs

209 lines
7.4 KiB
C#
Raw Normal View History

using AsbCloudApp.Data.ProcessMap;
using AsbCloudApp.Services;
using ClosedXML.Excel;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.ProcessMap
{
public class ProcessMapReportMakerService : IProcessMapReportMakerService
{
const int firstColumn = 2;
const int lastColumn = 49;
2023-04-06 16:20:21 +05:00
const int headerRowsCount = 5;
private readonly IProcessMapReportService processMapService;
public ProcessMapReportMakerService(IProcessMapReportService processMapService)
{
this.processMapService = processMapService;
}
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token)
{
var stream = GetExcelTemplateStream();
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
2023-04-06 10:25:51 +05:00
var data = await processMapService.GetProcessMapReportAsync(idWell, token);
FillProcessMapToWorkbook(workbook, data);
MemoryStream memoryStream = new MemoryStream();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> data)
{
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, IEnumerable<IGrouping<int, ProcessMapReportDto>> dataBySections)
{
var startRow = headerRowsCount + 1;
foreach (var sectionData in dataBySections)
{
if(sectionData.Any())
startRow = FillSection(sheet, sectionData, startRow);
}
}
private static int FillSection(IXLWorksheet sheet, IGrouping<int, ProcessMapReportDto> sectionData, 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;
}
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDto interval, int row)
{
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;
}
private static int FillIntervalModeData(IXLWorksheet sheet, ProcessMapReportDto modeData, 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)
.SetVal(modeData.Rop);
return row + 1;
}
private static void FillIntervalModeDataParam(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
{
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, ProcessMapReportParamsDto dataParam, int column, int row)
{
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 = System.Reflection.Assembly.GetExecutingAssembly()
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
return stream!;
}
private static IXLStyle 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 ;
return style;
}
}
}