using System; using System.Collections.Generic; using ClosedXML.Excel; using DeclarationAutomatization.Models; namespace DeclarationAutomatization.Services; public class ExcelImportService { // Читает лист СПРАВКА из файла Excel. // startingNumber — первый п/п для строк этого файла. // Возвращает список SpravkaItem с назначенными п/п. public List ReadSpravka(string filePath, int startingNumber) { var result = new List(); using var workbook = new XLWorkbook(filePath); // Ищем лист "СПРАВКА" (регистронезависимо) IXLWorksheet? sheet = null; foreach (var ws in workbook.Worksheets) { if (ws.Name.Equals("СПРАВКА", StringComparison.OrdinalIgnoreCase)) { sheet = ws; break; } } if (sheet == null) throw new InvalidOperationException($"Лист 'СПРАВКА' не найден в файле: {filePath}"); // Ищем строку заголовка: первая строка, где ячейка B содержит "Наименование" int headerRow = FindHeaderRow(sheet); if (headerRow < 0) throw new InvalidOperationException("Не найдена строка заголовка в листе СПРАВКА (ожидалась ячейка с 'Наименование')"); int sequentialNumber = startingNumber; for (int row = headerRow + 1; row <= sheet.LastRowUsed()?.RowNumber(); row++) { var cellB = sheet.Cell(row, 2).GetString().Trim(); if (string.IsNullOrWhiteSpace(cellB)) continue; // пропускаем пустые строки var item = new SpravkaItem { SequentialNumber = sequentialNumber++, Description = cellB, ProductCode = sheet.Cell(row, 5).GetString().Trim(), TnVed = sheet.Cell(row, 8).GetString().Trim(), CountryId = sheet.Cell(row, 11).GetString().Trim(), Country = sheet.Cell(row, 12).GetString().Trim(), Unit = sheet.Cell(row, 13).GetString().Trim(), Quantity = ParseDecimal(sheet.Cell(row, 14)), AmountWithVat = ParseDecimal(sheet.Cell(row, 15)), GrossWeight = ParseDecimal(sheet.Cell(row, 16)), NetWeight = ParseDecimal(sheet.Cell(row, 17)), RegNumber = sheet.Cell(row, 18).GetString().Trim(), RegDate = FormatDate(sheet.Cell(row, 19)), }; result.Add(item); } return result; } private static int FindHeaderRow(IXLWorksheet sheet) { int lastRow = Math.Min(sheet.LastRowUsed()?.RowNumber() ?? 200, 200); for (int r = 1; r <= lastRow; r++) { var val = sheet.Cell(r, 2).GetString(); if (val.Contains("Наименование", StringComparison.OrdinalIgnoreCase)) return r; } return -1; } private static decimal ParseDecimal(IXLCell cell) { try { if (cell.IsEmpty()) return 0; var val = cell.GetString().Trim().Replace(',', '.'); return decimal.TryParse(val, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var d) ? d : 0; } catch { return 0; } } private static string FormatDate(IXLCell cell) { if (cell.IsEmpty()) return ""; try { if (cell.DataType == XLDataType.DateTime) return cell.GetDateTime().ToString("dd.MM.yyyy"); } catch { } return cell.GetString().Trim(); } }