1

我需要从 excel 电子表格中读取值并将值保存到数据库中。我此时似乎遇到的问题是访问行对象中列中的各个值

http://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.cellvalue.aspx

var cellValues = from cell in row.Descendants<Cell>()
                                                     select (cell.DataType != null && cell.DataType.HasValue && cell.DataType == CellValues.SharedString
                                                       && int.Parse(cell.CellValue.InnerText) < sharedString.ChildElements.Count 
                                                        ? sharedString.ChildElements[int.Parse(cell.CellValue.InnerText)].InnerText 
                                                        : cell.CellValue.InnerText);

不幸的是,上面的代码似乎没有完成这项工作,因为它在运行时会引发异常,因此寻找有关如何使用 OpenXML 访问 Excel Row 对象中包含的值的最佳想法。

+$exception {"对象引用未设置为对象的实例。"} System.Exception {System.NullReferenceException}

生成的 StackTrace

   at MOC.Import.Products.<ProcessRows>b__0(Cell cell) in c:\Development\CFrontEnd\MOC.Import\Products.cs:line 37
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
   at MOC.Import.Products.ProcessRows(IEnumerable`1 dataRows, SharedStringTable sharedString) in c:\Development\CFrontEnd\MOC.Import\Products.cs:line 45
4

1 回答 1

1

您引用的对象之一为空。找到导致问题的特定对象的最简单方法是从 LINQ 表达式中取出过滤和格式化代码,然后遍历单元格:

var cellValues = from cell in row.Descendants<Cell>()
                    select cell;

foreach (var cell in cellValues)
{
    if(cell.DataType != null 
        && cell.DataType.HasValue 
        && cell.DataType == CellValues.SharedString
        && int.Parse(cell.CellValue.InnerText) < sharedString.ChildElements.Count)
    {
        DoSomething(sharedString.ChildElements[int.Parse(cell.CellValue.InnerText)].InnerText);
    }
    else
    {
        DoSomething(cell.CellValue.InnerText);
    }
}

使用这种结构,很容易在调试器中检测到问题。您还可以进一步展开此代码并添加更多针对空值的防护措施,以使您的代码更加健壮。简而言之,您的问题是您对正在阅读的文档的结构做出了无效的假设。作为一般规则,假设是不好的,尤其是当它们是关于您无法完全控制的输入的假设时。

于 2012-09-26T22:13:58.110 回答