资讯动态

CRMEB 项目中的 PHPExcel 公式函数参考:通用引言与 Excel5 写入器兼容性边界

发布时间:2026/10/15 2:51:12 来源:尧图企业网站定制
后端电商前端【免费下载链接】CRMEBCRMEB开源商城免费开源多语言商城系统Tp6框架商城系统可商用包含小程序商城、H5商城、公众号商城、PC商城、App支持分销、拼团、砍价、秒杀、优惠券、积分、会员等级、小程序直播、页面DIY前后端分离方便二开更有详细使用文档、接口文档、数据字典、二开文档/视频教程欢迎大家提出宝贵意见和建议项目地址https://gitcode.com/gh_mirrors/cr/CRMEB点击查看免费下载导读本文围绕 CRMEB 开源商城仓库中所携带的 PHPExcel 组件文档《Calculation Engine - Formula Function Reference》的通用引言部分展开核心回答一个开发者最关心的问题哪些 Excel 公式函数已经被 PHPExcel 计算引擎实现、但在写入 Excel 5.xls格式时会报错。文章不仅完整梳理了不支持写入 Excel5的函数清单Cube 函数、数据库函数、日期与时间函数等还将结合仓库内 PHPExcel 源码深入讲解日期函数在不同返回类型Excel 时间戳 / PHP 时间戳 / PHP DateTime 对象下的行为差异、Excel5 写入器与 Analysis ToolPak 加载项的兼容性边界并给出可直接运行的验证示例。读完本文你将掌握如何在 CRMEB 这类基于 PHP 的商城项目中安全地选择公式、规避 Excel5 写入错误以及如何在需要时切换公式计算结果的返回类型。本文所引用的文档文件位于仓库 02-General-Introduction.md对应的 PHPExcel 组件位于 crmeb/vendor/phpoffice/phpexcel 目录。一、什么是Excel 5 写入器与不支持函数1.1 Excel5 Writer 的定位PHPExcel 是一个用 PHP 实现的内存电子表格库既能读也能写。在其 Writer 家族中PHPExcel_Writer_Excel2007、PHPExcel_Writer_Excel5、PHPExcel_Writer_CSV、PHPExcel_Writer_HTML、PHPExcel_Writer_OpenDocument、PHPExcel_Writer_PDF等见仓库 Classes/PHPExcel/Writer 目录PHPExcel_Writer_Excel5负责把工作簿输出为 Excel 5即经典的二进制 .xls格式。在 CRMEB 项目里虽然当前业务导出主要使用PhpOffice\PhpSpreadsheet的 Xlsx/Xls 写入器见 SpreadsheetExcelService.php 中的excelSave()方法但仓库完整携带了 PHPExcel 1.8 时代的全部源码与官方文档其中关于公式函数能否被写入 Excel5的说明对任何需要生成 .xls 报表的场景都具有直接参考价值。1.2 不支持的确切含义文档原文明确了两层含义并非所有函数都被 Excel 5 Writer 支持如果工作簿中使用了这些函数尝试写入 Excel5 时会触发错误result in an error when trying to write to Excel5。也就是说这里的不支持不是指公式在 PHPExcel 计算引擎里算不出来而是指写入二进制 .xls 文件时无法正确编码该函数。这类函数在 PHPExcel 计算引擎中通常是已实现的能够被求值只是无法被 Excel5 写入器序列化。二、不可写入 Excel5 的函数清单文档《02-General-Introduction》给出了三类函数的清单。2.1 Cube 函数多维数据集函数以下 7 个 Cube 函数不仅无法写入 Excel5而且在 PHPExcel 中根本没有实现文档标记为 Not yet ImplementedExcel 函数说明CUBEKPIMEMBER返回关键绩效指标KPI属性未实现CUBEMEMBER返回多维数据集中的成员或元组未实现CUBEMEMBERPROPERTY返回多维数据集成员属性值未实现CUBERANKEDMEMBER返回集合中排名第 N 的成员未实现CUBESET定义多维数据集成员的集合未实现CUBESETCOUNT返回集合中的成员数量未实现CUBEVALUE返回集合中聚合值未实现源码印证仓库中对应的函数参考文档 03-01-Cube-Functions.md 对上述 7 个函数逐一标注为 Not yet implemented同时PHPExcel_Calculation_Functions::DUMMY()见 Functions.php返回#Not Yet Implemented这是所有尚未实现函数的标准占位返回。因此若在 CRMEB 的报表业务中构造包含 Cube 函数的公式PHPExcel 计算引擎会直接返回占位错误更谈不上写入任何格式的文件。2.2 Database 函数数据库函数文档在 Database 函数一节给出了一个空的表格——这并不意味着数据库函数全部支持写入 Excel5而是说明该文档当时尚未罗列数据库函数的具体限制。需要指出PHPExcel 计算引擎中数据库函数是已经实现的包括DAVERAGE、DCOUNT、DMAX、DMIN、DSUM等见 Calculation/Database.php以及对应的函数参考文档 03-02-Database-Functions.md。使用建议当文档表格为空或标注未实现时稳妥的做法是用 PHPExcel 求值验证 实际写入 Excel5 验证双重确认而不是默认某个函数一定可用。2.3 Date and Time 函数日期与时间函数文档明确指出以下两个日期函数在 Excel 5 中并非标准函数而是 Analysis ToolPak分析工具库加载项提供的函数因此当前无法写入 Excel5Excel 函数说明EDATE返回指定月数之前或之后的日期同月同日EOMONTH返回指定月数之前或之后那个月的最后一天源码印证仓库 DateTime.php 中EDATE()与EOMONTH()均已实现且文档 03-03-Date-and-Time-Functions.md 中给这两个函数标注了同样的WARNINGThis function is currently not supported by the Excel5 Writer because it is not a standard function within Excel 5, but an add-in from the Analysis ToolPak.这是整个通用引言中最重要的实战提示公式可以计算但用PHPExcel_Writer_Excel5写出包含EDATE/EOMONTH的工作簿会报错。如果需要 .xls 输出应改用 Excel2007 写入器.xlsx或在写入前将公式结果替换为静态值。2.4 DAYS360 的特殊警告文档中的附加提示虽然DAYS360不在不可写入 Excel5的清单内但文档在DAYS360函数的 Notes 里特别补充了一个与 Excel5 写入器直接相关的坑当第三个可选参数method传入PHP 布尔值TRUE/FALSE时该函数当前无法配合 Excel5 Writer 工作写入时会生成错误只有传入数值 0/1或使用 Excel 的TRUE()/FALSE()函数才能正常工作。这一细节说明Excel5 写入错误不限于未实现函数参数类型选择不当同样会触发。编写面向 .xls 的公式时务必用0/1代替 PHP 布尔值。三、日期函数源码级解析DATE / DATEDIF / DATEVALUE 等通用引言列出的 EDATE、EOMONTH 属于日期与时间函数族。要真正用好它们必须先理解 PHPExcel 的日期返回类型机制而这正是文档与源码的交叉验证点。3.1 三种日期返回类型Return Date TypePHPExcel 的日期类函数DATE、DATEVALUE、EDATE、EOMONTH、NOW等的返回值类型由全局静态配置PHPExcel_Calculation_Functions::$returnDateType决定。仓库源码 Functions.php 定义了三个常量常量值返回内容RETURNDATE_PHP_NUMERICPPHP 时间戳integerUnix 秒数RETURNDATE_PHP_OBJECTOPHPDateTime对象RETURNDATE_EXCELEExcel 日期序列值float如 39813.0 表示 2008-12-31默认值protected static $returnDateType self::RETURNDATE_EXCEL;Functions.php即默认返回 Excel 序列值。通过setReturnDateType()Functions.php与getReturnDateType()Functions.php可以随时切换。3.2 DATE 函数的参数解析与边界处理DATE(year, month, day)的返回值在文档中定义为mixed具体形态取决于当前返回类型设置。从源码 DateTime.php 可以看到完整的参数处理逻辑year 的相对年份规则文档说明若 year 在 0~1899Windows 1900 日历或 4~1903Mac 1904 日历之间PHPExcel 会将其加到日历基准年上。源码中对应逻辑为if (($year $baseYear) ($year ($baseYear-1900))) { $year 1900; }其中$baseYear由PHPExcel_Shared_Date::getExcelCalendar()决定1900 或 1904。因此DATE(108,12,31)在 Windows 1900 日历下表示 2008-12-31。month 越界修正month 12时做$year floor($month / 12); $month $month % 12;所以DATE(2008,14,2)进位为 2009-02-02month 1时做--$month; $year ceil($month / 12) - 1; $month 13 - abs($month % 12);所以DATE(2008,0,2)回退为 2007-12-02。day 越界修正由FormattedPHPToExcel()内部统一处理例如DATE(2008,1,35)自动进位为 2008-02-04DATE(2008,3,0)回退为 2008-02-29闰年DATE(2008,3,-2)回退为 2008-02-27。非法输入非数值参数返回#VALUE!年份超出合法范围返回#NUM!源码分别调用PHPExcel_Calculation_Functions::VALUE()与::NaN()。3.3 返回类型切换的完整示例可运行文档提供了两个官方示例此处完整保留并补充注释// 在单元格中写入公式通过 getCalculatedValue() 求值 $worksheet-setCellValue(A1, Year) -setCellValue(A2, Month) -setCellValue(A3, Day); $worksheet-setCellValue(B1, 2008) -setCellValue(B2, 12) -setCellValue(B3, 31); $worksheet-setCellValue(D1, DATE(B1,B2,B3)); $retVal $worksheet-getCell(D1)-getCalculatedValue(); // $retVal 1230681600 默认返回类型为 RETURNDATE_EXCEL 时是 Excel 序列值注意上述注释中的$retVal 1230681600对应的是RETURNDATE_PHP_NUMERICPHP 时间戳形态若保持默认的RETURNDATE_EXCEL同样公式的求值结果为39813.0。这也是为什么文档强调返回值取决于getReturnDateType()的原因。// 同一函数需要以不同返回类型多次调用先关闭计算结果缓存 PHPExcel_Calculation::getInstance()-setCalculationCacheEnabled(FALSE); $saveFormat PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType( PHPExcel_Calculation_Functions::RETURNDATE_EXCEL ); $retVal call_user_func_array( array(PHPExcel_Calculation_Functions, DATE), array(2008, 12, 31) ); // $retVal 39813.0 PHPExcel_Calculation_Functions::setReturnDateType( PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC ); $retVal call_user_func_array( array(PHPExcel_Calculation_Functions, DATE), array(2008, 12, 31) ); // $retVal 1230681600 PHPExcel_Calculation_Functions::setReturnDateType($saveFormat);为什么必须先关闭计算缓存源码 Calculation.php 中$calculationCacheEnabled默认为true且同一单元格的公式计算结果会被缓存见 Calculation.php。若不关闭缓存第二次以不同返回类型求值时会命中缓存、得到第一次的结果导致改了返回类型却拿到旧值的假象。3.4 静态调用call_user_func_array的使用意义文档中大量使用call_user_func_array(array(PHPExcel_Calculation_Functions, DATE), ...)的形式调用函数。原因在于PHPExcel 的日期函数实现在PHPExcel_Calculation_DateTime类中但通过PHPExcel_Calculation_Functions的别名机制暴露公式引擎在解析DATE(...)时会把函数名映射到对应的静态方法直接静态调用的好处是可以脱离单元格与工作簿上下文纯粹以编程方式验证函数的参数处理和返回值类型。例如在 DateTime.php 中DAY在单元格公式里写作DAY(A2)但对应的静态方法是DAYOFMONTH()见 DateTime.phpHOUR对应HOUROFDAY()DateTime.php、MINUTE对应MINUTEOFHOUR()DateTime.php、MONTH对应MONTHOFYEAR()DateTime.php、SECOND对应SECONDOFMINUTE()DateTime.php、WEEKDAY对应DAYOFWEEK()、NOW对应DATETIMENOW()DateTime.php。这些命名差异是静态调用时必须注意的细节。3.5 EDATE / EOMONTH 的求值语义文档对EDATE(baseDate, months)与EOMONTH(baseDate, months)的定义如下EDATE返回基准日期 N 个月后或前的同一日期适合计算到期日、还款日months 为正数表示未来负数表示过去。示例EDATE(1-Jan-2008, 5)得到39600.0即 1-Jun-2008EDATE(29-Feb-2008, -12)得到39141.028-Feb-2007注意 2 月 29 日不存在时自动取月末。EOMONTH返回基准日期 N 个月后或前那个月的最后一天。示例EOMONTH(1-Jan-2000, 5)得到39629.030-Jun-2000EOMONTH(14-Feb-2009, -12)得到39507.029-Feb-2008闰年。与 Excel 的差异提醒文档原话的 WARNINGPHPExcel 接受比 MS Excel 更宽的日期字符串格式因此可能出现PHPExcel 能算出来、Excel 打开却报#VALUE!的情况。在写入 Excel5/Excel2007 的工作簿中应谨慎使用字符串形式的日期参与运算。四、Excel5 写入器的兼容性边界与规避策略综合通用引言和 03-03-Date-and-Time-Functions.md 的提示可将 Excel5 写入兼容性问题归纳为三类未实现函数如全部 Cube 函数CUBEMEMBER、CUBESET、CUBEVALUE等计算引擎直接返回#Not Yet Implemented任何格式都无法写出有效结果已实现但 Excel5 无法编码的函数如EDATE、EOMONTHAnalysis ToolPak 加载项计算正常但PHPExcel_Writer_Excel5写入时报错参数类型触发的写入错误如DAYS360的第三个参数使用 PHP 布尔值TRUE/FALSE写入 Excel5 报错应改用0/1或TRUE()/FALSE()函数。规避策略可直接落地面向 .xls 输出时先核对目标函数是否在上述清单内需要EDATE/EOMONTH且必须输出 .xls可先通过getCalculatedValue()求出结果再把单元格值改写为静态日期值或使用PHPExcel_Writer_Excel2007输出 .xlsx对任何公式都建议以计算验证 写入验证双轨测试参考仓库示例 Examples/13calculation.php 与 Examples/14excel5.php 了解计算引擎与 Excel5 写入的典型用法。五、附PHPExcel 计算引擎与公式求值入门为了把公式函数放进完整上下文这里补充计算引擎的两个核心概念源自仓库文档 Overview/09-Calculation-Engine.mdgetCalculatedValue()单元格可以是值类型或公式类型。对公式单元格调用$objPHPExcel-getActiveSheet()-getCell(E11)-getCalculatedValue()即可触发求值例如SUM(A1:A10)会返回 A1~A10 的和。行列插入的自动公式调整$objPHPExcel-getActiveSheet()-insertNewRowBefore(7, 2)在指定行前插入两行时公式引用会自动平移如单元格 E11 中的SUM(E4:E9)在插入两行后变为 E13 中的SUM(E4:E11)并且插入行会复制相邻行样式行为与 Excel 一致。此外计算引擎存在两条已知限制与通用引言同属公式函数参考主题下的重要背景运算符优先级Excel 中的优先级高于与代数中*高于类似但 PHPExcel 计算引擎转换到 PHP 后优先级行为可能与 Excel 不完全一致复杂混合表达式需注意。数字与文本混算如3Hello Excel 会返回#VALUE!错误而 PHPExcel 依据 PHP 的字符串转数值规则Hello 转为 0会把结果算成3甚至可能生成不可读的 Excel 文件内容。这两条限制提示我们公式函数的可靠性最终受 PHP 语言特性约束在 CRMEB 等生产项目中设计报表公式时应避免依赖 Excel 与 PHP 语义不一致的写法。六、总结通用引言明确了三类不能写入 Excel5的函数Cube 函数未实现、Database 函数文档留白需实测、Date and Time 中的 EDATE/EOMONTHAnalysis ToolPak 加载项日期函数的返回值形态由setReturnDateType()统一控制RETURNDATE_EXCEL/RETURNDATE_PHP_NUMERIC/RETURNDATE_PHP_OBJECT默认是 Excel 序列值反复以不同返回类型求值时务必先setCalculationCacheEnabled(FALSE)关闭计算缓存Excel5 写入错误还可能源于参数类型如DAYS360的 PHP 布尔值规避手段是使用0/1或TRUE()/FALSE()。如果业务只需要 .xlsx 输出上述 Excel5 兼容性问题大多可以绕开若必须提供 .xls则应在写码前对照本文清单进行逐项规避并在完成后用 Excel 实测文件可读性。延伸阅读仓库内公式函数参考入口01-Introduction.md日期与时间函数完整参考03-03-Date-and-Time-Functions.mdCube 函数参考03-01-Cube-Functions.md计算引擎概述Overview/09-Calculation-Engine.md日期函数实现DateTime.php返回类型与兼容模式配置Functions.phpCRMEB 电子表格导出服务PhpSpreadsheet 封装SpreadsheetExcelService.php计算示例13calculation.php、14excel5.php赞分享后端电商前端【免费下载链接】CRMEBCRMEB开源商城免费开源多语言商城系统Tp6框架商城系统可商用包含小程序商城、H5商城、公众号商城、PC商城、App支持分销、拼团、砍价、秒杀、优惠券、积分、会员等级、小程序直播、页面DIY前后端分离方便二开更有详细使用文档、接口文档、数据字典、二开文档/视频教程欢迎大家提出宝贵意见和建议项目地址https://gitcode.com/gh_mirrors/cr/CRMEB点击查看免费下载相关推荐PHPExcel 计算引擎函数参考Excel5 Writer 不支持的函数清单与兼容性处理指南PHPExcel 计算引擎函数参考Excel5 Writer 不支持的函数清单与兼容性处理指南 导读 本文基于 PHPExcel 官方计算引擎函数参考文档中的后端数据处理如何快速掌握PHPExcel公式函数数学、文本与逻辑函数实用指南如何快速掌握PHPExcel公式函数数学、文本与逻辑函数实用指南 PHPExcel是一款强大的PHP电子表格处理库支持创建、读取和修改Excel文件。本文将后端数据处理vanilla-extract的浏览器兼容性参考兼容性参考vanilla extract的浏览器兼容性参考兼容性参考 vanilla extract作为一款Zero runtime Stylesheets in Ty前端开发工具上一篇3条命令做出精简版Windows 11免费的Tiny11Builder能把官方镜像做小多少下一篇如何快速配置RTL8852BE无线网卡驱动新手必看的简易教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑