У меня есть файл, из которого необходимо заполнить базу данных. Структура файла сложная(например, значение ячейки С6 зависит от Company name1, Type1, Section1). Как его распарсить чтобы заполнить бд данными? Для работы с excel я использую npoi.
получаем лист и файл и передаем функции по обработке эксель
private void SelectTableFromExcel(int year)
{
var openFile = OpenFile();
var excelWorksheets = GetExcelWorksheet(openFile);
TableFromExcel(excelWorksheets, "номер последней колонки");
}
выбираем и открываем файл
private OpenFileDialog OpenFile()
{
var openFile = new OpenFileDialog
{
Title = @"Выберите файл",
Filter = @"Файлы Excel|*.xls;*.xlsx",
FilterIndex = 1,
RestoreDirectory = true
};
return openFile.ShowDialog() != true ? null : openFile;
}
получаем первый лист из выбранного файла
private ExcelWorksheet GetExcelWorksheet(OpenFileDialog openFile)
{
var package = new ExcelPackage(new FileInfo(openFile.FileName));
var excelWorksheets = package.Workbook.Worksheets[1];
return excelWorksheets;
}
основная функция для работы с эксель
private void TableFromExcel(ExcelWorksheet excelWorksheet, string numberCol)
{
var rangeExcel = GetRangeExcel(excelWorksheet);
var lastColRange = GetLastColumnExcel(excelWorksheet, numberCol);
var nullsRowFromExcel = GetNullRowFromExcel(excelWorksheet, rangeExcel);
LoadDataFromExcel(excelWorksheet, rangeExcel, nullsRowFromExcel, lastColRange);
}
получаем ячейку, откуда начинают идти данные
private ExcelCellAddress GetRangeExcel(ExcelWorksheet excelWorksheets)
{
return excelWorksheets.Cells[1, 1, excelWorksheets.Dimension.Rows, excelWorksheets.Dimension.Columns]
.First(c => c.Value != null && c.Value?.ToString().Length != 0 && c.Value.ToString().Contains("Company name1"))
?.Start;
}
получаем ячейку по последнему столбцу
private ExcelCellAddress GetLastColumnExcel(ExcelWorksheet excelWorksheet, string numberColumn)
{
return excelWorksheet.Cells[1, 1, excelWorksheet.Dimension.Rows, excelWorksheet.Dimension.Columns]
.First(c => c.Value != null && c.Value?.ToString().Length != 0 && c.Value.ToString().Contains(numberColumn))
?.Start;
}
получаем нулевые строки, чтобы дальше их пропускать
private List<int> GetNullRowFromExcel(ExcelWorksheet excelWorksheet, ExcelCellAddress rangeExcel)
{
var nullRowFromExcel = new List<int>();
for (var i = rangeExcel.Row; i <= excelWorksheet.Dimension.Rows; i++)
if (excelWorksheet.Cells[i, rangeExcel.Column - 1].Value == null)
nullRowFromExcel.Add(i);
return nullRowFromExcel;
}
считываем данные из эксель
private void LoadDataFromExcel(ExcelWorksheet excelWorksheet, ExcelCellAddress rangeExcel, List<int> nullsRowFromExcel, ExcelCellAddress lastColRange)
{
var rowWithAllCollumn = new List<string>();
for (var i = rangeExcel.Row; i <= excelWorksheet.Dimension.Rows; i++)
{
rowWithAllCollumn.Clear();
for (var j = rangeExcel.Column - 2; j <= lastColRange.Column; j++)
{
if (j == rangeExcel.Column - 1 || j > rangeExcel.Column)
{
rowWithAllCollumn.Add(excelWorksheet.Cells[i, j].Value == null ? "0" : excelWorksheet.Cells[i, j].Value.ToString());
}
else
{
rowWithAllCollumn.Add(null);
}
}
if (nullsRowFromExcel.Contains(i)) continue;
//_plansEntities это dataContext в entity framework, LoadPlanMZTemps моя таблица,куда надо грузить данные
_plansEntities.LoadPlanMZTemps.Add(ChangesListToModel(rowWithAllCollumn, lastColRange.Column));
_plansEntities.SaveChanges();
}
}
тут уже вставляем в таблицу данные
private LoadPlanMZTemp ChangesListToModel(List<string> rowWithAllCollumn, int lastColumn)
{
//моя модель из ef
var objPlan = new LoadPlanMZTemp();
var descr = TypeDescriptor.GetProperties(objPlan);
var index = 0;
foreach (PropertyDescriptor property in descr)
{
if (index < lastColumn)
{
switch (property.Name)
{
case "id":
continue;
default:
property.SetValue(objPlan, System.Convert.ToDecimal(rowWithAllCollumn[index]));
break;
}
index++;
}
else break;
}
return objPlan;
}
Я для работы с Excel
использую EpPlus
, но я уверен, что принцип работы один и тот же.
Как я понимаю, формат вам заранее известен => идете как по двумерному массиву и постепенно заполняете DataTable
:
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Имеется такая строчка в методе на il: "IL_0007: ret"Что это значит ? (Понятно, что это связано с окончанием метода, но как конкретно)
Пытаюсь по нажатию кнопки обработать все строки в гридеВ моем случае есть грид с сообщениями
Имеется сервис, который собирает данные и отправляет в другой сервисСервис работает в докер-контейнере