open xml excel read cell value

后端 未结 5 1760
感动是毒
感动是毒 2020-11-27 05:24

I am using the Open XML SDK to open an Excel xlsx file and I try to read the cellvalue on position A1 in each sheet. I use the following code:

using (Spreads         


        
5条回答
  •  长情又很酷
    2020-11-27 05:55

    I found this post of reading entire excel data as a data table very helpful. It also uses open-xml sdk.

    using System;
    using System.Data;
    using System.Linq;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Spreadsheet;
    
    public static DataTable ReadAsDataTable(string fileName)
    {
        DataTable dataTable = new DataTable();
        using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(fileName, false))
        {
            WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
            IEnumerable sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild().Elements();
            string relationshipId = sheets.First().Id.Value;
            WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
            Worksheet workSheet = worksheetPart.Worksheet;
            SheetData sheetData = workSheet.GetFirstChild();
            IEnumerable rows = sheetData.Descendants();
    
            foreach (Cell cell in rows.ElementAt(0))
            {
                dataTable.Columns.Add(GetCellValue(spreadSheetDocument, cell));
            }
    
            foreach (Row row in rows)
            {
                DataRow dataRow = dataTable.NewRow();
                for (int i = 0; i < row.Descendants().Count(); i++)
                {
                    dataRow[i] = GetCellValue(spreadSheetDocument, row.Descendants().ElementAt(i));
                }
    
                dataTable.Rows.Add(dataRow);
            }
    
        }
        dataTable.Rows.RemoveAt(0);
    
        return dataTable;
    }
    
    private static string GetCellValue(SpreadsheetDocument document, Cell cell)
    {
        SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
        string value = cell.CellValue.InnerXml;
    
        if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
        {
            return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
        }
        else
        {
            return value;
        }
    }
    

    Note: There is an issue that while reading the excel it ignores the empty cells in each row. So this code is best fit when you are sure of that every cell in each row will have some data. If you want an appropriate handling for the same then you can do the following:

    Change the code of for loop :

    dataRow[i] = GetCellValue(spreadSheetDocument, row.Descendants().ElementAt(i));
    

    to

    Cell cell = row.Descendants().ElementAt(i);
    int actualCellIndex = CellReferenceToIndex(cell);
    dataRow[actualCellIndex] = GetCellValue(spreadSheetDocument, cell);
    

    and add below method which is used in the above modified code snippet:

    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;
    }
    

    I got this fix from this answer.

提交回复
热议问题