2012-01-18 52 views
3

我使用OpenXML打开电子表格并循环显示电子表格的行。我有一个linq查询返回一行内的所有单元格。 linq查询直接从MSDN上的演示中剥离。OpenXML linq查询

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查询的工作方式是只返回给定行有值的单元格。因此,如果有一行数据具有“John”,“”,“173 Sycamore”,那么linq查询只会在枚举中返回“John”和“173 Sycamore”,这反过来使我无法知道是否“173 Sycamore”是SSN或地址字段。

让我在这里重申:我需要的是返回所有单元格,而不仅仅是包含值的单元格。我试图以我能想到的每种方式来捣乱linq查询,但我没有任何运气(即 - 删除where子句不是诀窍)。任何帮助,将不胜感激。谢谢!

回答

4

OpenXML标准没有为没有数据的单元定义占位符。换句话说,它在XML中的底层存储是稀疏的。你可以工作,这一轮的两种方法之一:

  1. 创建所有“可用”或“可能”小区的名单(可能通过使用CROSS JOIN类型的操作),那么“左”加入到row.Descendants<Cell>()集合查看单元格引用是否具有值
  2. 利用第三方工具(如ClosedXMLEPPlus)作为Excel数据的包装并查询它们的接口,这些接口对开发人员更友好。
+0

我已经使用ClosedXML导出Excel电子表格,但我并不认为它确实导入了。可以?今天早些时候,我甚至在他们的网站上看到了真正的快速,并没有看到它的确如此(尽管这是一个非常快速的样子)。不过我会看看EPPlus。实际上,每次我尝试使用OpenXML做任何事情时,我都惊讶于看起来应该简单的事情,但最终却变成了一切! – Jagd 2012-01-19 00:22:08

+0

如果通过导入您的意思是读取和写入数据的能力,那么OpenXML和EPPlus都可以这样做。我同意试图直接使用OpenXML是一件痛苦的事情,但是使用上述工具和Document Explorer作为SDK的一部分,它比我们以前必须处理的旧的COM Interop要好得多! – jklemmack 2012-01-19 02:31:33

+1

ClosedXML效果很好。我希望从第一个开始就使用它,而不是使用OpenXML。再次感谢! – Jagd 2012-01-23 18:19:18

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 
     // ... 
    } 
} 
+0

太棒了!我会检查出来的! – Jagd 2012-01-19 15:07:15

+0

啊,这么多努力凝结了这么少的代码。谢谢 – 2016-03-10 11:15:57

0

我推荐的一种方式是填补所有空细胞与空白数据,因此他们会通过你的LINQ语句返回。请参阅answer了解如何操作。