using AsbCloudApp.Data.Trajectory; using ClosedXML.Excel; using System.Collections.Generic; using System.IO; using System.Linq; namespace AsbCloudInfrastructure.Services.Trajectory.Import { public abstract class TrajectoryParserService where T : TrajectoryGeoDto { public abstract string templateFileName { get; } public abstract string usingTemplateFile { get; } public abstract string sheetName { get; } public abstract int headerRowsCount { get; } protected abstract T ParseRow(IXLRow row); public IEnumerable Import(Stream stream) { using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled); var trajectoryRows = ParseFileStream(stream); return trajectoryRows; } private IEnumerable ParseFileStream(Stream stream) { using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled); return ParseWorkbook(workbook); } private IEnumerable ParseWorkbook(IXLWorkbook workbook) { var sheetTrajectory = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName); if (sheetTrajectory is null) throw new FileFormatException($"Книга excel не содержит листа {sheetName}."); var trajectoryRows = ParseSheet(sheetTrajectory); return trajectoryRows; } private IEnumerable ParseSheet(IXLWorksheet sheet) { if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 6) throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов."); var count = sheet.RowsUsed().Count() - headerRowsCount; if (count > 1024) throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк."); if (count <= 0) throw new FileFormatException($"Лист {sheet.Name} некорректного формата либо пустой"); var trajectoryRows = new List(count); var parseErrors = new List(); for (int i = 0; i < count; i++) { var row = sheet.Row(1 + i + headerRowsCount); try { var trajectoryRow = ParseRow(row); trajectoryRows.Add(trajectoryRow); } catch (FileFormatException ex) { parseErrors.Add(ex.Message); } } if (parseErrors.Any()) throw new FileFormatException(string.Join("\r\n", parseErrors)); return trajectoryRows; } } }