diff options
Diffstat (limited to 'RhSolutions.SkuParser.Api/Services/ExcelParser.cs')
-rw-r--r-- | RhSolutions.SkuParser.Api/Services/ExcelParser.cs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/RhSolutions.SkuParser.Api/Services/ExcelParser.cs b/RhSolutions.SkuParser.Api/Services/ExcelParser.cs new file mode 100644 index 0000000..27b10bd --- /dev/null +++ b/RhSolutions.SkuParser.Api/Services/ExcelParser.cs @@ -0,0 +1,76 @@ +using ClosedXML.Excel; +using RhSolutions.SkuParser.Models; + +namespace RhSolutions.SkuParser.Services; + +public class ExcelParser : ISkuParser +{ + public IEnumerable<ProductQuantity> ParseProducts(IFormFile file) + { + using XLWorkbook workbook = new(file.OpenReadStream()); + IXLWorksheet ws = workbook.Worksheet(1); + + var leftTop = ws.FirstCellUsed()?.Address; + var rightBottom = ws.LastCellUsed()?.Address; + if (new object?[] { leftTop, rightBottom }.Any(x => x == null)) + { + throw new ArgumentException($"Таблица пуста: {file.FileName}"); + } + + var lookupRange = ws.Range(leftTop, rightBottom).RangeUsed(); + var columns = lookupRange.Columns(); + + var skuColumnQuantity = columns + .Select(column => new + { + Column = column, + Products = column.CellsUsed() + .Select(cell => !cell.HasFormula && Product.TryParse(cell.Value.ToString(), out Product? p) ? p : null) + }) + .Select(c => new { c.Column, SkuCount = c.Products.Count(p => p != null) }) + .Aggregate((l, r) => l.SkuCount > r.SkuCount ? l : r); + var skuColumn = skuColumnQuantity.SkuCount > 0 ? skuColumnQuantity.Column : null; + + if (skuColumn == null) + { + throw new ArgumentException($"Столбец с артикулом не определен: {file.FileName}"); + } + + var quantityColumn = lookupRange.Columns().Skip(skuColumn.ColumnNumber()) + .Select(column => new + { + Column = column, + IsColumnWithNumbers = column.CellsUsed() + .Count(cell => cell.Value.IsNumber == true) > column.CellsUsed().Count() / 4 + }) + .First(x => x.IsColumnWithNumbers) + .Column; + + if (quantityColumn == null) + { + throw new ArgumentException($"Столбец с количеством не определен: {file.FileName}"); + } + + List<ProductQuantity> result = new(); + var rows = quantityColumn.CellsUsed().Select(x => x.Address.RowNumber); + + foreach (var row in rows) + { + var quantity = quantityColumn.Cell(row).Value; + var sku = skuColumn.Cell(row).Value; + + if (quantity.IsNumber + && Product.TryParse(sku.ToString(), out Product? p)) + { + ProductQuantity pq = new() + { + Product = p!, + Quantity = quantity.GetNumber() + }; + result.Add(pq); + } + } + + return result; + } +} |