1
0

77 lines
2.2 KiB
C#
Raw Normal View History

2025-01-14 05:59:55 +00:00
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;
}
}