'Object reference not set to an instance of an object' 使用 OpenXML 在数据集中导入 excel 时

'Object reference not set to an instance of an object' while importing excel in dataset using OpenXML

我正在开发 windows 应用程序,我在其中将多个 excel 文件一个一个地导入到可能包含多个工作表的数据集文件中。 我正在为此使用 OpenXML,目前,它在只有一个 excel 文件时工作正常,但在导入多个 excel 时出现异常,我遇到了 "Object reference not set to an instance of an object." 异常。

这是我使用的方法

internal DataSet GetDataFromExcelsxFile(string filePath)
{
    try
    {
        KeywordFiles objKeywordFilesController = new KeywordFiles();
        DataSet ds = new DataSet();
        using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filePath, false))
        {

            WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
            IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
            foreach (var item in sheets)
            {
                DataTable dt = new DataTable();
                string relationshipId = item.Id.Value;
                WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
                Worksheet workSheet = worksheetPart.Worksheet;
                SheetData sheetData = workSheet.GetFirstChild<SheetData>();
                IEnumerable<Row> rows = sheetData.Descendants<Row>();

                /*Exception getting on this loop start*/
                foreach (Cell cell in rows.ElementAtOrDefault(0))
                {
                    dt.Columns.Add(GetCellValue(spreadSheetDocument, cell));
                }

                foreach (Row row in rows) //this will also include your header row...
                {
                    DataRow tempRow = dt.NewRow();

                    for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
                    {
                        tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
                    }

                    dt.Rows.Add(tempRow);
                }
                dt.Rows.RemoveAt(0);
                ds.Tables.Add(dt);

            }
        }

        return ds

    }
    catch (Exception ex)
    {
        Logger.LogInfo(DateTime.Now.ToLongTimeString() + "\n" + "Exception occured to - " + fullName + " \n: " + ex.Message);
        //DialogResult dr = RadMessageBox.Show("Exception occured to - " + fullName + " \n: " + ex.Message, "Error Alert", MessageBoxButtons.OK, RadMessageIcon.Error);

    }

}

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

/* Exception getting on this loop start

     foreach (Cell cell in rows.ElementAtOrDefault(0))
                {
                    dt.Columns.Add(GetCellValue(spreadSheetDocument, cell));
                }

i tried rows.ElementAt(0) instead of rows.ElementAtOrDefault(0) but still getting same exception
*/

NullReferenceException 被抛出是因为,在您已经标记的代码行中,rows.ElementAtOrDefault(0) returns null。如果 SheetData 实例不包含任何 Row 个实例,就会发生这种情况。

IEnumerable<Row> rows = sheetData.Descendants<Row>();

/*Exception getting on this loop start*/
foreach (Cell cell in rows.ElementAtOrDefault(0))
{
    // Loop body removed
}

您的代码永远不应抛出 NullReference 异常。在这种情况下,罪魁祸首是术语 rows.ElementAtOrDefault(0),它可以 return null,因此不应在 foreach 循环中使用。

此外,Cell cell in rows.ElementAtOrDefault(0) 不是一个好的做法,可能会导致更多问题。在这种情况下,Row 实例可以同时包含 CellExtensionList 子实例,这会导致类型转换异常。