关于 openxml:使用 Excel 数据阅读器 (.Net) 读取 XLSX 时出现意外的空成员

Unexpected null members when reading XLSX with Excel Data Reader (.Net)

我正在使用来自 http://exceldatareader.codeplex.com/ 的 Excel 数据阅读器读取 XLSX(Microsoft Excel XML 文件),并且遇到了丢失数据的问题。库返回的数据集中缺少源 Excel 电子表格中的数据。

这里有一些关于我正在做的事情的详细信息:

  • 在 Excel 中创建了一个简单的测试电子表格,其中包含一个工作表、一个标题行和两个数据行。保存并关闭 Excel。
  • 打开文件并将流传递到 CreateOpenXmlReader() 方法并取回 IExcelDataReader。
  • 在 IExcelDataReader 上调用 AsDataSet() 方法并返回一个 DataSet。
  • 从表 0 的第 1 行获取 ItemArray。
  • 循环遍历 ItemArray。发现缺少数据(即在我期望 System.string 成员的地方有 System.DBNull 成员)。
  • 这里有更多的分析...

    我调试了代码并查看了 ExcelDataReader 对象模型的内部。找到一个名为 "SST" 的非公共字符串数组,它似乎包含电子表格中的数据作为单个线性(一维)数组。

    经过仔细检查,我发现我正在寻找的数据也从这个数组中丢失了。在这个原始数据中,该成员根本不存在。

    我的猜测是,由于某种原因,解析器没有从 OOXML 中提取数据并得出单元格为空的结论。查看 OOXML 本身,数据似乎被拆分为 sharedStrings.xml 和 sheet1.xml 文件,因此解析器可能很难将所有这些放在一起。

    以二进制格式(Excel 97 到 2003)保存文件并读取它可以解决问题,所以表面上似乎证实了我的怀疑是读取 OOXML 格式。

    建议?

    作为权宜之计,我正在将所有文件都转换为二进制格式,但这似乎是个麻烦事。有什么方法可以让我的 OOXML 格式的 Excel 文件使用 Excel 数据阅读器正确读取?


    要检索 Excel 电子表格 (.xlsx) 并将其加载到数据集中,您无需使用 XML 阅读器或 Excel 数据阅读器等单独的库。在 .NET 中使用普通的 OleDb 函数时,将整个电子表格读入 DataSet 的代码非常简单:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    Sub readInMyExcelFile

    Dim xlsFile as string ="myexcelfile"
    Dim conStr As String ="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & xlsFile &";Extended Properties=""Excel 12.0 Xml;HDR=YES"""

    Dim dtSheets As New DataTable
    Dim tmp As String
    Dim sqlText as Sting        

    Using cn As New OleDbConnection(conStr)
      cn.Open()
      dtSheets = cn.GetSchema("Tables")
    End Using

    //Dataset for the spreadsheet
    Dim ds as New DataSet  

    /Loop through the names of all the worksheets in the file.
    For Each rw as DataRow in dtSheets.Rows
      tmp = rw("TABLE_NAME")
      tmp ="[" & tmp &"]"

      Dim dt as New DataTable

      Using cn as New OleDbConnection(conStr)
        cn.Open
        /Retrieve all the records from the worksheet.
        sqlText ="SELECT * FROM" & tblName

        Dim adp As New OleDbDataAdapter(sqlText, cn)

        /Fill the data table with the all the data.
        adp.Fill(dt)
      End Using

      ds.Tables.Add(dt)
    Next

    End Sub

    codeplex 的 excel 数据读取器用于直接在 Web 应用程序上从 excel 文件中读取数据,而无需在服务器上进行任何类型的缓存。上面的代码仅在我们可以将 excel 文件存储在某处时才有效。我遇到过与 exceldatareader 类似的问题缺少某些数据的地方。最重要的是,我没有找到任何特定的趋势。我只是看到,如果所有行都有值,那么就没有问题。最好的机会是将 xlsx 转换为 xls。


    Excel数据阅读器似乎有一个错误(这是我第一次听说)。你必须使用它吗?如果没有,EPPlus 会是更好的选择。