Search code examples
c#.net-coreopenxml

Open Xml how to get row and column details when reading excel in .Net core?


Hi I am trying to read excel using open xml using .Net core. I have below code and i am able to display cell value but what i am expecting is i want to read something like

row: 0 and column:0 and cellvalue: somevalue

So basically I would like to display cell value against each row and column details.

private DataTable ConvertExcelToDataTable(IFormFile uploadRegistration)
{
    //Create a new DataTable.
    var table = new DataTable();

    using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(uploadRegistration.OpenReadStream(), false))
    {
        WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
        IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
        Worksheet workSheet = worksheetPart.Worksheet;
        SheetData sheetData = workSheet.GetFirstChild<SheetData>();
        IEnumerable<Row> rows = sheetData.Descendants<Row>();
        foreach (Cell cell in rows.ElementAt(0))
        {
            table.Columns.Add(GetCellValue(spreadSheetDocument, cell));
        }
        foreach (Row row in rows)
        {
            DataRow tempRow = table.NewRow();
            for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
            {
                // tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
                Console.WriteLine(GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i))); // Here i am able to display cell value but not row and column details
            }
            table.Rows.Add(tempRow);
        }
    }
    table.Rows.RemoveAt(0);
    return table;
}

In the above code I am able to display cell value using but along with cell value corresponding row and column i would like to display, can someone please help me how can i access row and column. Any help would be appreciated Thanks

  Console.WriteLine(GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i)));

Solution

  • Cell has a property called CellReference which contains the cell address in the form "A1". From that you can calculate column and row index like this:

    public static (int row, int col) ParseCellAddress(string s)
    {
         StringBuilder stringBuilderCol = new StringBuilder();
         StringBuilder stringBuilderRow = new StringBuilder();
    
         foreach (char c in s)
         {
             if (char.IsLetter(c))
             {
                 if (stringBuilderRow.Length > 0)
                 {
                     throw new ArgumentException($"Invalid Cell adress {s}.");
                 }
    
                 stringBuilderCol.Append(c);
             }
             else if (char.IsDigit(c))
             {
                 if (stringBuilderCol.Length < 1)
                 {
                     throw new ArgumentException($"Invalid Cell adress {s}.");
                 }
    
                 stringBuilderRow.Append(c);
             }
             else
             {
                 throw new ArgumentException($"Invalid Cell adress {s}.");
             }
         }
    
         if (stringBuilderRow.Length == 0 || stringBuilderCol.Length == 0)
         {
             throw new ArgumentException($"Invalid Cell adress {s}.");
         }
    
         int rowIdx = int.Parse(stringBuilderRow.ToString());
    
         // calc column index from column name
    
         string columnName = stringBuilderCol.ToString();
    
         int colIdx = 0;
         int pow = 1;
         for (int i = columnName.Length - 1; i >= 0; i--)
         {
             colIdx += (columnName[i] - 'A' + 1) * pow;
             pow *= 26;
         }
    
         return (rowIdx, colIdx);
     }
    

    You can add it to your code like this:

     Cell cell = row.Descendants<Cell>().ElementAt(i);
     (int row, int col) res = ParseCellAddress(cell.CellReference);
    
     Console.WriteLine($"Row {res.row}, Col {res.col}, Value: {GetCellValue(spreadSheetDocument, cell)}");