OpenXML linq查询

时间:2012-01-18 23:57:33

标签: linq openxml openxml-sdk closedxml

我使用OpenXML打开电子表格并循环遍历电子表格的各行。我有一个linq查询返回一行中的所有单元格。 linq查询直接从MSDN上的演示中删除。

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

linq查询非常适合返回具有值的所有单元格,但它不会返回没有值的单元格。这反过来使得无法分辨哪个细胞是哪个细胞。让我再解释一下。比如说我们的电子表格中有三列:名称,SSN和地址。此linq查询的工作方式是它仅返回具有给定行的值的单元格。因此,如果有一行数据包含&#34; John&#34;,&#34;&#34;,&#34; 173 Sycamore&#34;然后linq查询只返回&#34; John&#34; &#34; 173 Sycamore&#34;在枚举中,这反过来使我无法知道&#34; 173 Sycamore&#34;是SSN或地址字段。

我在此重申:我需要的是返回所有单元格,而不仅仅是包含值的单元格。

我试图以我能想到的各种方式来追踪linq查询,但我没有任何运气(即 - 删除where子句不是诀窍)。任何帮助,将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:4)

OpenXML标准没有为没有数据的单元格定义占位符。换句话说,它在XML中的底层存储是稀疏的。您可以通过以下两种方式之一解决此问题:

  1. 创建所有“可用”或“可能”单元格的列表(可能使用CROSS JOIN类型的操作)然后“左”加入row.Descendants<Cell>()集合以查看单元格引用是否具有值
  2. 利用第三方工具(例如ClosedXMLEPPlus)作为Excel数据的包装并查询其界面,这些界面更适合开发人员。

答案 1 :(得分:3)

使用ClosedXML:

var wb = new XLWorkbook("YourWorkbook.xlsx");
var ws = wb.Worksheet("YourWorksheetName");
var range = ws.RangeUsed();
foreach(var row in range.Rows())
{
   // Do something with the row...
   // ...

   foreach(var cell in row.Cells())
   {
      // Now do something with every cell in the row
      // ...
   }
}

答案 2 :(得分:0)

我建议的一种方法是用空白数据填充所有空单元格,这样它们将由你的linq语句返回。有关如何执行此操作,请参阅此answer