I've profiled my Excel generation code with xdebug and reviewed the grind file. Apparently the majority of my execution time is spent in:
setFormatCode(...)
And the offending code is here:
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;
}
My reports typically take:
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
But if I comment out the guts of the formatRow() function, it takes:
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
Which is still long, but a substantial improvement (nearly 50% faster).
I've reviewed the answer here: PHPExcel very slow - ways to improve?, but I'm not sure how to implement the fixes. Ideally, I think one solution would be to apply the style to the entire column, not on a cell-by-cell basis. If the column is something like 'cost', I know all the column values will be a float, so it's probably safe to apply the number format to all the cells. Just now sure how to actually do that.
UPDATE:
In response to Mark Bakers answer, I did the following:
foreach($this->getIntegerColumns() as $column) {
$this->worksheet->getStyle(sprintf("%s%s:%s%s", $column, 5, $column, $this->line))
->getNumberFormat()
->setFormatCode('#,##0');
}
Which styles all the columns of type integer for all the cells within the column. All my report metrics start at 5 and goto this->line, which is internal counter. This is working well so far. It took about 4 additional seconds to completely style one sheet (I have 3x sheets in my report). So at that rate I should be able to style all sheets and only incur an additional ~12 seconds of execution time, taking it to ~65 vs ~125 !!!