Home » excel » c# – Retrieve "row pairs" from Excel

c# – Retrieve "row pairs" from Excel

Posted by: admin April 23, 2020 Leave a comment

Questions:

I am trying to retrieve data from an Excel spreadsheet using C#. The data in the spreadsheet has the following characteristics:

  • no column names are assigned

  • the rows can have varying column lengths

  • some rows are metadata, and these rows label the content of the columns in the next row

Therefore, the objects I need to construct will always have their name in the very first column, and its parameters are contained in the next columns. It is important that the parameter names are retrieved from the row above. An example:

row1|---------|FirstName|Surname|

row2|---Person|Bob------|Bloggs-|

row3|---------|---------|-------|

row4|---------|Make-----|Model--|

row5|------Car|Toyota---|Prius--|

So unfortunately the data is heterogeneous, and the only way to determine what rows “belong together” is to check whether the first column in the row is empty. If it is, then read all data in the row, and check which parameter names apply by checking the row above.
At first I thought the straightforward approach would be to simply loop through

1) the dataset containing all sheets, then
2) the datatables (i.e. sheets) and
3) the row.

However, I found that trying to extract this data with nested loops and if statements results in horrible, unreadable and inflexible code.
Is there a way to do this in LINQ ? I had a look at this article to start by filtering the empty rows between data but didn’t really get anywhere. Could someone point me in the right direction with a few code snippets please ?

Thanks in advance !
hiro

How to&Answers:

I see that you’ve already accepted the answer, but I think that more generic solution is possible – using reflection.

Let say you got your data as a List<string[]> where each element in the list is an array of string with all cells from corresponding row.

List<string[]> data;
data = LoadData();

var results = new List<object>();
string[] headerRow;

var en = data.GetEnumerator();
while(en.MoveNext())
{
    var row = en.Current;
    if(string.IsNullOrEmpty(row[0]))
    {
        headerRow = row.Skip(1).ToArray();
    }
    else
    {
        Type objType = Type.GetType(row[0]);
        object newItem = Activator.CreateInstance(objType);

        for(int i = 0; i < headerRow.Length; i++)
        {
            objType.GetProperty(headerRow[i]).SetValue(newItem, row[i+1]);
        }
        results.Add(newItem);
    }
}