【问题标题】:OpenXML linq queryOpenXML linq 查询
【发布时间】:2012-02-13 17:08:04
【问题描述】:

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

让我在这里重申一下:我需要的是返回所有单元格,而不仅仅是包含值的单元格

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

【问题讨论】:

    标签: linq openxml openxml-sdk closedxml


    【解决方案1】:

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

    1. 创建所有“可用”或“可能”单元格的列表(可能通过使用CROSS JOIN 类型的操作)然后“左”加入row.Descendants&lt;Cell&gt;() 集合以查看单元格引用是否具有值李>
    2. 使用 3rd 方工具(例如 ClosedXMLEPPlus)作为 Excel 数据的包装器并查询其接口,这对开发人员更加友好。

    【讨论】:

    • 我使用 ClosedXML 导出 Excel 电子表格,但我认为它根本没有导入。可以?今天早些时候,我什至在他们的网站上快速浏览了一下,但没有看到它确实如此(尽管它是一个非常快速的浏览)。不过,我会看看 EPPlus。确实,每次我尝试使用 OpenXML 做任何事情时,我都会惊讶于看似简单的事情最终却变成了任何事情!
    • 如果导入是指读取和写入数据的能力,那么 OpenXML 和 EPPlus 都可以做到。我同意直接用 OpenXML 做任何事情是一件非常痛苦的事情,但是使用上述工具和作为 SDK 一部分的文档资源管理器,它比我们过去必须处理的旧 COM 互操作要好得多!跨度>
    • ClosedXML 效果很好。我希望我从一开始就使用它,而不是使用 OpenXML。再次感谢!
    【解决方案2】:

    使用 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
          // ...
       }
    }
    

    【讨论】:

    • 啊,这么多的努力浓缩成这么少的代码。谢谢
    【解决方案3】:

    我推荐的一种方法是用空白数据填充所有空单元格,以便您的 linq 语句返回它们。请参阅此answer 了解如何执行此操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-03
      • 2016-01-31
      • 1970-01-01
      • 2020-06-10
      相关资源
      最近更新 更多