DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellOperationImport/FileParser/WellOperationDefaultExcelParser.cs
2023-09-29 12:06:46 +05:00

106 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AsbCloudApp.Data.WellOperationImport;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services.WellOperationImport;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.WellOperationImport.Constants;
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
public class WellOperationDefaultExcelParser : IWellOperationExcelParser
{
public int IdTemplate => Templates.IdDefaultTemplate;
public IEnumerable<int> IdTypes => new[] { WellOperation.IdOperationTypePlan, WellOperation.IdOperationTypeFact };
public IEnumerable<RowDto> Parse(Stream stream, WellOperationParserOptionsDto options)
{
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
return ParseWorkbook(workbook, options);
}
private static IEnumerable<RowDto> ParseWorkbook(IXLWorkbook workbook, WellOperationParserOptionsDto options)
{
if (string.IsNullOrWhiteSpace(options.SheetName))
throw new ArgumentInvalidException(nameof(options.SheetName), "Не указано название листа");
var sheet = workbook.Worksheets.FirstOrDefault(ws =>
string.Equals(ws.Name, options.SheetName, StringComparison.CurrentCultureIgnoreCase))
?? throw new FileFormatException($"Книга excel не содержит листа '{options.SheetName}'");
return ParseSheet(sheet);
}
private static IEnumerable<RowDto> ParseSheet(IXLWorksheet sheet)
{
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7)
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
var count = sheet.RowsUsed().Count() - DefaultTemplateInfo.HeaderRowsCount;
switch (count)
{
case > 1024:
throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество операций.");
case <= 0:
return Enumerable.Empty<RowDto>();
}
var rows = new RowDto[count];
var cellValuesErrors = new List<string>();
for (int i = 0; i < rows.Length; i++)
{
try
{
var xlRow = sheet.Row(1 + i + DefaultTemplateInfo.HeaderRowsCount);
rows[i] = ParseRow(xlRow);
}
catch (FileFormatException ex)
{
cellValuesErrors.Add(ex.Message);
}
}
if (cellValuesErrors.Any())
throw new FileFormatException(string.Join("\r\n", cellValuesErrors));
return rows;
}
private static RowDto ParseRow(IXLRow xlRow)
{
return new RowDto
{
Number = xlRow.RowNumber(),
Section = GetCellValue<string>(xlRow.Cell(DefaultTemplateInfo.ColumnSection)),
Category = GetCellValue<string>(xlRow.Cell(DefaultTemplateInfo.ColumnCategory)),
CategoryInfo = GetCellValue<string>(xlRow.Cell(DefaultTemplateInfo.ColumnCategoryInfo)),
DepthStart = GetCellValue<double>(xlRow.Cell(DefaultTemplateInfo.ColumnDepthStart)),
DepthEnd = GetCellValue<double>(xlRow.Cell(DefaultTemplateInfo.ColumnDepthEnd)),
Date = GetCellValue<DateTime>(xlRow.Cell(DefaultTemplateInfo.ColumnDate)),
Duration = GetCellValue<double>(xlRow.Cell(DefaultTemplateInfo.ColumnDuration)),
Comment = GetCellValue<string>(xlRow.Cell(DefaultTemplateInfo.ColumnComment))
};
}
//TODO: вынести в метод расширения
private static T GetCellValue<T>(IXLCell cell)
{
try
{
return (T)Convert.ChangeType(cell.Value, typeof(T));
}
catch
{
throw new FileFormatException(
$"Лист '{cell.Worksheet.Name}'. Ячейка: ({cell.Address.RowNumber},{cell.Address.ColumnNumber}) содержит некорректное значение");
}
}
}