判断Excel 2007电子表格中xlsx单元格是否为日期格式

2 投票
2 回答
3834 浏览
提问于 2025-04-16 11:31

我正在处理一些代码,这些代码通过解析xml来读取xlsx文件中的数据。整体过程都挺简单的,唯一复杂的地方是日期单元格。

日期是以整数形式存储的,并且有一个“s”属性,这个属性是样式表中的一个索引,可以用来获取日期格式字符串。以下是之前在StackOverflow上提到的一些例子:

19 = 'h:mm:ss AM/PM';

20 = 'h:mm';

21 = 'h:mm:ss';

22 = 'm/d/yy h:mm';

这些是ooxml标准中内置的日期格式字符串,不过看起来Excel通常会使用自定义的格式字符串,而不是这些内置的。下面是一个来自Excel 2007电子表格的格式示例。numFmtId大于164的就是自定义格式。

<numFmt formatCode="MM/DD/YY" numFmtId="165"/>

判断一个单元格是否应该格式化为日期是比较困难的,因为我能找到的唯一指示就是formatCode。这个显然是一个日期,但单元格的格式可能有很多种。我最初的尝试是查找formatCode中的M、D和Y,但这似乎有点问题。

有没有人解决过这个问题?目前看起来标准的Excel读取库在xlsx支持方面有些不足。我已经阅读了相关标准,并且翻阅了很多xlsx文件,但没有太大进展。

看起来最好的信息来自于这个StackOverflow的问题:

什么表示一个Office Open XML单元格包含日期时间值

谢谢!

2 个回答

0

仅仅寻找数字格式代码中的Ms、Ds和Ys是不够的。

[Red]#,##0 ;[Yellow](#,##0)

这个格式是完全有效的数字格式,它同时包含Y和D,但它并不是日期格式。我特别检查了所有标准的日期/时间格式字符('y'、'm'、'd'、'H'、'i'、's'),这些字符是在方括号('[' ']')之外的。即便如此,我发现还是有一些错误的情况出现,主要和会计和货币格式有关。因为这些格式通常以一个下划线('_')或一个空格后面跟着零(' 0')开头(而这些在日期格式中我从未见过),所以我特别把这些值过滤掉。

这是我(PHP)代码的一部分,用来判断一个格式是否是日期格式:

private static  $possibleDateFormatCharacters = 'ymdHis';

//  Typically number, currency or accounting (or occasionally fraction) formats
if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) {
    return false;
}
// Try checking for any of the date formatting characters that don't appear within square braces
if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) {
    return true;
}

// No date...
return false;

我相信可能还有一些我没有考虑到的例外情况,但如果有的话,它们可能都是极端的例子。

5

日期是以整数形式存储的

在Excel的数据模型中,其实没有真正的整数。所有的东西都是浮点数。日期和时间都是浮点数,表示从某个特定时间点开始的天数和小数部分。时间则是一天的一部分。

目前看来,标准的Excel读取库在支持xlsx格式方面有些不足。

可以在网上搜索“xlsxrd”。为了保持更新,可以加入python-excel小组

编辑 我看到你在那里已经问过一个问题。如果你在那儿问的问题和这个一样具体,或者回应我请求澄清的内容,你早就能得到这些信息了。

看看xlrd的文档。在前面有关于Excel日期的讨论。这些内容适用于Excel 2007以及更早的版本。特别是:需要解析自定义格式。还需要有一个“标准”格式索引表,用于日期格式。有些地方列出的“标准”格式不包括CJK地区使用的格式。

你可以选择:

(1) 从xlrd的源代码中借用,包括xldate_as_tuple函数。

(2) 选项(1) + 获取xlsxrd的附加工具包,并从它的源代码中借用。

(3) [推荐] 获取xlsxrd的附加工具包并使用它……你将获得一套可以在Excel 2.0到2007版本和Python 2.1到2.7版本之间操作的API。

撰写回答