Search code examples
c#excelasp.net-coreopenxmliformfile

C# open xml unable to read string values


Hi I am using open xml to read excel in my .Net application. I have method which accepts row and columns as input parameters and returns value for that particular cell. Below is my implementation.

public List<ServicePortDto> GetServicePorts(IFormFile formFile, Dictionary<string, int> starRowForPorts)
{
    using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(formFile.OpenReadStream(), false))
    {
        WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
        List<int> portRows = new();
        int counter = 0;
        IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
        foreach (var sheet in sheets)
        {
            int startRowPort = starRowForPorts.Where(x=>x.Key == sheet.Name.Value).Select(x => x.Value).FirstOrDefault();
            string relationshipId = sheet.Id.Value;
            WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
            Worksheet workSheet = worksheetPart.Worksheet;
            SheetData sheetData = workSheet.GetFirstChild<SheetData>();
            IEnumerable<Row> rows = sheetData.Descendants<Row>();
            rows = rows.Where(x=>x.RowIndex >= startRowPort);
            foreach (Row row in rows)
            {
                if(row.RowIndex >= startRowPort)
                {
                    string portName = GetCell(workSheet, "B", startRowPort).InnerText;

                    if (portName != null)
                    {
                        counter = counter + 1;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
    }
    return new List<ServicePortDto>();
}

Below is GetCell method.

private static Cell GetCell(Worksheet worksheet, string columnName, int rowIndex)
{
    Row row = worksheet.GetFirstChild<SheetData>().Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);

    if (row != null)
    {
        return row.Elements<Cell>().FirstOrDefault(c => string.Compare(c.CellReference.Value, columnName + rowIndex, true) == 0);
    }
    return null;
}

The problem is with above method is if there is any string data in cell then it reads as some integer. I am not sure why this is happening. Integer values reads properly. Only issue with String/Text fields. May I know what I am missing here? Can someone please help me with this? Any help would be appreciated. Thanks


Solution

  • In Open XML, cell values are stored as shared strings or directly as inline strings, and you need to handle them accordingly.

    private static string GetCellValue(Cell cell, SharedStringTablePart stringTablePart)
    {
        if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
        {
            if (stringTablePart != null)
            {
                SharedStringItem sharedStringItem = stringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(int.Parse(cell.InnerText));
                return sharedStringItem.Text?.Text;
            }
        }
        else if (cell.CellValue != null)
        {
            return cell.CellValue.Text;
        }
        return null;
    }