#c# #excel #data-binding #epplus
#c# #excel #привязка данных #epplus
Вопрос:
Итак, я пытаюсь прочитать файл Excel и вставить данные в свойства класса. Я думаю, что возникает проблема, когда я создаю класс, однако я делаю это до того, как я разбираю и добавляю значения в класс.
После завершения синтаксического анализа я вызываю связанный класс, но он возвращает нули.
Вызовы
TestData td = new TestData();
XLReader.GetClassFromExcel<TestData>(1,1,1);
var ddddd = td.Title; //this is null.
Класс
public class TestData
{
public string Title { get; set; }
public string Site { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public string Email { get; set; }
public string OrderRef { get; set; }
public string ReqBy { get; set; }
public string ApprovedBy { get; set; }
}
Синтаксический анализ Excel
public static class XLReader
{
/// <summary>
/// The deployment files folder name
/// </summary>
private static readonly string deploymentFilesFolderName =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
public static List<T> GetClassFromExcel<T>(int fromRow, int fromColumn, int toColumn = 0)
{
var path = Path.Combine(deploymentFilesFolderName, @"ToolsTestData.xlsx");
List<T> retList = new List<T>();
using (var pck = new ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
//Retrieve first Worksheet
var ws = pck.Workbook.Worksheets.First();
//If the to column is empty or 0, then make the tocolumn to the count of the properties
//Of the class object inserted
toColumn = toColumn == 0 ? typeof(T).GetProperties().Count() : toColumn;
//Read the first Row for the column names and place into a list so that
//it can be used as reference to properties
List<string> columnNames = new List<string>();
// wsRow = ws.Row(0);
foreach (var cell in ws.Cells[1, 1, 1, ws.Cells.Count()])
{
columnNames.Add(cell.Value.ToString());
}
//Loop through the rows of the excel sheet
for (var rowNum = fromRow; rowNum <= ws.Dimension.End.Row; rowNum )
{
//create a instance of T
T objT = Activator.CreateInstance<T>();
//Retrieve the type of T
Type myType = typeof(T);
//Get all the properties associated with T
PropertyInfo[] myProp = myType.GetProperties();
var wsRow = ws.Cells[rowNum, fromColumn, rowNum, ws.Cells.Count()];
foreach (var propertyInfo in myProp)
{
if (columnNames.Contains(propertyInfo.Name))
{
int position = columnNames.IndexOf(propertyInfo.Name);
//To prevent an exception cast the value to the type of the property.
var blah = Convert.ChangeType(wsRow[rowNum, position 1].Value, propertyInfo.PropertyType);
propertyInfo.SetValue(objT,blah);
}
}
retList.Add(objT);
}
}
return retList;
}
}
Комментарии:
1.
var td = XLReader.GetClassFromExcel<TestData>(1,1,1)[0];
2. Спасибо @KooKiz, это работает. Следующим шагом для меня является то, как я получаю данные в классе, поэтому всякий раз, когда я вызываю TestData() . Сайт (в любом другом классе) вернет данные?
3. Разве вы не могли бы просто
td.Site
получить доступ к данным?
Ответ №1:
Когда я импортирую данные Excel, я всегда создаю массив строк для хранения значения с помощью этого кода
package.Load(fileContent.InputStream);
ExcelWorksheet workSheet = package.Workbook.Worksheets[1];
int totalRows = workSheet.Dimension.End.Row;
int totalCols = workSheet.Dimension.End.Column;
List<myObject> listMyObject = new List<myObject>();
for (int currentRow = 1; currentRow <= totalRows; currentRow )
{
string[] resultRow = new string[totalCols];
for (int currentCol = 1; currentCol <= totalCols; currentCol )
{
//We read the entire line and store it in the array
resultRow[currentCol - 1] = (workSheet.Cells[currentRow, currentCol].Value != null) ? workSheet.Cells[currentRow, currentCol].Value.ToString() : "";
}
//And now I can bind my array to my object
listMyObject.Add(myObjectHelper.Convert(resultRow));
}
//Here i've got my list object
В худшем случае мой массив будет содержать пустую строку. В этом случае я знаю, что в моем файле Excel ничего не было заполнено.
И после того, как я преобразовал свой массив строк в свой объект