【问题标题】:PHPExcel - Severe performance slowdown when applying number formatsPHPExcel - 应用数字格式时性能严重下降
【发布时间】:2025-11-22 12:20:05
【问题描述】:

我已经使用 xdebug 分析了我的 Excel 生成代码并查看了研磨文件。显然我的大部分执行时间都花在:

setFormatCode(...)

而且有问题的代码在这里:

protected function formatRow($line)
{
    // /*
    foreach ($this->getIntegerColumns() as $column) {
        $style = $this->worksheet->getStyle($column . $line);
        $style->getNumberFormat()->setFormatCode('#,##0');
    }
    foreach ($this->getFloatColumns() as $column) {
        $style = $this->worksheet->getStyle($column . $line);
        $style->getNumberFormat()->setFormatCode('#,##0.00');
    }
    foreach ($this->getPercentageColumns() as $column) {
        $style = $this->worksheet->getStyle($column . $line);
        $style->getNumberFormat()->setFormatCode('0.00%');
    }
    foreach ($this->getDateColumns() as $column) {
        $style = $this->worksheet->getStyle($column . $line);
        $style->getNumberFormat()->setFormatCode('mm/dd/yyyy');
    }
    // */
    return $this;
}

我的报告通常需要:

getSummaryData: Elapsed time: 4
getInteractionData: Elapsed time: 10
getVideoData: Elapsed time: 2
new CampaignDetailReport: Elapsed time: 0
new CampaignDetailReportWriter: Elapsed time: 0
new write(): Elapsed time: 125

~ 140 seconds

但如果我注释掉 formatRow() 函数的内容,它需要:

getSummaryData: Elapsed time: 4
getInteractionData: Elapsed time: 9
getVideoData: Elapsed time: 2
new CampaignDetailReport: Elapsed time: 0
new CampaignDetailReportWriter: Elapsed time: 0
new write(): Elapsed time: 32

~ 50 seconds

这仍然很长,但有很大的改进(快了近 50%)。

我在这里查看了答案:PHPExcel very slow - ways to improve?,但我不确定如何实施修复。理想情况下,我认为一种解决方案是将样式应用于整个列,而不是逐个单元格。如果该列类似于“成本”,我知道所有列值都是浮点数,因此将数字格式应用于所有单元格可能是安全的。现在才确定如何真正做到这一点。

更新:

为了回应 Mark Ba​​kers 的回答,我做了以下事情:

foreach($this->getIntegerColumns() as $column) {
        $this->worksheet->getStyle(sprintf("%s%s:%s%s", $column, 5, $column, $this->line))
             ->getNumberFormat()
             ->setFormatCode('#,##0');
    }

为列中的所有单元格设置整数类型的所有列的样式。我所有的报告指标都从 5 开始,然后转到 this->line,这是内部计数器。到目前为止,这运作良好。完成一张工作表的样式大约需要 4 秒(我的报告中有 3 个工作表)。所以按照这个速度,我应该能够为所有工作表设置样式,并且只需要额外的约 12 秒的执行时间,将其提高到 ~65 与 ~125 !!!

【问题讨论】:

    标签: php symfony reporting phpexcel


    【解决方案1】:

    利用流畅的界面。

    尽可能将您的格式应用于一系列单元格:

    $this->worksheet->getStyle('A1:A21')
        ->getNumberFormat()
        ->setFormatCode('0.00%');
    

    如果您想一次性将多个样式设置应用于一个单元格(或单元格范围),请使用样式的 applyFromArray()。

    所有这些技术都将有助于提高速度。

    【讨论】:

    • 太棒了 - 我将我的格式化代码在我的类层次结构中向上移动了一点,并执行了你的建议。到目前为止工作得更好 - 必须更新我所有的“工作表”才能使用它。谢谢。用实际代码更新了我的答案。
    • 我似乎记得一个计划的功能实现如下: $this->objPHPExcel->getActiveSheet()->getStyle($columnIndex)->getNumberFormat()->setFormatCode('$#, ##0.00');这没有发生吗?
    • 不,行和列样式尚不可用
    最近更新 更多