RhSolutions-AddIn/RhSolutions.AddIn/Services/ExcelReader.cs
2023-04-20 09:37:07 +03:00

191 lines
6.1 KiB
C#

using System.IO;
#if !NET472
using System.Runtime.Versioning;
using RhSolutions.Tools;
#endif
namespace RhSolutions.Services;
#if !NET472
[SupportedOSPlatform("windows")]
#endif
public class ExcelReader : IReader, IDisposable
{
private ProgressBar _progressBar;
private readonly Dictionary<string, string> headers;
private readonly Application _application;
public ExcelReader(Application application, IAddInConfiguration configuration)
{
_application = application;
headers = configuration.GetPriceListHeaders();
}
public Dictionary<Product, double> ReadProducts(Range range)
{
object[,] cells = range.Value2;
Dictionary<Product, double> readResult = new();
for (int row = 1; row <= range.Rows.Count; row++)
{
if (cells[row, 1] == null || cells[row, 2] == null)
continue;
string currentSku = null;
double? currentAmount = null;
for (int column = 1; column <= 2; column++)
{
object currentCell = cells[row, column];
if (ProductSku.TryParse(currentCell.ToString(), out var validSku))
{
currentSku = validSku.FirstOrDefault().ToString() ?? null;
}
else if (currentCell.GetType() == typeof(string)
&& double.TryParse(currentCell.ToString(), out _))
{
currentAmount = double.Parse((string)currentCell);
}
else if (currentCell.GetType() == typeof(double))
{
currentAmount = (double)currentCell;
}
}
if (currentSku == null || currentAmount == null)
{
continue;
}
Product product = new() { ProductSku = currentSku };
if (readResult.ContainsKey(product))
{
readResult[product] += currentAmount.Value;
}
else
{
readResult.Add(product, currentAmount.Value);
}
}
return readResult;
}
public List<(string, Dictionary<Product, double>)>
ReadProducts(IEnumerable<Worksheet> worksheets)
{
List<(string, Dictionary<Product, double>)> result = new();
foreach (Worksheet worksheet in worksheets)
{
if (!worksheet.IsValidSource())
{
continue;
}
string wbName = Path.GetFileNameWithoutExtension(
worksheet.Parent.Name);
Range AmountCell = worksheet.Cells.Find(headers["Amount"]),
SkuCell = worksheet.Cells.Find(headers["Sku"]),
ProductLineCell = worksheet.Cells.Find(headers["ProductLine"]),
NameCell = worksheet.Cells.Find(headers["Name"]),
MeasureCell = worksheet.Cells.Find(headers["Measure"]);
var lastRowIndex = worksheet.Cells[worksheet.Rows.Count, AmountCell.Column]
.End[XlDirection.xlUp].Row;
Dictionary<Product, double> readResult = new();
for (int row = AmountCell.Row + 1; row <= lastRowIndex; row++)
{
double? amount = worksheet.Cells[row, AmountCell.Column].Value2 as double?;
if (amount != null && amount.Value != 0)
{
object productLine = worksheet.Cells[row, ProductLineCell.Column].Value2;
object name = worksheet.Cells[row, NameCell.Column].Value2;
object sku = worksheet.Cells[row, SkuCell.Column].Value2;
object measure = worksheet.Cells[row, MeasureCell.Column].Value2;
Measure productMeasure;
switch (measure.ToString())
{
case "м":
productMeasure = Measure.M;
break;
case "шт":
productMeasure = Measure.P;
break;
case "м2":
productMeasure = Measure.M2;
break;
case "кг":
productMeasure = Measure.Kg;
break;
default:
productMeasure = Measure.P;
break;
}
if (productLine == null || name == null || sku == null)
continue;
if (!ProductSku.TryParse(sku.ToString(), out _))
continue;
Product p = new()
{
ProductSku = sku.ToString(),
ProductLine = productLine.ToString(),
Name = name.ToString(),
ProductMeasure = productMeasure
};
if (readResult.ContainsKey(p))
{
readResult[p] += amount.Value;
}
else
{
readResult.Add(p, amount.Value);
}
}
}
result.Add((wbName, readResult));
}
return result;
}
public List<(string, Dictionary<Product, double>)> ReadProducts(string[] files)
{
_progressBar = new("Открываю исходные файлы...", files.Length);
List<Worksheet> worksheets = new();
_application.ScreenUpdating = false;
foreach (string file in files)
{
Workbook wb = _application.Workbooks.Open(file);
worksheets.Add(wb.ActiveSheet);
_progressBar.Update();
}
_application.ScreenUpdating = true;
var result = ReadProducts(worksheets);
foreach (var ws in worksheets)
{
ws.Parent.Close();
}
return result;
}
public void Dispose()
{
_progressBar?.Dispose();
}
}