190 lines
6.1 KiB
C#
190 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(currentSku)
|
|
{
|
|
Name = $"Распознанный артикул"
|
|
};
|
|
|
|
if (readResult.ContainsKey(product))
|
|
{
|
|
readResult[product] += currentAmount.Value;
|
|
}
|
|
|
|
else
|
|
{
|
|
readResult.Add(product, currentAmount.Value);
|
|
}
|
|
}
|
|
|
|
return readResult;
|
|
}
|
|
|
|
public IEnumerable<(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"]);
|
|
Range headerRow = amountCell.EntireRow;
|
|
Range skuCell = headerRow.Find(headers["Sku"]),
|
|
productLineCell = headerRow.Find(headers["ProductLine"]),
|
|
nameCell = headerRow.Find(headers["Name"]),
|
|
measureCell = headerRow.Find(headers["Measure"]);
|
|
|
|
var lastRowIndex = worksheet.Cells[worksheet.Rows.Count, skuCell.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;
|
|
var productMeasure = measure?.ToString() switch
|
|
{
|
|
"м" => Measure.M,
|
|
"шт" => Measure.P,
|
|
"м2" => Measure.M2,
|
|
"кг" => Measure.Kg,
|
|
_ => Measure.P,
|
|
};
|
|
if (productLine == null || name == null || sku == null)
|
|
continue;
|
|
|
|
if (!ProductSku.TryParse(sku.ToString(), out _))
|
|
continue;
|
|
|
|
Product p = new(sku.ToString())
|
|
{
|
|
ProductLines = new List<string>() { productLine.ToString() },
|
|
Name = name.ToString().Split('\n').First(),
|
|
ProductMeasure = productMeasure
|
|
};
|
|
|
|
if (readResult.ContainsKey(p))
|
|
{
|
|
readResult[p] += amount.Value;
|
|
}
|
|
|
|
else
|
|
{
|
|
readResult.Add(p, amount.Value);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
result.Add((wbName, readResult));
|
|
}
|
|
return result.OrderBy(x => x.Item1);
|
|
}
|
|
|
|
public IEnumerable<(string, Dictionary<Product, double>)> ReadProducts(string[] files)
|
|
{
|
|
HashSet<string> openedFiles = RhSolutionsAddIn.Excel.Workbooks
|
|
.Cast<Workbook>()
|
|
.Select(wb => wb.FullName)
|
|
.ToHashSet();
|
|
_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)
|
|
{
|
|
string file = (string)ws.Parent.FullName;
|
|
if (!openedFiles.Contains(file))
|
|
{
|
|
ws.Parent.Close(SaveChanges: false);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_progressBar?.Dispose();
|
|
}
|
|
} |