forked from ddrilling/AsbCloudServer
Merge pull request '#28176443 Унификация работы с ClosedXml' (#216) from feature/closed_xml into dev
Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/216
This commit is contained in:
commit
c33b7d086a
@ -53,7 +53,7 @@
|
|||||||
<PackageReference Include="AsbSaubReportLas" Version="3.24.116.510" />
|
<PackageReference Include="AsbSaubReportLas" Version="3.24.116.510" />
|
||||||
<PackageReference Include="AsbSaubReportPdf" Version="3.24.116.510" />
|
<PackageReference Include="AsbSaubReportPdf" Version="3.24.116.510" />
|
||||||
<PackageReference Include="CliWrap" Version="3.6.6" />
|
<PackageReference Include="CliWrap" Version="3.6.6" />
|
||||||
<PackageReference Include="ClosedXML" Version="0.97.0" />
|
<PackageReference Include="ClosedXML" Version="0.102.2" />
|
||||||
<PackageReference Include="itext7" Version="8.0.2" />
|
<PackageReference Include="itext7" Version="8.0.2" />
|
||||||
<PackageReference Include="itext7.bouncy-castle-adapter" Version="8.0.2" />
|
<PackageReference Include="itext7.bouncy-castle-adapter" Version="8.0.2" />
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
@ -106,7 +106,7 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
.GetExecutingAssembly()
|
.GetExecutingAssembly()
|
||||||
.GetTemplateCopyStreamAsync("DailyReportTemplate.xlsx", cancellationToken);
|
.GetTemplateCopyStreamAsync("DailyReportTemplate.xlsx", cancellationToken);
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(excelTemplateStream);
|
||||||
|
|
||||||
AddDailyReportToWorkBook(workbook, dailyReport);
|
AddDailyReportToWorkBook(workbook, dailyReport);
|
||||||
|
|
||||||
@ -120,18 +120,17 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
{
|
{
|
||||||
const string sheetName = "Суточный отчёт";
|
const string sheetName = "Суточный отчёт";
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
var sheet = workbook.GetWorksheet(sheetName);;
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
|
||||||
|
|
||||||
sheet.Cell(cellCustomer).Value = dailyReport.Customer;
|
sheet.Cell(cellCustomer).SetCellValue(dailyReport.Customer);
|
||||||
sheet.Cell(cellContractor).Value = dailyReport.Contractor;
|
sheet.Cell(cellContractor).SetCellValue(dailyReport.Contractor);
|
||||||
sheet.Cell(cellDeposit).Value = dailyReport.Deposit;
|
sheet.Cell(cellDeposit).SetCellValue(dailyReport.Deposit);
|
||||||
sheet.Cell(cellCluster).Value = dailyReport.Cluster;
|
sheet.Cell(cellCluster).SetCellValue(dailyReport.Cluster);
|
||||||
sheet.Cell(cellWellCaption).Value = dailyReport.WellCaption;
|
sheet.Cell(cellWellCaption).SetCellValue(dailyReport.WellCaption);
|
||||||
sheet.Cell(cellWellType).Value = dailyReport.WellType;
|
sheet.Cell(cellWellType).SetCellValue(dailyReport.WellType);
|
||||||
sheet.Cell(cellDate).Value = dailyReport.Date;
|
sheet.Cell(cellDate).SetCellValue(dailyReport.Date);
|
||||||
sheet.Cell(cellDepthStart).Value = dailyReport.DepthStart;
|
sheet.Cell(cellDepthStart).SetCellValue(dailyReport.DepthStart);
|
||||||
sheet.Cell(cellDepthEnd).Value = dailyReport.DepthEnd;
|
sheet.Cell(cellDepthEnd).SetCellValue(dailyReport.DepthEnd);
|
||||||
|
|
||||||
if (dailyReport.TimeBalanceBlock is not null)
|
if (dailyReport.TimeBalanceBlock is not null)
|
||||||
AddTimeBalanceBlockToSheet(sheet, dailyReport.TimeBalanceBlock);
|
AddTimeBalanceBlockToSheet(sheet, dailyReport.TimeBalanceBlock);
|
||||||
@ -150,10 +149,10 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
|
|
||||||
private static void AddTrajectoryBlockToSheet(IXLWorksheet sheet, TrajectoryBlockDto trajectoryBlock)
|
private static void AddTrajectoryBlockToSheet(IXLWorksheet sheet, TrajectoryBlockDto trajectoryBlock)
|
||||||
{
|
{
|
||||||
sheet.Cell(cellTrajectoryBlockWellboreDepth).Value = trajectoryBlock.WellboreDepth;
|
sheet.Cell(cellTrajectoryBlockWellboreDepth).SetCellValue(trajectoryBlock.WellboreDepth);
|
||||||
sheet.Cell(cellTrajectoryBlockVerticalDepth).Value = trajectoryBlock.VerticalDepth;
|
sheet.Cell(cellTrajectoryBlockVerticalDepth).SetCellValue(trajectoryBlock.VerticalDepth);
|
||||||
sheet.Cell(cellTrajectoryBlockZenithAngle).Value = trajectoryBlock.ZenithAngle;
|
sheet.Cell(cellTrajectoryBlockZenithAngle).SetCellValue(trajectoryBlock.ZenithAngle);
|
||||||
sheet.Cell(cellTrajectoryBlockAzimuthGeo).Value = trajectoryBlock.AzimuthGeo;
|
sheet.Cell(cellTrajectoryBlockAzimuthGeo).SetCellValue(trajectoryBlock.AzimuthGeo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddTimeBalanceBlockToSheet(IXLWorksheet sheet, TimeBalanceBlockDto timeBalanceBlock)
|
private static void AddTimeBalanceBlockToSheet(IXLWorksheet sheet, TimeBalanceBlockDto timeBalanceBlock)
|
||||||
@ -162,19 +161,19 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
|
|
||||||
foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation))
|
foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation))
|
||||||
{
|
{
|
||||||
sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours.Plan;
|
sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).SetCellValue(wellOperation.DurationHours.Plan);
|
||||||
sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours.Fact;
|
sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).SetCellValue(wellOperation.DurationHours.Fact);
|
||||||
sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).Value = wellOperation.ReasonDeviation;
|
sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).SetCellValue(wellOperation.ReasonDeviation);
|
||||||
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).Value = wellOperation.DrillingDeviationPerSection;
|
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).SetCellValue(wellOperation.DrillingDeviationPerSection);
|
||||||
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDay).Value = wellOperation.DrillingDeviationPerDay;
|
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDay).SetCellValue(wellOperation.DrillingDeviationPerDay);
|
||||||
|
|
||||||
rowCurrent++;
|
rowCurrent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName;
|
sheet.Cell(cellTimeBalanceBlockSection).SetCellValue(timeBalanceBlock.SectionName);
|
||||||
sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepth.Plan;
|
sheet.Cell(cellTimeBalanceBlockWellDepthPlan).SetCellValue(timeBalanceBlock.WellDepth.Plan);
|
||||||
sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepth.Fact;
|
sheet.Cell(cellTimeBalanceBlockWellDepthFact).SetCellValue(timeBalanceBlock.WellDepth.Fact);
|
||||||
sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).Value = timeBalanceBlock.WellOperationSlipsTimeCount;
|
sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).SetCellValue(timeBalanceBlock.WellOperationSlipsTimeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock)
|
private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock)
|
||||||
@ -183,24 +182,23 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
|
|
||||||
foreach (var subsystem in subsystemBlock.Subsystems)
|
foreach (var subsystem in subsystemBlock.Subsystems)
|
||||||
{
|
{
|
||||||
sheet.Cell(rowСurrent, columnSubsystemName).Value = subsystem.Name;
|
sheet.Cell(rowСurrent, columnSubsystemName).SetCellValue(subsystem.Name);
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).SetCellValue(subsystem.UsagePerDay?.UsedTimeHours);
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).SetCellValue(subsystem.UsagePerDay?.SumDepthInterval);
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).SetCellValue(subsystem.UsagePerDay?.KUsage);
|
||||||
|
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).Value = subsystem.UsagePerDay?.UsedTimeHours;
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).SetCellValue(subsystem.UsagePerWell?.UsedTimeHours);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).Value = subsystem.UsagePerDay?.SumDepthInterval;
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).SetCellValue(subsystem.UsagePerWell?.SumDepthInterval);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).Value = subsystem.UsagePerDay?.KUsage;
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).SetCellValue(subsystem.UsagePerWell?.KUsage);
|
||||||
|
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).Value = subsystem.UsagePerWell?.UsedTimeHours;
|
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).Value = subsystem.UsagePerWell?.SumDepthInterval;
|
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).Value = subsystem.UsagePerWell?.KUsage;
|
|
||||||
|
|
||||||
rowСurrent++;
|
rowСurrent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sheet.Cell(cellSubsystemComment).Value = subsystemBlock.Comment;
|
sheet.Cell(cellSubsystemComment).SetCellValue(subsystemBlock.Comment);
|
||||||
sheet.Cell(cellSubsystemTvgLagDays).Value = subsystemBlock.TvgLagDays;
|
sheet.Cell(cellSubsystemTvgLagDays).SetCellValue(subsystemBlock.TvgLagDays);
|
||||||
sheet.Cell(cellSubsystemMeasurementsPerDay).Value = subsystemBlock.MeasurementsPerDay;
|
sheet.Cell(cellSubsystemMeasurementsPerDay).SetCellValue(subsystemBlock.MeasurementsPerDay);
|
||||||
sheet.Cell(cellSubsystemWellbore).Value = subsystemBlock.Wellbore;
|
sheet.Cell(cellSubsystemWellbore).SetCellValue(subsystemBlock.Wellbore);
|
||||||
sheet.Cell(cellSubsystemTotalRopPlan).Value = subsystemBlock.TotalRopPlan;
|
sheet.Cell(cellSubsystemTotalRopPlan).SetCellValue(subsystemBlock.TotalRopPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddScheduleBlockToSheet(IXLWorksheet sheet, IEnumerable<ScheduleRecordDto> scheduleBlock)
|
private static void AddScheduleBlockToSheet(IXLWorksheet sheet, IEnumerable<ScheduleRecordDto> scheduleBlock)
|
||||||
@ -209,9 +207,9 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
|
|
||||||
foreach (var schedule in scheduleBlock.OrderBy(s => s.ShiftStart))
|
foreach (var schedule in scheduleBlock.OrderBy(s => s.ShiftStart))
|
||||||
{
|
{
|
||||||
sheet.Cell(rowCurrent, columnSheduleDriller).Value = $"{schedule.Surname} {schedule.Name} {schedule.Patronymic}";
|
sheet.Cell(rowCurrent, columnSheduleDriller).SetCellValue($"{schedule.Surname} {schedule.Name} {schedule.Patronymic}");
|
||||||
sheet.Cell(rowCurrent, columnSheduleShiftStart).Value = schedule.ShiftStart;
|
sheet.Cell(rowCurrent, columnSheduleShiftStart).SetCellValue(schedule.ShiftStart);
|
||||||
sheet.Cell(rowCurrent, columnSheduleShiftEnd).Value = schedule.ShiftEnd;
|
sheet.Cell(rowCurrent, columnSheduleShiftEnd).SetCellValue(schedule.ShiftEnd);
|
||||||
|
|
||||||
rowCurrent++;
|
rowCurrent++;
|
||||||
}
|
}
|
||||||
@ -224,11 +222,11 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
|
|
||||||
foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.DrillingMode))
|
foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.DrillingMode))
|
||||||
{
|
{
|
||||||
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockDrillingMode).Value = processMapWellDrilling.DrillingMode;
|
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockDrillingMode).SetCellValue(processMapWellDrilling.DrillingMode);
|
||||||
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockWellBoreDepth).Value = processMapWellDrilling.WellBoreDepth;
|
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockWellBoreDepth).SetCellValue(processMapWellDrilling.WellBoreDepth);
|
||||||
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMechDrillingHours).Value = processMapWellDrilling.MechDrillingHours;
|
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMechDrillingHours).SetCellValue(processMapWellDrilling.MechDrillingHours);
|
||||||
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopPlan).Value = processMapWellDrilling.Rop.Plan;
|
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopPlan).SetCellValue(processMapWellDrilling.Rop.Plan);
|
||||||
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopFact).Value = processMapWellDrilling.Rop.Fact;
|
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopFact).SetCellValue(processMapWellDrilling.Rop.Fact);
|
||||||
|
|
||||||
rowCurrent++;
|
rowCurrent++;
|
||||||
}
|
}
|
||||||
@ -238,12 +236,12 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
{
|
{
|
||||||
var rowCurrent = rowStartFactWellOperationBlock;
|
var rowCurrent = rowStartFactWellOperationBlock;
|
||||||
|
|
||||||
sheet.Cell(cellSectionDrillingHours).Value = factWellOperationBlock.SectionDrillingHours;
|
sheet.Cell(cellSectionDrillingHours).SetCellValue(factWellOperationBlock.SectionDrillingHours);
|
||||||
|
|
||||||
foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName))
|
foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName))
|
||||||
{
|
{
|
||||||
sheet.Cell(rowCurrent, columnWellOperationCategory).Value = factOperation.CategoryName;
|
sheet.Cell(rowCurrent, columnWellOperationCategory).SetCellValue(factOperation.CategoryName);
|
||||||
sheet.Cell(rowCurrent, columnWellOperationDurationHours).Value = factOperation.DurationHours;
|
sheet.Cell(rowCurrent, columnWellOperationDurationHours).SetCellValue(factOperation.DurationHours);
|
||||||
|
|
||||||
rowCurrent++;
|
rowCurrent++;
|
||||||
}
|
}
|
||||||
@ -251,7 +249,7 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
|
|
||||||
private static void AddSignBlockToSheet(IXLWorksheet sheet, SignBlockDto signBlock)
|
private static void AddSignBlockToSheet(IXLWorksheet sheet, SignBlockDto signBlock)
|
||||||
{
|
{
|
||||||
sheet.Cell(cellSignDrillingMaster).Value = signBlock.DrillingMaster?.ToString();
|
sheet.Cell(cellSignDrillingMaster).SetCellValue(signBlock.DrillingMaster?.ToString());
|
||||||
sheet.Cell(cellSignSupervisor).Value = signBlock.Supervisor?.ToString();
|
sheet.Cell(cellSignSupervisor).SetCellValue(signBlock.Supervisor?.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -42,8 +42,9 @@ public class DetectedOperationExportService
|
|||||||
private const int columnIdReasonOfEnd = 9;
|
private const int columnIdReasonOfEnd = 9;
|
||||||
private const int columnComment = 10;
|
private const int columnComment = 10;
|
||||||
|
|
||||||
|
//TODO: удалить неиспользуемую зависимость
|
||||||
private readonly IAsbCloudDbContext dbContext;
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
|
|
||||||
public DetectedOperationExportService(IAsbCloudDbContext dbContext, IWellOperationRepository wellOperationRepository)
|
public DetectedOperationExportService(IAsbCloudDbContext dbContext, IWellOperationRepository wellOperationRepository)
|
||||||
{
|
{
|
||||||
@ -82,7 +83,7 @@ public class DetectedOperationExportService
|
|||||||
{
|
{
|
||||||
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(excelTemplateStream);
|
||||||
|
|
||||||
await AddToWorkbookAsync(workbook, well, host, operationDetectorResults, cancellationToken);
|
await AddToWorkbookAsync(workbook, well, host, operationDetectorResults, cancellationToken);
|
||||||
|
|
||||||
@ -100,8 +101,7 @@ public class DetectedOperationExportService
|
|||||||
if (!operationDetectorResults.Any())
|
if (!operationDetectorResults.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
|
||||||
|
|
||||||
await AddToSheetAsync(sheet, well, host, operationDetectorResults
|
await AddToSheetAsync(sheet, well, host, operationDetectorResults
|
||||||
.OrderBy(x => x.Operation.DateStart).ThenBy(x => x.Operation.DepthStart).ToArray(),
|
.OrderBy(x => x.Operation.DateStart).ThenBy(x => x.Operation.DepthStart).ToArray(),
|
||||||
@ -113,10 +113,10 @@ public class DetectedOperationExportService
|
|||||||
{
|
{
|
||||||
var wellOperationCategories = await dbContext.WellOperationCategories.ToListAsync(cancellationToken);
|
var wellOperationCategories = await dbContext.WellOperationCategories.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
sheet.Cell(cellDepositName).Value = well.Cluster.Deposit.Caption;
|
sheet.Cell(cellDepositName).SetCellValue(well.Cluster.Deposit.Caption);
|
||||||
sheet.Cell(cellClusterName).Value = well.Cluster.Caption;
|
sheet.Cell(cellClusterName).SetCellValue(well.Cluster.Caption);
|
||||||
sheet.Cell(cellWellName).Value = well.Caption;
|
sheet.Cell(cellWellName).SetCellValue(well.Caption);
|
||||||
sheet.Cell(cellDeltaDate).Value = operationDetectorResults.Max(o => o.Operation.DateEnd) - operationDetectorResults.Min(o => o.Operation.DateStart);
|
sheet.Cell(cellDeltaDate).SetCellValue(operationDetectorResults.Max(o => o.Operation.DateEnd) - operationDetectorResults.Min(o => o.Operation.DateStart));
|
||||||
|
|
||||||
var detectedOperations = operationDetectorResults.Select(o => o.Operation).ToArray();
|
var detectedOperations = operationDetectorResults.Select(o => o.Operation).ToArray();
|
||||||
|
|
||||||
@ -128,31 +128,38 @@ public class DetectedOperationExportService
|
|||||||
|
|
||||||
var row = sheet.Row(5 + i + headerRowsCount);
|
var row = sheet.Row(5 + i + headerRowsCount);
|
||||||
|
|
||||||
row.Cell(columnOperationName).Value = GetCategoryName(wellOperationCategories, current);
|
var categoryName = GetCategoryName(wellOperationCategories, current);
|
||||||
row.Cell(columnDateEnd).Value = dateEnd;
|
|
||||||
row.Cell(columnDuration).Value = (dateEnd - dateStart).TotalMinutes;
|
row.Cell(columnOperationName).SetCellValue(categoryName);
|
||||||
row.Cell(columnDepthStart).Value = current.DepthStart;
|
row.Cell(columnDateEnd).SetCellValue(dateEnd);
|
||||||
row.Cell(columnDepthEnd).Value = current.DepthEnd;
|
row.Cell(columnDuration).SetCellValue((dateEnd - dateStart).TotalMinutes);
|
||||||
row.Cell(columnDepth).Value = current.DepthEnd - current.DepthStart;
|
row.Cell(columnDepthStart).SetCellValue(current.DepthStart);
|
||||||
|
row.Cell(columnDepthEnd).SetCellValue(current.DepthEnd);
|
||||||
|
row.Cell(columnDepth).SetCellValue(current.DepthEnd - current.DepthStart);
|
||||||
|
|
||||||
if (current.ExtraData.TryGetValue("IdReasonOfEnd", out object? idReasonOfEndObject)
|
if (current.ExtraData.TryGetValue("IdReasonOfEnd", out object? idReasonOfEndObject)
|
||||||
&& idReasonOfEndObject is int idReasonOfEnd)
|
&& idReasonOfEndObject is int idReasonOfEnd)
|
||||||
row.Cell(columnIdReasonOfEnd).Value = GetIdReasonOfEnd(idReasonOfEnd);
|
{
|
||||||
|
var reasonOfEnd = GetIdReasonOfEnd(idReasonOfEnd);
|
||||||
|
row.Cell(columnIdReasonOfEnd).SetCellValue(reasonOfEnd);
|
||||||
|
}
|
||||||
|
|
||||||
var query = new QueryBuilder();
|
var query = new QueryBuilder();
|
||||||
query.Add("end", dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"));
|
query.Add("end", dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"));
|
||||||
query.Add("range", "1800");
|
query.Add("range", "1800");
|
||||||
|
|
||||||
|
row.Cell(columnDateStart).SetCellValue(dateStart);
|
||||||
|
|
||||||
var link = $"{host}/well/{well.Id}/telemetry/monitoring{query}";
|
var link = $"{host}/well/{well.Id}/telemetry/monitoring{query}";
|
||||||
|
row.Cell(columnDateStart).SetHyperlink(link);
|
||||||
row.Cell(columnDateStart).Value = dateStart;
|
|
||||||
row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
|
var deltaDepth = i > 0 && i + 1 < detectedOperations.Length
|
||||||
|
|
||||||
row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Length
|
|
||||||
? current.DepthStart - detectedOperations[i - 1].DepthEnd
|
? current.DepthStart - detectedOperations[i - 1].DepthEnd
|
||||||
: 0;
|
: 0;
|
||||||
|
row.Cell(columnDeltaDepth).SetCellValue(deltaDepth);
|
||||||
|
|
||||||
row.Cell(columnComment).Value = CreateComment(operationDetectorResults[i]);
|
var comment = CreateComment(operationDetectorResults[i]);
|
||||||
|
row.Cell(columnComment).SetCellValue(comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using AsbCloudApp.Data.DrillTestReport;
|
using AsbCloudApp.Data.DrillTestReport;
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using ClosedXML.Excel;
|
using ClosedXML.Excel;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -7,6 +6,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DrillTestReport
|
namespace AsbCloudInfrastructure.Services.DrillTestReport
|
||||||
{
|
{
|
||||||
@ -20,7 +20,7 @@ namespace AsbCloudInfrastructure.Services.DrillTestReport
|
|||||||
{
|
{
|
||||||
using var excelTemplateStream = await Assembly.GetExecutingAssembly().GetTemplateCopyStreamAsync(templateName, cancellationToken);
|
using var excelTemplateStream = await Assembly.GetExecutingAssembly().GetTemplateCopyStreamAsync(templateName, cancellationToken);
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(excelTemplateStream);
|
||||||
|
|
||||||
AddToWorkbook(workbook, report);
|
AddToWorkbook(workbook, report);
|
||||||
|
|
||||||
@ -30,50 +30,39 @@ namespace AsbCloudInfrastructure.Services.DrillTestReport
|
|||||||
|
|
||||||
return memoryStream;
|
return memoryStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void AddToWorkbook(XLWorkbook workbook, DrillTestReportDataDto report)
|
private void AddToWorkbook(XLWorkbook workbook, DrillTestReportDataDto report)
|
||||||
{
|
{
|
||||||
var drillTestEntities = report.Data.Params;
|
var drillTests = report.Data.Params;
|
||||||
if (!drillTestEntities.Any())
|
|
||||||
|
if (!drillTests.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
|
||||||
|
|
||||||
sheet.Cell(4, 2).Value = report.Caption;
|
sheet.Cell(4, 2).SetCellValue(report.Caption);
|
||||||
sheet.Cell(5, 2)._SetValue(report.Date, setAllBorders: false);
|
sheet.Cell(5, 2).SetCellValue(report.Date);
|
||||||
|
|
||||||
var rowNumber = startRowNumber;
|
var stepWithMaxDepthSpeed = drillTests.MaxBy(p => p.DepthSpeed)!.Step;
|
||||||
|
|
||||||
var stepWithMaxDepthSpeed = drillTestEntities.OrderByDescending(p => p.DepthSpeed).FirstOrDefault()!.Step;
|
|
||||||
var startDepth = report.Data.DepthStart;
|
var startDepth = report.Data.DepthStart;
|
||||||
var startDate = report.Data.TimeStampStart;
|
var startDate = report.Data.TimeStampStart;
|
||||||
|
|
||||||
foreach (var drillTestEntity in drillTestEntities)
|
var rowNumber = startRowNumber;
|
||||||
|
|
||||||
|
foreach (var drillTestEntity in drillTests)
|
||||||
{
|
{
|
||||||
var endDepth = startDepth + (drillTestEntity.DepthDrillStep ?? 0);
|
var endDepth = startDepth + (drillTestEntity.DepthDrillStep ?? 0);
|
||||||
var endDateTime = startDate.AddSeconds(drillTestEntity.TimeDrillStep ?? 0);
|
var endDateTime = startDate.AddSeconds(drillTestEntity.TimeDrillStep ?? 0);
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 2).Value = startDepth;
|
sheet.Cell(rowNumber, 2).SetCellValue(startDepth);
|
||||||
|
sheet.Cell(rowNumber, 3).SetCellValue(endDepth);
|
||||||
sheet.Cell(rowNumber, 3).Value = endDepth;
|
sheet.Cell(rowNumber, 4).SetCellValue(drillTestEntity.DepthDrillStep);
|
||||||
|
sheet.Cell(rowNumber, 5).SetCellValue(drillTestEntity.Workload);
|
||||||
sheet.Cell(rowNumber, 4).Value = drillTestEntity.DepthDrillStep;
|
sheet.Cell(rowNumber, 6).SetCellValue(drillTestEntity.Speed);
|
||||||
|
sheet.Cell(rowNumber, 7).SetCellValue(startDate.DateTime);
|
||||||
sheet.Cell(rowNumber, 5).Value = drillTestEntity.Workload;
|
sheet.Cell(rowNumber, 8).SetCellValue(endDateTime.DateTime);
|
||||||
|
sheet.Cell(rowNumber, 9).SetCellValue(Math.Round((drillTestEntity.TimeDrillStep ?? 0) / (60 * 60), 2));
|
||||||
sheet.Cell(rowNumber, 6).Value = drillTestEntity.Speed;
|
sheet.Cell(rowNumber, 10).SetCellValue(drillTestEntity.DepthSpeed);
|
||||||
|
|
||||||
var cell = sheet.Cell(rowNumber, 7);
|
|
||||||
cell._SetValue(startDate.DateTime);
|
|
||||||
|
|
||||||
cell = sheet.Cell(rowNumber, 8);
|
|
||||||
cell._SetValue(endDateTime.DateTime);
|
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 9).Value = Math.Round((drillTestEntity.TimeDrillStep ?? 0) / (60 * 60), 2);
|
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 10).Value = drillTestEntity.DepthSpeed;
|
|
||||||
|
|
||||||
if (drillTestEntity.Step == stepWithMaxDepthSpeed)
|
if (drillTestEntity.Step == stepWithMaxDepthSpeed)
|
||||||
{
|
{
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
using ClosedXML.Excel;
|
|
||||||
using ClosedXML.Excel.Drawings;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DrillingProgram
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class DrillingProgramMaker
|
|
||||||
{
|
|
||||||
private const int maxAllowedColumns = 256;
|
|
||||||
|
|
||||||
public static void UniteExcelFiles(IEnumerable<string> excelFilesNames, string resultExcelPath, IEnumerable<AsbCloudApp.Data.DrillingProgramPartDto> 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();
|
|
||||||
|
|
||||||
foreach (var excelFileName in filteredFileNames)
|
|
||||||
{
|
|
||||||
using var workbookSrc = new XLWorkbook(excelFileName, XLEventTracking.Disabled);
|
|
||||||
|
|
||||||
foreach (var sheet in workbookSrc.Worksheets)
|
|
||||||
{
|
|
||||||
if (sheet.Visibility == XLWorksheetVisibility.Visible)
|
|
||||||
CopySheet(resultExcelFile, sheet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resultExcelFile.SaveAs(resultExcelPath,
|
|
||||||
new SaveOptions { EvaluateFormulasBeforeSaving = true });
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CopySheet(XLWorkbook workbookDst, IXLWorksheet sheetSrc)
|
|
||||||
{
|
|
||||||
var newSheetName = sheetSrc.Name;
|
|
||||||
var suffix = "";
|
|
||||||
int index = 1;
|
|
||||||
|
|
||||||
while (workbookDst.Worksheets.Contains(newSheetName))
|
|
||||||
{
|
|
||||||
newSheetName = sheetSrc.Name;
|
|
||||||
suffix = $"_{index++}";
|
|
||||||
if (newSheetName.Length + suffix.Length >= 31)
|
|
||||||
newSheetName = newSheetName[..(31 - suffix.Length)];
|
|
||||||
newSheetName += suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
var imagesInfos = sheetSrc.Pictures.Select(p => new ImageInfo
|
|
||||||
{
|
|
||||||
Id = p.Id,
|
|
||||||
Data = p.ImageStream.GetBuffer(),
|
|
||||||
Height = p.Height,
|
|
||||||
Width = p.Width,
|
|
||||||
TopLeftCellAddress = p.TopLeftCell.Address,
|
|
||||||
Left = p.Left,
|
|
||||||
Top = p.Top
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
IXLWorksheet resultSheet;
|
|
||||||
|
|
||||||
if (sheetSrc.Columns().Count() > maxAllowedColumns)
|
|
||||||
{
|
|
||||||
resultSheet = workbookDst.Worksheets.Add(newSheetName);
|
|
||||||
|
|
||||||
var rngData = GetCellsRange(sheetSrc);
|
|
||||||
|
|
||||||
rngData.CopyTo(resultSheet.Cell(1, 1));
|
|
||||||
|
|
||||||
var lastRowWithData = rngData.LastRowUsed().RangeAddress
|
|
||||||
.LastAddress.RowNumber;
|
|
||||||
|
|
||||||
for (int i = 1; i < lastRowWithData; i++)
|
|
||||||
{
|
|
||||||
resultSheet.Row(i).Height = sheetSrc.Row(i).Height;
|
|
||||||
resultSheet.Column(i).Width = sheetSrc.Column(i).Width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RemovePicturesFromSheet(sheetSrc);
|
|
||||||
resultSheet = sheetSrc.CopyTo(workbookDst, newSheetName);
|
|
||||||
}
|
|
||||||
CopyImagesToAnotherSheet(imagesInfos, resultSheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IXLWorksheet CopyImagesToAnotherSheet(IEnumerable<ImageInfo> imagesInfos,
|
|
||||||
IXLWorksheet resultSheet)
|
|
||||||
{
|
|
||||||
foreach (var image in imagesInfos)
|
|
||||||
{
|
|
||||||
var stream = new MemoryStream();
|
|
||||||
stream.Write(image.Data, 0, image.Data.Length);
|
|
||||||
|
|
||||||
resultSheet.AddPicture(stream)
|
|
||||||
.WithPlacement(XLPicturePlacement.Move)
|
|
||||||
.WithSize(image.Width, image.Height)
|
|
||||||
.MoveTo(resultSheet.Cell(image.TopLeftCellAddress),
|
|
||||||
image.Left, image.Top);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultSheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RemovePicturesFromSheet(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
var filteredPics = sheet.Pictures.Select(p => p.Name).Distinct().ToList();
|
|
||||||
|
|
||||||
foreach (var n in filteredPics)
|
|
||||||
sheet.Pictures.Delete(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IXLRange GetCellsRange(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
var firstTableCell = sheet.FirstCellUsed();
|
|
||||||
var lastTableCell = sheet.LastCellUsed();
|
|
||||||
var rngData = sheet.Range(firstTableCell.Address, lastTableCell.Address);
|
|
||||||
|
|
||||||
return rngData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Binary file not shown.
@ -37,7 +37,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var stream = GetExcelTemplateStream();
|
var stream = GetExcelTemplateStream();
|
||||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(stream);
|
||||||
|
|
||||||
var data = await processMapReportWellDrillingService.GetAsync(idWell, cancellationToken);
|
var data = await processMapReportWellDrillingService.GetAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
@ -55,9 +55,10 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook,
|
private static void FillProcessMapToWorkbook(XLWorkbook workbook,
|
||||||
IEnumerable<ProcessMapReportWellDrillingDto> data)
|
IEnumerable<ProcessMapReportWellDrillingDto> data)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
const string sheetName = "Отчёт";
|
||||||
if (sheet is null)
|
|
||||||
return;
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
|
|
||||||
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
||||||
FillSheet(sheet, dataBySections);
|
FillSheet(sheet, dataBySections);
|
||||||
}
|
}
|
||||||
@ -83,7 +84,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
sheet.Range(row, firstColumn, row, lastColumn)
|
sheet.Range(row, firstColumn, row, lastColumn)
|
||||||
.Merge()
|
.Merge()
|
||||||
.FirstCell()
|
.FirstCell()
|
||||||
.SetVal(sectionName)
|
.SetCellValue(sectionName)
|
||||||
.Style
|
.Style
|
||||||
.Fill.SetBackgroundColor(XLColor.LightGray);
|
.Fill.SetBackgroundColor(XLColor.LightGray);
|
||||||
row++;
|
row++;
|
||||||
@ -102,17 +103,10 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
const int columnRopTime = firstColumn + 3;
|
const int columnRopTime = firstColumn + 3;
|
||||||
const int columnMode = firstColumn + 4;
|
const int columnMode = firstColumn + 4;
|
||||||
|
|
||||||
sheet.Cell(row, firstColumn)
|
sheet.Cell(row, firstColumn).SetCellValue(interval.DepthStart);
|
||||||
.SetVal(interval.DepthStart, "0.0");
|
sheet.Cell(row, columnDepth).SetCellValue(interval.DepthEnd);
|
||||||
|
sheet.Cell(row, columnDate).SetCellValue(interval.DateStart);
|
||||||
sheet.Cell(row, columnDepth)
|
sheet.Cell(row, columnRopTime).SetCellValue(interval.MechDrillingHours);
|
||||||
.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);
|
row = FillIntervalModeData(sheet, interval, columnMode, row);
|
||||||
|
|
||||||
@ -131,25 +125,18 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
int columnUsageFact = columnUsagePlan + 1;
|
int columnUsageFact = columnUsagePlan + 1;
|
||||||
int columnRop = columnUsageFact + 12;
|
int columnRop = columnUsageFact + 12;
|
||||||
|
|
||||||
sheet.Cell(row, column)
|
sheet.Cell(row, column).SetCellValue(modeData.DrillingMode);
|
||||||
.SetVal(modeData.DrillingMode);
|
|
||||||
|
|
||||||
sheet.Cell(row, columnDeltaDepth)
|
|
||||||
.SetVal(modeData.DeltaDepth);
|
|
||||||
|
|
||||||
|
sheet.Cell(row, columnDeltaDepth).SetCellValue(modeData.DeltaDepth);
|
||||||
|
|
||||||
FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
|
FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
|
||||||
FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
|
FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
|
||||||
FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
|
FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
|
||||||
FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
|
FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
|
||||||
|
|
||||||
sheet.Cell(row, columnUsagePlan)
|
sheet.Cell(row, columnUsagePlan).SetCellValue(modeData.UsagePlan);
|
||||||
.SetVal(modeData.UsagePlan);
|
sheet.Cell(row, columnUsageFact).SetCellValue(modeData.UsageFact);
|
||||||
|
sheet.Cell(row, columnRop).SetCellValue(modeData.Rop.Fact);
|
||||||
sheet.Cell(row, columnUsageFact)
|
|
||||||
.SetVal(modeData.UsageFact);
|
|
||||||
|
|
||||||
sheet.Cell(row, columnRop)
|
|
||||||
.SetVal(modeData.Rop.Fact);
|
|
||||||
|
|
||||||
return row + 1;
|
return row + 1;
|
||||||
}
|
}
|
||||||
@ -163,20 +150,11 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
const int columnOffsetLimit = 3;
|
const int columnOffsetLimit = 3;
|
||||||
const int columnOffsetPercent = 4;
|
const int columnOffsetPercent = 4;
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetSpPlan)
|
sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(dataParam.SetpointPlan);
|
||||||
.SetVal(dataParam.SetpointPlan);
|
sheet.Cell(row, column + columnOffsetSpFact).SetCellValue(dataParam.SetpointFact);
|
||||||
|
sheet.Cell(row, column + columnOffsetFact).SetCellValue(dataParam.Fact);
|
||||||
sheet.Cell(row, column + columnOffsetSpFact)
|
sheet.Cell(row, column + columnOffsetLimit).SetCellValue(dataParam.Limit);
|
||||||
.SetVal(dataParam.SetpointFact);
|
sheet.Cell(row, column + columnOffsetPercent).SetCellValue(dataParam.SetpointUsage);
|
||||||
|
|
||||||
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,
|
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet,
|
||||||
@ -188,22 +166,14 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
const int columnOffsetLimit = 3;
|
const int columnOffsetLimit = 3;
|
||||||
const int columnOffsetPercent = 4;
|
const int columnOffsetPercent = 4;
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetSpPlan)
|
sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(dataParam.SetpointPlan);
|
||||||
.SetVal(dataParam.SetpointPlan);
|
sheet.Cell(row, column + columnOffsetSpFact).SetCellValue(dataParam.SetpointFact);
|
||||||
|
sheet.Cell(row, column + columnOffsetFact).SetCellValue(dataParam.Fact);
|
||||||
sheet.Cell(row, column + columnOffsetSpFact)
|
sheet.Cell(row, column + columnOffsetLimit).SetCellValue(dataParam.Limit);
|
||||||
.SetVal(dataParam.SetpointFact);
|
sheet.Cell(row, column + columnOffsetPercent).SetCellValue(dataParam.SetpointUsage);
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: использовать метод расширения, избавиться от этого метода
|
||||||
private static Stream GetExcelTemplateStream()
|
private static Stream GetExcelTemplateStream()
|
||||||
{
|
{
|
||||||
var stream = Assembly.GetExecutingAssembly()
|
var stream = Assembly.GetExecutingAssembly()
|
||||||
@ -213,6 +183,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
return stream!;
|
return stream!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: нужен ли этот метод? Это можно настроить в шаблоне
|
||||||
private static void SetBorders(IXLStyle style)
|
private static void SetBorders(IXLStyle style)
|
||||||
{
|
{
|
||||||
style.Border.RightBorder = XLBorderStyleValues.Thin;
|
style.Border.RightBorder = XLBorderStyleValues.Thin;
|
||||||
|
@ -28,7 +28,7 @@ public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportServ
|
|||||||
|
|
||||||
private const int headerRowsCount = 2;
|
private const int headerRowsCount = 2;
|
||||||
|
|
||||||
private const int columnWellSectionType = 1;
|
private const int columnSection = 1;
|
||||||
private const int columnMode = 2;
|
private const int columnMode = 2;
|
||||||
private const int columnDepthStart = 3;
|
private const int columnDepthStart = 3;
|
||||||
private const int columnDepthEnd = 4;
|
private const int columnDepthEnd = 4;
|
||||||
@ -116,9 +116,8 @@ public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportServ
|
|||||||
|
|
||||||
private void AddToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings)
|
private void AddToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
var sheet = workbook.GetWorksheet(sheetNamePlan);
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlan}.");
|
|
||||||
|
|
||||||
AddToSheet(sheet, processMapPlanWellDrillings.ToArray());
|
AddToSheet(sheet, processMapPlanWellDrillings.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,31 +135,32 @@ public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportServ
|
|||||||
|
|
||||||
private void AddToRow(IXLRow row, ProcessMapPlanWellDrillingDto processMapPlanWellDrillings)
|
private void AddToRow(IXLRow row, ProcessMapPlanWellDrillingDto processMapPlanWellDrillings)
|
||||||
{
|
{
|
||||||
row.Cell(columnWellSectionType).Value = sections.First(x => x.Id == processMapPlanWellDrillings.IdWellSectionType).Caption;
|
var section = sections.First(x => x.Id == processMapPlanWellDrillings.IdWellSectionType).Caption;
|
||||||
row.Cell(columnMode).Value = GetModeCaption(processMapPlanWellDrillings.IdMode);
|
var modeCaption = GetModeCaption(processMapPlanWellDrillings.IdMode);
|
||||||
row.Cell(columnDepthStart).Value = processMapPlanWellDrillings.DepthStart;
|
|
||||||
row.Cell(columnDepthEnd).Value = processMapPlanWellDrillings.DepthEnd;
|
row.Cell(columnSection).SetCellValue(section);
|
||||||
row.Cell(columnPressurePlan).Value = processMapPlanWellDrillings.Pressure.Plan;
|
row.Cell(columnMode).SetCellValue(modeCaption);
|
||||||
row.Cell(columnPressureLimitMax).Value = processMapPlanWellDrillings.Pressure.LimitMax;
|
row.Cell(columnDepthStart).SetCellValue(processMapPlanWellDrillings.DepthStart);
|
||||||
row.Cell(columnAxialLoadPlan).Value = processMapPlanWellDrillings.AxialLoad.Plan;
|
row.Cell(columnDepthEnd).SetCellValue(processMapPlanWellDrillings.DepthEnd);
|
||||||
row.Cell(columnAxialLoadLimitMax).Value = processMapPlanWellDrillings.AxialLoad.LimitMax;
|
row.Cell(columnPressurePlan).SetCellValue(processMapPlanWellDrillings.Pressure.Plan);
|
||||||
row.Cell(columnTopDriveTorquePlan).Value = processMapPlanWellDrillings.TopDriveTorque.Plan;
|
row.Cell(columnPressureLimitMax).SetCellValue(processMapPlanWellDrillings.Pressure.LimitMax);
|
||||||
row.Cell(columnTopDriveTorqueLimitMax).Value = processMapPlanWellDrillings.TopDriveTorque.LimitMax;
|
row.Cell(columnAxialLoadPlan).SetCellValue(processMapPlanWellDrillings.AxialLoad.Plan);
|
||||||
row.Cell(columnTopDriveSpeedPlan).Value = processMapPlanWellDrillings.TopDriveSpeed.Plan;
|
row.Cell(columnAxialLoadLimitMax).SetCellValue(processMapPlanWellDrillings.AxialLoad.LimitMax);
|
||||||
row.Cell(columnTopDriveSpeedLimitMax).Value = processMapPlanWellDrillings.TopDriveSpeed.LimitMax;
|
row.Cell(columnTopDriveTorquePlan).SetCellValue(processMapPlanWellDrillings.TopDriveTorque.Plan);
|
||||||
row.Cell(columnFlowPlan).Value = processMapPlanWellDrillings.Flow.Plan;
|
row.Cell(columnTopDriveTorqueLimitMax).SetCellValue(processMapPlanWellDrillings.TopDriveTorque.LimitMax);
|
||||||
row.Cell(columnFlowLimitMax).Value = processMapPlanWellDrillings.Flow.LimitMax;
|
row.Cell(columnTopDriveSpeedPlan).SetCellValue(processMapPlanWellDrillings.TopDriveSpeed.Plan);
|
||||||
row.Cell(columnRopPlan).Value = processMapPlanWellDrillings.RopPlan;
|
row.Cell(columnTopDriveSpeedLimitMax).SetCellValue(processMapPlanWellDrillings.TopDriveSpeed.LimitMax);
|
||||||
row.Cell(columnUsageSaub).Value = processMapPlanWellDrillings.UsageSaub;
|
row.Cell(columnFlowPlan).SetCellValue(processMapPlanWellDrillings.Flow.Plan);
|
||||||
row.Cell(columnUsageSpin).Value = processMapPlanWellDrillings.UsageSpin;
|
row.Cell(columnFlowLimitMax).SetCellValue(processMapPlanWellDrillings.Flow.LimitMax);
|
||||||
row.Cell(columnComment).Value = processMapPlanWellDrillings.Comment;
|
row.Cell(columnRopPlan).SetCellValue(processMapPlanWellDrillings.RopPlan);
|
||||||
|
row.Cell(columnUsageSaub).SetCellValue(processMapPlanWellDrillings.UsageSaub);
|
||||||
|
row.Cell(columnUsageSpin).SetCellValue(processMapPlanWellDrillings.UsageSpin);
|
||||||
|
row.Cell(columnComment).SetCellValue(processMapPlanWellDrillings.Comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<ProcessMapPlanWellDrillingDto> ParseWorkBook(IXLWorkbook workbook)
|
private IEnumerable<ProcessMapPlanWellDrillingDto> ParseWorkBook(IXLWorkbook workbook)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
var sheet = workbook.GetWorksheet(sheetNamePlan);
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlan}.");
|
|
||||||
|
|
||||||
return ParseSheet(sheet);
|
return ParseSheet(sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportServ
|
|||||||
|
|
||||||
private ProcessMapPlanWellDrillingDto ParseRow(IXLRow row)
|
private ProcessMapPlanWellDrillingDto ParseRow(IXLRow row)
|
||||||
{
|
{
|
||||||
var wellSectionTypeCaption = row.Cell(columnWellSectionType).GetCellValue<string>()?.Trim().ToLower();
|
var wellSectionTypeCaption = row.Cell(columnSection).GetCellValue<string>()?.Trim().ToLower();
|
||||||
var modeName = row.Cell(columnMode).GetCellValue<string>()?.Trim().ToLower();
|
var modeName = row.Cell(columnMode).GetCellValue<string>()?.Trim().ToLower();
|
||||||
var depthStart = row.Cell(columnDepthStart).GetCellValue<double>();
|
var depthStart = row.Cell(columnDepthStart).GetCellValue<double>();
|
||||||
var depthEnd = row.Cell(columnDepthEnd).GetCellValue<double>();
|
var depthEnd = row.Cell(columnDepthEnd).GetCellValue<double>();
|
||||||
@ -337,7 +337,7 @@ public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportServ
|
|||||||
{
|
{
|
||||||
using var excelTemplateStream = (await GetExcelTemplateStreamAsync(cancellationToken)).File;
|
using var excelTemplateStream = (await GetExcelTemplateStreamAsync(cancellationToken)).File;
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(excelTemplateStream);
|
||||||
|
|
||||||
AddToWorkbook(workbook, processMapPlanWellDrillings);
|
AddToWorkbook(workbook, processMapPlanWellDrillings);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
|||||||
private Stream MakeExelFileStream(IEnumerable<T> trajectories)
|
private Stream MakeExelFileStream(IEnumerable<T> trajectories)
|
||||||
{
|
{
|
||||||
using Stream ecxelTemplateStream = GetTemplateFile();
|
using Stream ecxelTemplateStream = GetTemplateFile();
|
||||||
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(ecxelTemplateStream);
|
||||||
AddTrajecoryToWorkbook(workbook, trajectories);
|
AddTrajecoryToWorkbook(workbook, trajectories);
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||||
@ -65,9 +65,7 @@ namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
|||||||
{
|
{
|
||||||
if (trajectories.Any())
|
if (trajectories.Any())
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName);
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
if (sheet is null)
|
|
||||||
throw new FileFormatException($"Лист с именем {sheetName} отсутствует, либо имеет некорректное название");
|
|
||||||
AddTrajecoryToSheet(sheet, trajectories);
|
AddTrajecoryToSheet(sheet, trajectories);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,12 @@ namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
|||||||
|
|
||||||
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoFactDto trajectory)
|
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoFactDto trajectory)
|
||||||
{
|
{
|
||||||
row.Cell(1).Value = trajectory.WellboreDepth;
|
row.Cell(1).SetCellValue(trajectory.WellboreDepth);
|
||||||
row.Cell(2).Value = trajectory.ZenithAngle;
|
row.Cell(2).SetCellValue(trajectory.ZenithAngle);
|
||||||
row.Cell(3).Value = trajectory.AzimuthGeo;
|
row.Cell(3).SetCellValue(trajectory.AzimuthGeo);
|
||||||
row.Cell(4).Value = trajectory.AzimuthMagnetic;
|
row.Cell(4).SetCellValue(trajectory.AzimuthMagnetic);
|
||||||
row.Cell(5).Value = trajectory.VerticalDepth;
|
row.Cell(5).SetCellValue(trajectory.VerticalDepth);
|
||||||
row.Cell(6).Value = trajectory.Comment;
|
row.Cell(6).SetCellValue(trajectory.Comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,12 @@ namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
|||||||
|
|
||||||
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoFactDto trajectory)
|
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoFactDto trajectory)
|
||||||
{
|
{
|
||||||
row.Cell(1).Value = trajectory.WellboreDepth;
|
row.Cell(1).SetCellValue(trajectory.WellboreDepth);
|
||||||
row.Cell(2).Value = trajectory.ZenithAngle;
|
row.Cell(2).SetCellValue(trajectory.ZenithAngle);
|
||||||
row.Cell(3).Value = trajectory.AzimuthGeo;
|
row.Cell(3).SetCellValue(trajectory.AzimuthGeo);
|
||||||
row.Cell(4).Value = trajectory.AzimuthMagnetic;
|
row.Cell(4).SetCellValue(trajectory.AzimuthMagnetic);
|
||||||
row.Cell(5).Value = trajectory.VerticalDepth;
|
row.Cell(5).SetCellValue(trajectory.VerticalDepth);
|
||||||
row.Cell(6).Value = trajectory.Comment;
|
row.Cell(6).SetCellValue(trajectory.Comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,13 @@ namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
|||||||
|
|
||||||
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoPlanDto trajectory)
|
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoPlanDto trajectory)
|
||||||
{
|
{
|
||||||
row.Cell(1).Value = trajectory.WellboreDepth;
|
row.Cell(1).SetCellValue(trajectory.WellboreDepth);
|
||||||
row.Cell(2).Value = trajectory.ZenithAngle;
|
row.Cell(2).SetCellValue(trajectory.ZenithAngle);
|
||||||
row.Cell(3).Value = trajectory.AzimuthGeo;
|
row.Cell(3).SetCellValue(trajectory.AzimuthGeo);
|
||||||
row.Cell(4).Value = trajectory.AzimuthMagnetic;
|
row.Cell(4).SetCellValue(trajectory.AzimuthMagnetic);
|
||||||
row.Cell(5).Value = trajectory.VerticalDepth;
|
row.Cell(5).SetCellValue(trajectory.VerticalDepth);
|
||||||
row.Cell(6).Value = trajectory.Radius;
|
row.Cell(6).SetCellValue(trajectory.Radius);
|
||||||
row.Cell(7).Value = trajectory.Comment;
|
row.Cell(7).SetCellValue(trajectory.Comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +32,9 @@ public abstract class TrajectoryParserService<T> : ParserServiceBase<T, IParserO
|
|||||||
|
|
||||||
public override ParserResultDto<T> Parse(Stream file, IParserOptionsRequest options)
|
public override ParserResultDto<T> Parse(Stream file, IParserOptionsRequest options)
|
||||||
{
|
{
|
||||||
using var workbook = new XLWorkbook(file, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(file);
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws =>
|
var sheet = workbook.GetWorksheet(SheetName);
|
||||||
ws.Name.ToLower().Trim() == SheetName.ToLower().Trim())
|
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {SheetName}.");
|
|
||||||
|
|
||||||
var trajectoryRows = ParseExcelSheet(sheet, ParseRow, ColumnCount, HeaderRowsCount);
|
var trajectoryRows = ParseExcelSheet(sheet, ParseRow, ColumnCount, HeaderRowsCount);
|
||||||
return trajectoryRows;
|
return trajectoryRows;
|
||||||
|
@ -15,7 +15,7 @@ public class WellOperationDefaultExcelParser : IWellOperationExcelParser<WellOpe
|
|||||||
{
|
{
|
||||||
public SheetDto Parse(Stream stream, WellOperationImportDefaultOptionsDto options)
|
public SheetDto Parse(Stream stream, WellOperationImportDefaultOptionsDto options)
|
||||||
{
|
{
|
||||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(stream);
|
||||||
|
|
||||||
return ParseWorkbook(workbook, options);
|
return ParseWorkbook(workbook, options);
|
||||||
}
|
}
|
||||||
@ -26,9 +26,7 @@ public class WellOperationDefaultExcelParser : IWellOperationExcelParser<WellOpe
|
|||||||
? DefaultTemplateInfo.SheetNamePlan
|
? DefaultTemplateInfo.SheetNamePlan
|
||||||
: DefaultTemplateInfo.SheetNameFact;
|
: DefaultTemplateInfo.SheetNameFact;
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws =>
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
string.Equals(ws.Name, sheetName, StringComparison.CurrentCultureIgnoreCase))
|
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа '{sheetName}'");
|
|
||||||
|
|
||||||
return ParseSheet(sheet);
|
return ParseSheet(sheet);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class WellOperationGazpromKhantosExcelParser : IWellOperationExcelParser<
|
|||||||
|
|
||||||
public SheetDto Parse(Stream stream, WellOperationImportGazpromKhantosOptionsDto options)
|
public SheetDto Parse(Stream stream, WellOperationImportGazpromKhantosOptionsDto options)
|
||||||
{
|
{
|
||||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(stream);
|
||||||
|
|
||||||
return ParseWorkBook(workbook, options);
|
return ParseWorkBook(workbook, options);
|
||||||
}
|
}
|
||||||
@ -54,10 +54,7 @@ public class WellOperationGazpromKhantosExcelParser : IWellOperationExcelParser<
|
|||||||
if (options.EndRow < options.StartRow)
|
if (options.EndRow < options.StartRow)
|
||||||
throw new ArgumentInvalidException(nameof(options.EndRow), "Конечный номер строки не может быть больше начального");
|
throw new ArgumentInvalidException(nameof(options.EndRow), "Конечный номер строки не может быть больше начального");
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws =>
|
var sheet = workbook.GetWorksheet(options.SheetName);
|
||||||
string.Equals(ws.Name, options.SheetName, StringComparison.CurrentCultureIgnoreCase))
|
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа '{options.SheetName}'");
|
|
||||||
|
|
||||||
return ParseSheet(sheet, options.StartRow, options.EndRow);
|
return ParseSheet(sheet, options.StartRow, options.EndRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationImport;
|
|||||||
|
|
||||||
public class WellOperationExportService : IWellOperationExportService
|
public class WellOperationExportService : IWellOperationExportService
|
||||||
{
|
{
|
||||||
|
//TODO: удалить неиспользуемую зависимость
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
private readonly IWellOperationImportTemplateService wellOperationImportTemplateService;
|
private readonly IWellOperationImportTemplateService wellOperationImportTemplateService;
|
||||||
@ -42,7 +43,7 @@ public class WellOperationExportService : IWellOperationExportService
|
|||||||
{
|
{
|
||||||
using Stream ecxelTemplateStream = wellOperationImportTemplateService.GetExcelTemplateStream();
|
using Stream ecxelTemplateStream = wellOperationImportTemplateService.GetExcelTemplateStream();
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(ecxelTemplateStream);
|
||||||
AddOperationsToWorkbook(workbook, operations);
|
AddOperationsToWorkbook(workbook, operations);
|
||||||
|
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
@ -56,17 +57,17 @@ public class WellOperationExportService : IWellOperationExportService
|
|||||||
var planOperations = operations.Where(o => o.IdType == 0);
|
var planOperations = operations.Where(o => o.IdType == 0);
|
||||||
if (planOperations.Any())
|
if (planOperations.Any())
|
||||||
{
|
{
|
||||||
var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == DefaultTemplateInfo.SheetNamePlan);
|
var sheetPlan = workbook.GetWorksheet(DefaultTemplateInfo.SheetNamePlan);
|
||||||
if (sheetPlan is not null)
|
|
||||||
AddOperationsToSheet(sheetPlan, planOperations);
|
AddOperationsToSheet(sheetPlan, planOperations);
|
||||||
}
|
}
|
||||||
|
|
||||||
var factOperations = operations.Where(o => o.IdType == 1);
|
var factOperations = operations.Where(o => o.IdType == 1);
|
||||||
if (factOperations.Any())
|
if (factOperations.Any())
|
||||||
{
|
{
|
||||||
var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == DefaultTemplateInfo.SheetNameFact);
|
var sheetFact = workbook.GetWorksheet(DefaultTemplateInfo.SheetNameFact);
|
||||||
if (sheetFact is not null)
|
|
||||||
AddOperationsToSheet(sheetFact, factOperations);
|
AddOperationsToSheet(sheetFact, factOperations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +88,16 @@ public class WellOperationExportService : IWellOperationExportService
|
|||||||
private static void AddOperationToRow(IXLRow row, WellOperationDto operation, IEnumerable<WellSectionTypeDto> sections,
|
private static void AddOperationToRow(IXLRow row, WellOperationDto operation, IEnumerable<WellSectionTypeDto> sections,
|
||||||
IEnumerable<WellOperationCategoryDto> categories)
|
IEnumerable<WellOperationCategoryDto> categories)
|
||||||
{
|
{
|
||||||
row.Cell(DefaultTemplateInfo.ColumnSection).Value = sections.First(s => s.Id == operation.IdWellSectionType).Caption;
|
var sectionCaption = sections.First(s => s.Id == operation.IdWellSectionType).Caption;
|
||||||
row.Cell(DefaultTemplateInfo.ColumnCategory).Value = categories.First(o => o.Id == operation.IdCategory).Name;
|
var categoryName = categories.First(o => o.Id == operation.IdCategory).Name;
|
||||||
row.Cell(DefaultTemplateInfo.ColumnCategoryInfo).Value = operation.CategoryInfo;
|
|
||||||
row.Cell(DefaultTemplateInfo.ColumnDepthStart).Value = operation.DepthStart;
|
row.Cell(DefaultTemplateInfo.ColumnSection).SetCellValue(sectionCaption);
|
||||||
row.Cell(DefaultTemplateInfo.ColumnDepthEnd).Value = operation.DepthEnd;
|
row.Cell(DefaultTemplateInfo.ColumnCategory).SetCellValue(categoryName);
|
||||||
row.Cell(DefaultTemplateInfo.ColumnDate).Value = operation.DateStart;
|
row.Cell(DefaultTemplateInfo.ColumnCategoryInfo).SetCellValue(operation.CategoryInfo);
|
||||||
row.Cell(DefaultTemplateInfo.ColumnDuration).Value = operation.DurationHours;
|
row.Cell(DefaultTemplateInfo.ColumnDepthStart).SetCellValue(operation.DepthStart);
|
||||||
row.Cell(DefaultTemplateInfo.ColumnComment).Value = operation.Comment;
|
row.Cell(DefaultTemplateInfo.ColumnDepthEnd).SetCellValue(operation.DepthEnd);
|
||||||
|
row.Cell(DefaultTemplateInfo.ColumnDate).SetCellValue(operation.DateStart);
|
||||||
|
row.Cell(DefaultTemplateInfo.ColumnDuration).SetCellValue(operation.DurationHours);
|
||||||
|
row.Cell(DefaultTemplateInfo.ColumnComment).SetCellValue(operation.Comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,7 +37,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");
|
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");
|
||||||
|
|
||||||
var ecxelTemplateStream = GetExcelTemplateStream();
|
var ecxelTemplateStream = GetExcelTemplateStream();
|
||||||
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
using var workbook = new XLWorkbook(ecxelTemplateStream);
|
||||||
FillScheduleSheetToWorkbook(workbook, tvd, well);
|
FillScheduleSheetToWorkbook(workbook, tvd, well);
|
||||||
FillTvdSheetToWorkbook(workbook, tvd, well);
|
FillTvdSheetToWorkbook(workbook, tvd, well);
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
@ -72,9 +72,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
|
|
||||||
private static void FillCurrentScheduleSheet(XLWorkbook workbook, IEnumerable<WellOperationDto> tvdList, string sheetName)
|
private static void FillCurrentScheduleSheet(XLWorkbook workbook, IEnumerable<WellOperationDto> tvdList, string sheetName)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName);
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
if (sheet is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int headerRowsCount = 6;
|
const int headerRowsCount = 6;
|
||||||
|
|
||||||
@ -103,9 +101,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
|
|
||||||
private static void FillScheduleSheet(XLWorkbook workbook, IEnumerable<PlanFactPredictBase<WellOperationDto>> tvd, WellDto well)
|
private static void FillScheduleSheet(XLWorkbook workbook, IEnumerable<PlanFactPredictBase<WellOperationDto>> tvd, WellDto well)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameSchedule);
|
var sheet = workbook.GetWorksheet(sheetNameSchedule);
|
||||||
if (sheet is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int headerRowsCount = 6;
|
const int headerRowsCount = 6;
|
||||||
const int rowTitle = 3;
|
const int rowTitle = 3;
|
||||||
@ -132,7 +128,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
const int columnNpt = 21;
|
const int columnNpt = 21;
|
||||||
|
|
||||||
var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}";
|
var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}";
|
||||||
sheet.Row(rowTitle).Cell(3).Value = subTitle;
|
sheet.Row(rowTitle).Cell(3).SetCellValue(subTitle);
|
||||||
|
|
||||||
var tvdList = tvd.ToList();
|
var tvdList = tvd.ToList();
|
||||||
var facts = tvd
|
var facts = tvd
|
||||||
@ -228,7 +224,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
|
|
||||||
var rowSummary = sheet.Row(rowNumSummary);
|
var rowSummary = sheet.Row(rowNumSummary);
|
||||||
rowSummary.Style.Font.Bold = true;
|
rowSummary.Style.Font.Bold = true;
|
||||||
rowSummary.Cell(columnCaption).Value = "Итого:";
|
rowSummary.Cell(columnCaption).SetCellValue("Итого:");
|
||||||
|
|
||||||
AddRangeFormula(rowSummary, "sum", columnDeltaWellDepthPerDay);
|
AddRangeFormula(rowSummary, "sum", columnDeltaWellDepthPerDay);
|
||||||
AddRangeFormula(rowSummary, "sum", columnDurationPlan);
|
AddRangeFormula(rowSummary, "sum", columnDurationPlan);
|
||||||
@ -241,9 +237,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
SetBorder(rowSummary.Cells(true).Style);
|
SetBorder(rowSummary.Cells(true).Style);
|
||||||
|
|
||||||
var rowSummary2 = sheet.Row(rowNumSummary + 1);
|
var rowSummary2 = sheet.Row(rowNumSummary + 1);
|
||||||
rowSummary2.DataType = XLDataType.Number;
|
|
||||||
rowSummary2.Style.NumberFormat.Format = "0,00";
|
rowSummary2.Style.NumberFormat.Format = "0,00";
|
||||||
rowSummary2.Cell(columnCaption).Value = "в сутках:";
|
rowSummary2.Cell(columnCaption).SetCellValue("в сутках:");
|
||||||
rowSummary2.Cell(columnDurationPlan).FormulaA1 = $"={GetColunmLetter(columnDurationPlan)}{rowNumSummary}/24";
|
rowSummary2.Cell(columnDurationPlan).FormulaA1 = $"={GetColunmLetter(columnDurationPlan)}{rowNumSummary}/24";
|
||||||
SetNumber(rowSummary2.Cell(columnDurationPlan));
|
SetNumber(rowSummary2.Cell(columnDurationPlan));
|
||||||
rowSummary2.Cell(columnDurationFact).FormulaA1 = $"={GetColunmLetter(columnDurationFact)}{rowNumSummary}/24";
|
rowSummary2.Cell(columnDurationFact).FormulaA1 = $"={GetColunmLetter(columnDurationFact)}{rowNumSummary}/24";
|
||||||
@ -255,9 +250,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
|
|
||||||
private static void FillTvdSheetToWorkbook(XLWorkbook workbook, IEnumerable<PlanFactPredictBase<WellOperationDto>> tvd, WellDto well)
|
private static void FillTvdSheetToWorkbook(XLWorkbook workbook, IEnumerable<PlanFactPredictBase<WellOperationDto>> tvd, WellDto well)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameTvd);
|
var sheet = workbook.GetWorksheet(sheetNameTvd);
|
||||||
if (sheet is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int rowTitle = 2;
|
const int rowTitle = 2;
|
||||||
const int rowSubtitle = 3;
|
const int rowSubtitle = 3;
|
||||||
@ -346,14 +339,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
|
|
||||||
private static IXLCell SetDateTime(IXLCell cell)
|
private static IXLCell SetDateTime(IXLCell cell)
|
||||||
{
|
{
|
||||||
cell.DataType = XLDataType.DateTime;
|
|
||||||
cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
|
cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IXLCell SetNumber(IXLCell cell)
|
private static IXLCell SetNumber(IXLCell cell)
|
||||||
{
|
{
|
||||||
cell.DataType = XLDataType.Number;
|
|
||||||
cell.Style.NumberFormat.Format = "0.00";
|
cell.Style.NumberFormat.Format = "0.00";
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
@ -361,7 +352,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
private static IXLCell SetCell(IXLRow row, int colunm, object? value)
|
private static IXLCell SetCell(IXLRow row, int colunm, object? value)
|
||||||
{
|
{
|
||||||
var cell = row.Cell(colunm);
|
var cell = row.Cell(colunm);
|
||||||
cell.Value = value;
|
cell.SetCellValue(value);
|
||||||
|
|
||||||
SetBorder(cell.Style);
|
SetBorder(cell.Style);
|
||||||
cell.Style.Alignment.WrapText = true;
|
cell.Style.Alignment.WrapText = true;
|
||||||
|
@ -1,96 +1,46 @@
|
|||||||
using ClosedXML.Excel;
|
using ClosedXML.Excel;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure;
|
namespace AsbCloudInfrastructure;
|
||||||
|
|
||||||
internal static class XLExtentions
|
public static class XLExtentions
|
||||||
{
|
{
|
||||||
internal static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS", bool setAllBorders = true)
|
public static IXLWorksheet GetWorksheet(this IXLWorkbook workbook, string sheetName) =>
|
||||||
{
|
workbook.Worksheets.FirstOrDefault(ws => string.Equals(ws.Name.Trim(), sheetName.Trim(), StringComparison.CurrentCultureIgnoreCase))
|
||||||
cell.Value = value;
|
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
||||||
if (setAllBorders == true)
|
|
||||||
{
|
|
||||||
cell.Style
|
|
||||||
.SetAllBorders()
|
|
||||||
.Alignment.WrapText = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static IXLCell SetCellValue<T>(this IXLCell cell, T value)
|
||||||
|
{
|
||||||
|
if (typeof(T) == typeof(DateTime))
|
||||||
|
cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
|
||||||
|
|
||||||
cell.Value = value;
|
cell.Value = XLCellValue.FromObject(value);
|
||||||
|
|
||||||
cell.DataType = XLDataType.DateTime;
|
return cell;
|
||||||
cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
|
}
|
||||||
|
|
||||||
return cell;
|
public static IXLCell SetHyperlink(this IXLCell cell, string link)
|
||||||
}
|
{
|
||||||
|
cell.SetHyperlink(new XLHyperlink(link));
|
||||||
|
|
||||||
public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00")
|
return cell;
|
||||||
{
|
}
|
||||||
cell.Value = (value is not null && double.IsFinite(value.Value)) ? value : null;
|
|
||||||
cell.DataType = XLDataType.Number;
|
|
||||||
cell.Style.NumberFormat.Format = format;
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false)
|
public static T? GetCellValue<T>(this IXLCell cell)
|
||||||
{
|
{
|
||||||
cell.Value = value;
|
try
|
||||||
if (adaptRowHeight)
|
{
|
||||||
{
|
if (cell.IsEmpty() && default(T) == null)
|
||||||
var colWidth = cell.WorksheetColumn().Width;
|
return default;
|
||||||
var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize);
|
|
||||||
if (value.Length > maxCharsToWrap)
|
|
||||||
{
|
|
||||||
var row = cell.WorksheetRow();
|
|
||||||
var baseHeight = row.Height;
|
|
||||||
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cell;
|
return cell.GetValue<T>();
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
public static IXLCell SetVal(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS")
|
{
|
||||||
{
|
throw new FileFormatException(
|
||||||
cell.Value = value;
|
$"Лист '{cell.Worksheet.Name}'. {cell.Address.RowNumber} строка содержит некорректное значение в {cell.Address.ColumnNumber} столбце");
|
||||||
cell.DataType = XLDataType.DateTime;
|
}
|
||||||
cell.Style.DateFormat.Format = dateFormat;
|
}
|
||||||
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IXLStyle SetAllBorders(this IXLStyle style, XLBorderStyleValues borderStyle = XLBorderStyleValues.Thin)
|
|
||||||
{
|
|
||||||
style.Border.RightBorder = borderStyle;
|
|
||||||
style.Border.LeftBorder = borderStyle;
|
|
||||||
style.Border.TopBorder = borderStyle;
|
|
||||||
style.Border.BottomBorder = borderStyle;
|
|
||||||
style.Border.InsideBorder = borderStyle;
|
|
||||||
style.Border.OutsideBorder = borderStyle;
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static T? GetCellValue<T>(this IXLCell cell)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (cell.IsEmpty() && default(T) == null)
|
|
||||||
return default;
|
|
||||||
|
|
||||||
if (typeof(T) != typeof(DateTime))
|
|
||||||
return (T)Convert.ChangeType(cell.GetFormattedString(), typeof(T), CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
if (cell.Value is DateTime dateTime)
|
|
||||||
return (T)(object)dateTime;
|
|
||||||
|
|
||||||
return (T)(object)DateTime.FromOADate((double)cell.Value);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист '{cell.Worksheet.Name}'. {cell.Address.RowNumber} строка содержит некорректное значение в {cell.Address.ColumnNumber} столбце");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
159
AsbCloudWebApi.Tests/XLExtensionsTests.cs
Normal file
159
AsbCloudWebApi.Tests/XLExtensionsTests.cs
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using AsbCloudInfrastructure;
|
||||||
|
using ClosedXML.Excel;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Tests;
|
||||||
|
|
||||||
|
public class XLExtensionsTests
|
||||||
|
{
|
||||||
|
private const string cellUsed = "A1";
|
||||||
|
private const string sheetName = "test";
|
||||||
|
|
||||||
|
private readonly IXLWorkbook workbook;
|
||||||
|
|
||||||
|
public XLExtensionsTests()
|
||||||
|
{
|
||||||
|
workbook = new XLWorkbook();
|
||||||
|
workbook.Worksheets.Add(sheetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetWorksheet_returns_sheet()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(sheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(valueTypesToSet))]
|
||||||
|
public void SetCellValue_returns_success(object value, XLDataType expectedDataType)
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var cell = GetCell(cellUsed);
|
||||||
|
cell.SetCellValue(value);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(expectedDataType, cell.DataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCellValue_returns_double()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
const double expectedValue = 2.0d;
|
||||||
|
SetCellValue(expectedValue);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var actualValue = GetCell(cellUsed).GetCellValue<double>();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCellValue_returns_float()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
const float expectedValue = 2.0f;
|
||||||
|
SetCellValue(expectedValue);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var actualValue = GetCell(cellUsed).GetCellValue<float>();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("test")]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void GetCellValue_returns_string(string? expectedValue)
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
SetCellValue(expectedValue);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var actualValue = GetCell(cellUsed).GetCellValue<string>();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCellValue_returns_bool()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
const bool expectedValue = true;
|
||||||
|
SetCellValue(expectedValue);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var actualValue = GetCell(cellUsed).GetCellValue<bool>();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCellValue_returns_dateTime()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var expectedValue = DateTime.Parse("2023-01-01");
|
||||||
|
SetCellValue(expectedValue);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var actualValue = GetCell(cellUsed).GetCellValue<DateTime>();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
Assert.Equal(DateTimeKind.Unspecified, actualValue.Kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCellValue_returns_nullable()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var actualValue = GetCell(cellUsed).GetCellValue<object?>();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Null(actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SetHyperlink_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
const string link = "http://test.ru";
|
||||||
|
|
||||||
|
//act
|
||||||
|
GetCell(cellUsed).SetHyperlink(link);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
var hyperLink = GetCell(cellUsed).GetHyperlink();
|
||||||
|
Assert.NotNull(hyperLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCellValue<T>(T value)
|
||||||
|
{
|
||||||
|
var cell = GetCell(cellUsed);
|
||||||
|
cell.SetCellValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly object[][] valueTypesToSet =
|
||||||
|
{
|
||||||
|
new object[] { 2.0d, XLDataType.Number },
|
||||||
|
new object[] { 2.0f, XLDataType.Number },
|
||||||
|
new object[] { "test", XLDataType.Text },
|
||||||
|
new object[] { true, XLDataType.Boolean },
|
||||||
|
new object[] { DateTime.UtcNow, XLDataType.DateTime }
|
||||||
|
};
|
||||||
|
|
||||||
|
private IXLCell GetCell(string cellAddressInRange)
|
||||||
|
{
|
||||||
|
var sheet = workbook.GetWorksheet(sheetName);
|
||||||
|
return sheet.Cell(cellAddressInRange);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user