I'm working on an Export method in Laravel to generate an XLSX file with included formulae. Everything is working, but on Export, the formula is getting an extra @
symbol added in a couple places, which then breaks the formula... The cell value is rendered as #VALUE
.
This is the function:
namespace App\Exports\Reports;
use App\Exports\Sheets\Reports\SheetOne;
use App\Exports\Sheets\Reports\SheetTwo;
use App\Exports\Sheets\Reports\SheetThree;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class ExcelReport implements WithMultipleSheets {
public function sheets(): array {
return [
new SheetOne($this->sheetOneData),
new SheetTwo($this->sheetTwoData),
new SheetThree($this->sheetThreeData)
];
}
}
The issue is on "Sheet 2":
namespace App\Exports\Sheets\Reports;
use App\Models\SheetTwoData;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\FromCollection;
class SheetTwo implements FromCollection, WithHeadings, WithMapping, WithTitle {
protected Collection $sheetTwoData;
private int $maxIndex;
public function __construct(Collection $sheetTwoData) {
$this->sheetTwoData = $sheetTwoData;
$this->maxIndex = 2 + $sheetTwoData->count() - 1;
}
public function collection(): collection {
$calcOne = "SheetTwo!D2:D{$this->maxIndex}";
$calcTwo = "SheetTwo!G2:G{$this->maxIndex}";
return $this->sheetTwoData->push([
'',
'Totals',
"=SUBTOTAL(109, C2:C{$this->maxIndex})",
"=SUM(IF({$calcOne}<>\"\",1/COUNTIF({$calcOne},{$calcOne}),0))",
"=SUM(IF({$calcTwo}<>\"\",1/COUNTIF({$calcTwo},{$calcTwo}),0))",
''
]);
}
public function headings(): array {
return [
'Column A',
'Column B',
'Column C',
'Column D',
'Column E',
'Column F',
'Column G'
];
}
public function map($row): array {
if ($row instanceof SheetTwoData) {
return $row->toArray();
}
return $row;
}
public function title(): string {
return 'SheetTwo';
}
This is then hooked up to a POST
Form via a Button, which when clicked, streams the generated XLSX as a Download through Chrome (or whatever browser):
if ($request->method() == 'POST') {
return Excel::download(new ExcelReport([
'sheetOneData' => SheetOneData::all(),
'sheetTwoData' => SheetTwoData::all(),
'sheetThreeData' => SheetThreeData::all()
]), 'excel-report.xlsx');
}
This all works just fine, and the file is downloaded, but the $calcOne
and $calcTwo
strings get adjusted. If I add dd($row);
before return $row;
(the handler that renders the row with these formulae), I see this:
array:6 [▼
0 => ""
1 => "Totals"
2 => "=SUBTOTAL(109, C2:C50)"
3 => "=SUM(IF(SheetTwo!D2:D50<>"",1/COUNTIF(SheetTwo!D2:D50,SheetTwo!D2:D50),0))"
4 => "=SUM(IF(SheetTwo!G2:G50<>"",1/COUNTIF(SheetTwo!G2:G50,SheetTwo!G2:G50),0))"
5 => ""
]
However, in the XLSX file, these formulae render as:
=SUM(IF(@SheetTwo!D2:D50<>"",1/COUNTIF(SheetTwo!D2:D50,@SheetTwo!D2:D50),0))
($calcTwo
, targeting G2:G50
is also broken in the same way).
Has anyone seen this issue before? Google is being less than helpful since searching for @
or "at symbol"
is very ambiguous, and Excel's help is laughably bad. Thanks!
Sidenote: If I manually remove this @
symbol from the generated XLSX file, then the formulae work as intended. The whole point of this XLSX file is so that I can generate it and send via Email, so currently I can modify it before send, but it might be fully automated in the future.