使用OpenXML在数据集中导入Excel时,“对象引用未设置为对象的实例”

时间:2019-07-19 06:40:42

标签: c# excel dataset openxml

我正在Windows应用程序上工作,我在可能包含多个图纸的数据集文件中一个接一个地导入多个Excel文件。 我为此使用OpenXML,目前,当只有一个excel文件时,它可以很好地工作,但是在导入多个excel时却出现异常,我得到“对象引用未设置为对象的实例”。

这是我使用的方法

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
*/

1 个答案:

答案 0 :(得分:1)

之所以抛出NullReferenceException是因为在您已经标记的代码行中,rows.ElementAtOrDefault(0)返回了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),它可以返回null,因此不应在foreach循环中使用。

此外,Cell cell in rows.ElementAtOrDefault(0)不是一个好习惯,并且可能导致其他问题。在这种情况下,Row实例可以同时包含CellExtensionList子实例,这可能导致类型转换异常。