【问题标题】:OpenXML SDK2.5 (Excel): How to determine if a cell contains a numeric value?OpenXML SDK2.5 (Excel):如何判断单元格是否包含数值?
【发布时间】:2017-02-22 11:55:57
【问题描述】:

我正忙于开发一个从 MS Excel (2016) 文件中导入数据的组件。 该组件使用 MS OpenXML SDK2.5 库。 MS Excel 的最终用户安装基于荷兰国家/地区设置。 除其他外,该文件包含一个包含财务数据(数字)的列。此列的位置事先不知道。

为了确定一个单元格是否包含数字数据,我评估了属性 Cell.DataType(CellValues 类型,它是一个枚举)。 起初,该属性似乎是确定这一点的完美候选者。 CellValues 的可能值为: 布尔值、数字、错误、共享字符串、字符串、内联字符串或日期。所以我希望 Cell.DataType 设置为 CellValues.Number。 经过一些调试,我发现当单元格包含数字数据时,Cell.DataType 为空。

在互联网上搜索以查找解释时,我发现了以下 MSDN 文章: https://msdn.microsoft.com/en-us/library/office/hh298534.aspx

这篇文章准确地描述了我在调试过程中发现的内容:

Cell 类型提供了一个 DataType 属性,该属性指示单元格内数据的类型。对于数字和日期类型,DataType 属性的值为 null。

有人知道为什么 Cell.DataType 没有分别用 CellValues.Number 或 CellValues.Date 初始化吗?

确定单元格是否包含数值的最佳方法是什么?

【问题讨论】:

    标签: c# excel openxml-sdk


    【解决方案1】:

    有人知道为什么 Cell.DataType 没有分别用 CellValues.Number 或 CellValues.Date 初始化吗?

    查看here 的 ECMA-376 标准,Cell 的(缩写)XSD 如下所示:

    <xsd:complexType name="CT_Cell">
        ...
        <xsd:attribute name="t" type="ST_CellType" use="optional" default="n"/>
        ...
    </xsd:complexType>
    

    该属性表示类型。请注意,它是可选的,默认值为"n"。第 18.18.11 节 ST_CellType(细胞类型)列出了该类型的有效值:

    b - 布尔值
    d - 日期
    e - 错误
    inlineStr - 内联字符串
    n - 数字(默认)
    s - 共享字符串 str - 公式字符串

    你可以看到"n"代表一个number

    确定单元格是否包含数值的最佳方法是什么?

    从上面看来,您可以检查CellValues.Number 中的Cell.DataTypeCell.DataType 是否为空,以判断单元格是否包含数字,但这并不是那么简单——最大的问题是日期。

    似乎最初的日期存储机制是使用数字并依靠样式来知道数字是否实际上是数字或数字是否代表日期。

    令人困惑的是,规范已更新为包含Date 类型,但并非所有日期都将使用日期类型Date 类型表示单元格包含 ISO 8601 格式的日期,但将日期存储为具有正确样式的数字是完全有效的。例如,以下 XML sn-p 以 NumberDate 格式显示相同的日期(2017 年 2 月 1 日):

    <sheetData>
        <row r="1" spans="1:1" x14ac:dyDescent="0.25">
            <c r="A1" s="1">
                <v>42767</v>
            </c>
        </row>
        <row r="2" spans="1:1" x14ac:dyDescent="0.25">
            <c r="A2" s="1" t="d">
                <v>2017-02-01</v>
            </c>
        </row>
    </sheetData>
    

    在 Excel 中打开时如下所示:

    如果您需要区分日期和数字,那么您需要找到任何数字(null Cell.DataTypeCellValues.NumberCell.DataType),然后检查这些单元格的样式以确保它们是数字而不是数字伪装成数字的日期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-10
      • 1970-01-01
      • 2018-10-26
      • 2019-08-17
      相关资源
      最近更新 更多