If there were data in all cells in a row, then everything works well. At the moment when you have at least one empty cell in a row, things are going badly.
Why is this happening in the first place ?
This is because in the code below:
row.Descendants<Cell>().Count()
Count()
is the number of non-empty filled cells (not all columns). So, when you pass row.Descendants<Cell>().ElementAt(i)
as an argument to the GetCellValue
method:
GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
Then it will find the contents of the next non-empty filled cell (not necessarily what is in the index of this column, i
), for example, if the first column is empty and we call ElementAt(1)
, instead it returns the value in the second column. and all logic is confused.
Decision. We need to deal with the appearance of empty cells . In fact, we need to find out the initial index of the cell column in case there were empty cells in front of it. So you need to replace your loop code as below:
for (int i = 0; i < row.Descendants<Cell>().Count(); i++) { tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i)); }
with
for (int i = 0; i < row.Descendants<Cell>().Count(); i++) { Cell cell = row.Descendants<Cell>().ElementAt(i); int actualCellIndex = CellReferenceToIndex(cell); tempRow[actualCellIndex] = GetCellValue(spreadSheetDocument, cell); }
and add the method below to your code, which is used in the above fragment of the modified code to get the source / correct column index of any cell:
private static int CellReferenceToIndex(Cell cell) { int index = 0; string reference = cell.CellReference.ToString().ToUpper(); foreach (char ch in reference) { if (Char.IsLetter(ch)) { int value = (int)ch - (int)'A'; index = (index == 0) ? value : ((index + 1) * 26) + value; } else return index; } return index; }