1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
RhSolutions.SkuParser/RhSolutions.SkuParser.Api/Services/ExcelParser.cs
Serghei Cebotari 6fe0a5e92b Squashed commit of the following:
commit 688c5426e8793b808b9c75c9a19733af0a402fcb
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 16:25:14 2024 +0300

    Switch to port 8080

commit c39249f6528ec76686a9382d1dc375c07d1d5044
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 16:24:59 2024 +0300

    Switch to alpine image

commit 5318d7ec3f4f3d205549cf6732fa5b066a1d0a36
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 15:40:14 2024 +0300

    Add docker

commit b6cd60a973da26bc92cf1fb45b4d2396b7ce56ea
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 15:00:12 2024 +0300

    Delete asynchrony

commit 44a194e6d27312f3b8dd0b9c9c02d873e06e0b22
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 14:59:29 2024 +0300

    Add Equals and GetHasCode methods overrides to ProductQuantity class

commit a274eadd313e12f11cc84d32e5030bbc5b187f8c
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 14:58:37 2024 +0300

    Add parsers tests

commit 4f969e70d9716d8ddb4f4efedd466846289d7e2b
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sun Jul 21 14:57:55 2024 +0300

    Update product tests

commit 2485e20d0e93bed562f929055b6867dc2574a95b
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sat Jul 20 19:34:19 2024 +0300

    Implement Excel parser

commit 30f2e28c87
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Sat Jul 20 16:58:35 2024 +0300

    Implement csv parser

commit 08e86b43c0
Author: Serghei Cebotari <serghei@cebotari.ru>
Date:   Thu Jul 18 21:01:28 2024 +0300

    Edit port number
2024-07-21 16:25:59 +03:00

77 lines
2.2 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 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;
}
}