如何在c#中使用OpenXML读取excel的空白单元格列值

时间:2022-06-10 19:55:05

Here in my Execl Sheet there are some blank value column cell, so When I use This code then in get Error "Object reference not set to an instance of an object".

在我的Execl表中,有一些空白的值列单元格,因此当我使用这个代码时,会出现错误“对象引用没有设置为对象的实例”。

foreach (Row row in rows)
{
   DataRow dataRow = dataTable.NewRow();
   for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
   {
        dataRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
   }

   dataTable.Rows.Add(dataRow);
}

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

1 个解决方案

#1


1  

The "CellValue" don't necessarily exist. In your case it is "null", so you have your error. To read your blank cell :

“CellValue”并不一定存在。在你的例子中,它是空的,所以你有你的错误。阅读你的空白单元格:

If you don't want format the result depending what the cell contain, try

如果您不希望根据单元格包含的内容格式化结果,请尝试

private static string GetCellValue(Cell cell)
{
    return cell.InnerText;
}

if you want to format your cell before returning the value of it

如果您想在返回单元格值之前格式化它

private static string GetCellValue(SpreadsheetDocument doc, Cell cell)
{
    // if no dataType, return the value of the innerText of the cell
    if (cell.DataType == null) return cell.InnerText;

    // depending type of the cell
    switch (cell.DataType.Value)
    {
        // string => search for CellValue
        case CellValues.String:
            return cell.CellValue != null ? cell.CellValue.Text : string.Empty;

        // inlineString => search of InlineString
        case CellValues.InlineString:
            return cell.InlineString != null ? cell.InlineString.Text.Text : string.Empty;

        // sharedString => search for the SharedString
        case CellValues.SharedString:
            // is sharedPart exist ?
            if (doc.WorkbookPart.SharedStringTablePart == null) doc.WorkbookPart.SharedStringTablePart = new SharedStringTablePart();
            // is the text exist ?
            foreach (SharedStringItem item in doc.WorkbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>())
            {
                // the text exist, return it from SharedStringTable
                if (item.InnerText == cell.InnerText) return cell.InnerText;
            }
            // no text in sharedStringTable, create it and return it
            doc.WorkbookPart.SharedStringTablePart.SharedStringTable.Append(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(cell.InnerText)));
            doc.WorkbookPart.SharedStringTablePart.SharedStringTable.Save();
            return cell.InnerText;

        // default case : bool / number / date
        // return the value of the cell in plain text
        // you can parse types depending your needs
        default:
            return cell.InnerText;
    }
}

Two usefull documentations:

两个有用文件:

#1


1  

The "CellValue" don't necessarily exist. In your case it is "null", so you have your error. To read your blank cell :

“CellValue”并不一定存在。在你的例子中,它是空的,所以你有你的错误。阅读你的空白单元格:

If you don't want format the result depending what the cell contain, try

如果您不希望根据单元格包含的内容格式化结果,请尝试

private static string GetCellValue(Cell cell)
{
    return cell.InnerText;
}

if you want to format your cell before returning the value of it

如果您想在返回单元格值之前格式化它

private static string GetCellValue(SpreadsheetDocument doc, Cell cell)
{
    // if no dataType, return the value of the innerText of the cell
    if (cell.DataType == null) return cell.InnerText;

    // depending type of the cell
    switch (cell.DataType.Value)
    {
        // string => search for CellValue
        case CellValues.String:
            return cell.CellValue != null ? cell.CellValue.Text : string.Empty;

        // inlineString => search of InlineString
        case CellValues.InlineString:
            return cell.InlineString != null ? cell.InlineString.Text.Text : string.Empty;

        // sharedString => search for the SharedString
        case CellValues.SharedString:
            // is sharedPart exist ?
            if (doc.WorkbookPart.SharedStringTablePart == null) doc.WorkbookPart.SharedStringTablePart = new SharedStringTablePart();
            // is the text exist ?
            foreach (SharedStringItem item in doc.WorkbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>())
            {
                // the text exist, return it from SharedStringTable
                if (item.InnerText == cell.InnerText) return cell.InnerText;
            }
            // no text in sharedStringTable, create it and return it
            doc.WorkbookPart.SharedStringTablePart.SharedStringTable.Append(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(cell.InnerText)));
            doc.WorkbookPart.SharedStringTablePart.SharedStringTable.Save();
            return cell.InnerText;

        // default case : bool / number / date
        // return the value of the cell in plain text
        // you can parse types depending your needs
        default:
            return cell.InnerText;
    }
}

Two usefull documentations:

两个有用文件: