2

我已经使用 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 非常慢 - 如何改进?,但我不确定如何实施修复。理想情况下,我认为一种解决方案是将样式应用于整个列,而不是逐个单元格。如果该列类似于“成本”,我知道所有列值都是浮点数,因此将数字格式应用于所有单元格可能是安全的。现在确定如何实际做到这一点。

更新:

为了回应马克贝克斯的回答,我做了以下事情:

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 !!!

4

1 回答 1

4

利用流畅的界面。

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

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

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

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

于 2013-03-07T21:05:20.010 回答