PHPExcel 自动筛选之 DateGroup 日期分组筛选完全指南:规则构建、源码校验与 Excel2007 读写映射
后端电商前端【免费下载链接】CRMEBCRMEB开源商城免费开源多语言商城系统Tp6框架商城系统可商用包含小程序商城、H5商城、公众号商城、PC商城、App支持分销、拼团、砍价、秒杀、优惠券、积分、会员等级、小程序直播、页面DIY前后端分离方便二开更有详细使用文档、接口文档、数据字典、二开文档/视频教程欢迎大家提出宝贵意见和建议项目地址https://gitcode.com/gh_mirrors/cr/CRMEB点击查看免费下载DateGroup日期分组筛选是 PHPExcel 中针对日期列的高级筛选能力它让开发者能用year、month、day等时间粒度精确筛选整年、整月乃至某个时刻的数据。本文以 PHPExcel 官方 AutoFilter 文档为骨架结合 CRMEB 仓库crmeb/vendor/phpoffice/phpexcel目录下的完整源码系统讲解 DateGroup 规则的构建方法、关联数组的底层校验逻辑以及该规则在 Excel2007.xlsx读写层面的 XML 映射细节。什么是 DateGroup 筛选在 MS Excel 中DateGroup 筛选会为日期列提供一组级联的下拉选择器用户可以指定整个年份、某一年中的某个月份或者某个月份中的某一天甚至精确到时、分、秒。它的行为与 Excel 中日期筛选菜单里按年、按月、按日折叠分组的效果一致。与 PHPExcel 的另外几类筛选表达式Simple、Custom、Dynamic、TopTen不同DateGroup 筛选仍然作为标准筛选Standard Filter类型应用。这意味着在列Column层面上它的filterType依然是$columnFilter-setFilterType( PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER );而区分 DateGroup 与普通简单筛选的关键在于规则Rule层面的ruleType只有把规则类型显式设置为AUTOFILTER_RULETYPE_DATEGROUP该规则才会被识别为日期分组项。这一设计可以从 Rule.php 中定义的规则类型常量看出const AUTOFILTER_RULETYPE_FILTER filter; const AUTOFILTER_RULETYPE_DATEGROUP dateGroupItem; const AUTOFILTER_RULETYPE_CUSTOMFILTER customFilter; const AUTOFILTER_RULETYPE_DYNAMICFILTER dynamicFilter; const AUTOFILTER_RULETYPE_TOPTENFILTER top10Filter;dateGroupItem正是 Excel2007 OOXML 中filters元素下日期分组子元素的标签名在读写环节会被直接映射为同名的 XML 节点。前置准备定位要筛选的列在构造任何筛选表达式之前先通过工作表Worksheet的 AutoFilter 对象取得目标列。以下代码取自 PHPExcel 官方文档 03-Autofilter-Expressions.md$autoFilter $objPHPExcel-getActiveSheet()-getAutoFilter(); $columnFilter $autoFilter-getColumn(C);返回的PHPExcel_Worksheet_AutoFilter_Column对象承载了该列的全部筛选状态。从源码看该对象默认的filterType即AUTOFILTER_FILTERTYPE_FILTER多规则连接默认join为AUTOFILTER_COLUMN_JOIN_OR见 Column.php。换用getColumnByOffset($index)可按列索引取列Excel2007 读取器恢复筛选时正是这样做的。构建一个 DateGroup 规则创建 DateGroup 规则时把被勾选的时间值作为一个关联数组传入setRule()。数组中可用的键共有 6 个键含义典型取值year年份如2012month月份如1112day日如1131hour时如14023minute分如30059second秒如0059例如要筛选 2012 年 1 月的全部数据可以这样写$columnFilter-createRule() -setRule( PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, array( year 2012, month 1 ) ) -setRuleType( PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP );关键点createRule()在列的规则集中追加一个新规则并返回该规则对象见 Column.phpsetRule()的第一个参数传操作符常量对 DateGroup 而言总是AUTOFILTER_COLUMN_RULE_EQUALsetRuleType()必须显式设置否则规则仍会被当作普通 filter 处理一个列上可以创建任意数量的 DateGroup 规则。关联数组的底层校验与 grouping 自动推导在 Rule.php 的setValue()中对传入的关联数组有一套严格的校验逻辑只接受year、month、day、hour、minute、second六个键其余键会被静默移除计算grouping分组粒度为所有提供的键在$dateTimeGroups数组中索引的最大值即取最小的时间单位。例如只传year和month分组粒度推导为month如果过滤后数组为空没有任何合法键抛出PHPExcel_Exception(Invalid rule value for column AutoFilter Rule.)。对应的$dateTimeGroups定义如下const AUTOFILTER_RULETYPE_DATEGROUP_YEAR year; const AUTOFILTER_RULETYPE_DATEGROUP_MONTH month; const AUTOFILTER_RULETYPE_DATEGROUP_DAY day; const AUTOFILTER_RULETYPE_DATEGROUP_HOUR hour; const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE minute; const AUTOFILTER_RULETYPE_DATEGROUP_SECOND second;此外setRuleType()会校验类型是否在$ruleTypes白名单内Rule.php非法类型同样抛出PHPExcel_Exception。理解这一点有助于调试类型写错但看起来没报错的场景——实际上非法类型会直接中断。语义约束永远是 EQUALS永远是 OR与简单筛选Simple Filter见 04-01-Autofilter-Expressions-Simple.md一致DateGroup 筛选遵循两条硬性语义所有 DateGroup 规则的比较操作符固定为 EQUALSsetRule()第一参数应传AUTOFILTER_COLUMN_RULE_EQUAL同一列上的多个 DateGroup 规则之间总是按 OR 连接——即任一规则命中即显示该行。这正符合 Excel 的行为在日期列上勾选 2012 年 1 月和 2012 年 3 月展示的是两个月数据的并集。列对象的默认 join 就是 ORColumn.php且 DateGroup 属于标准筛选不参与 CustomFilter 的 AND/OR 自定义连接。另外注意PHPExcel 文档提醒同一列内不应混用不同类型的筛选表达式Simple / DateGroup / Custom / Dynamic / TopTen 互斥。库不会主动阻止混用但结果不可预期。源码纵深DateGroup 在 Excel2007 读写层的映射DateGroup 不是 PHPExcel 的虚构概念而是对 OOXML 规范中dateGroupItem节点的直接实现。写入Writer侧在 Writer/Excel2007/Worksheet.php 中写出筛选规则时对AUTOFILTER_RULETYPE_DATEGROUP做了专门处理if ($rule-getRuleType() PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { // Date Group filters foreach ($rule-getValue() as $key $value) { if ($value ) { $objWriter-writeAttribute($key, $value); } } $objWriter-writeAttribute(dateTimeGrouping, $rule-getGrouping()); }可以看到两个值得注意的实现细节关联数组中值为空字符串的时间单位不会被写出。例如规则只传了year和month生成的 XML 就只含这两个属性而不是全部 6 个dateTimeGrouping属性取自getGrouping()即前面setValue()自动推导出的最小时间粒度。写入容器是filters下的dateGroupItem元素通过$objWriter-startElement($rule-getRuleType())生成因为ruleType的值正是dateGroupItem。生成后的典型 XML 结构大致为filterColumn colId3 filters dateGroupItem year2012 month1 dateTimeGroupingmonth/ /filters /filterColumn读取Reader侧在 Reader/Excel2007.php 中读取器遍历$filters-dateGroupItem把 XML 属性还原回关联数组并显式传入dateTimeGrouping作为第三个参数foreach ($filters-dateGroupItem as $dateGroupItem) { $column-createRule()-setRule( null, array( year (string) $dateGroupItem[year], month (string) $dateGroupItem[month], day (string) $dateGroupItem[day], hour (string) $dateGroupItem[hour], minute (string) $dateGroupItem[minute], second (string) $dateGroupItem[second], ), (string) $dateGroupItem[dateTimeGrouping] ) -setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); }读取端把 6 个时间属性全部取出不存在的属性在 SimpleXML 中会得到空字符串并通过setRule()的第三个参数显式设置分组粒度。这样用 PHPExcel 写入的 DateGroup 筛选可以被 PHPExcel 完整读回实现写入—读取—再写入的往返无损。完整实战筛选当月最后一天的数据仓库中的示例 10autofilter-selection-1.php 生成了 3 年 × 12 月 × 8 国家的逐日销售数据其中 D 列Date就应用了 DateGroup 筛选——筛选出当前年份每个月的最后一天foreach($periods as $period) { $endDate date(t, mktime(0,0,0,$period,1,$currentYear)); $autoFilter-getColumn(D) -setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) -createRule() -setRule( PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, array( year $currentYear, month $period, day $endDate ) ) -setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); }这段代码展示了两个实用手法动态计算日期分量date(t, ...)获取当月的最大天数避免硬编码 31 等可能越界的值批量创建多条 OR 规则循环 12 个月为每个月各建一条year month day的 DateGroup 规则最终在 Excel 中呈现为当前年份每月最后一天共 12 个日期的并集筛选。运行该示例需要先引入 PHPExcel 自动加载示例通过require_once dirname(__FILE__) . /../Classes/PHPExcel.php引入并可用PHPExcel_IOFactory::createWriter($objPHPExcel, Excel2007)输出 .xlsx 验证效果。实践要点与常见坑位ruleType必须显式设置漏掉setRuleType(AUTOFILTER_RULETYPE_DATEGROUP)规则会被当作普通filter值处理Excel 中表现为单值相等而非日期分组。键名拼写敏感year/month/day/hour/minute/second之外的多余键会被setValue()直接丢弃若全部键非法将抛出异常。粒度自动推导不要手工猜测dateTimeGroupingPHPExcel 会按提供的键中最精细的时间单位自动推导如需显式指定可在setRule()第三个参数传入读取端即如此还原。空值写出策略写入 .xlsx 时值为空字符串的时间分量不会出现在 XML 中这保证最小粒度以上的冗余属性被省略。多规则即 OR同一日期列上多条 DateGroup 规则是并集关系若想表达同时满足年与月的嵌套关系应合并为一条规则中的多个键而不是拆成多条规则。与其他筛选类型互斥不要在同一列混合 DateGroup 与 Custom/Dynamic/TopTen 筛选PHPExcel 不阻止但结果不可预期。通过以上 API 用法与源码细节开发者可以在 PHPExcel 中完整复现 Excel 原生的日期分组筛选体验并理解dateGroupItem在 OOXML 层面的完整生命周期。赞分享后端电商前端【免费下载链接】CRMEBCRMEB开源商城免费开源多语言商城系统Tp6框架商城系统可商用包含小程序商城、H5商城、公众号商城、PC商城、App支持分销、拼团、砍价、秒杀、优惠券、积分、会员等级、小程序直播、页面DIY前后端分离方便二开更有详细使用文档、接口文档、数据字典、二开文档/视频教程欢迎大家提出宝贵意见和建议项目地址https://gitcode.com/gh_mirrors/cr/CRMEB点击查看免费下载相关推荐PHPExcel AutoFilter 日期分组筛选DateGroup Filter完整指南按年、月、日、时分秒精确筛选日期列PHPExcel AutoFilter 日期分组筛选DateGroup Filter完整指南按年、月、日、时分秒精确筛选日期列 导读 本篇文章以 PHPE后端数据处理PHPExcel AutoFilter 表达式编程完全指南Simple / DateGroup / Custom / Dynamic / TopTen 五种筛选规则实战PHPExcel AutoFilter 表达式编程完全指南Simple / DateGroup / Custom / Dynamic / TopTen 五种筛后端数据处理PHPExcel 自动筛选AutoFilter功能完全指南从概念到源码实现PHPExcel 自动筛选AutoFilter功能完全指南从概念到源码实现 导读 本篇指南以 PHPExcel 官方 Autofilters 系列文档为核后端数据处理上一篇Cutter 逆向分析平台Analysis 选项对话框与 Rizin 分析配置详解下一篇Pandoc 属性转义与可逆性测试解析从 native 到 fenced Div 的 round-trip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考