Spaces:
No application file
No application file
namespace Mautic\ReportBundle\Model; | |
use Mautic\CoreBundle\Twig\Helper\FormatterHelper; | |
use Mautic\ReportBundle\Crate\ReportDataResult; | |
use PhpOffice\PhpSpreadsheet\Exception; | |
use PhpOffice\PhpSpreadsheet\IOFactory; | |
use PhpOffice\PhpSpreadsheet\Spreadsheet; | |
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; | |
use Symfony\Contracts\Translation\TranslatorInterface; | |
class ExcelExporter | |
{ | |
public function __construct( | |
protected FormatterHelper $formatterHelper, | |
private TranslatorInterface $translator | |
) { | |
} | |
/** | |
* @param string $name | |
* | |
* @throws \Exception | |
*/ | |
public function export(ReportDataResult $reportDataResult, $name, string $output = 'php://output'): void | |
{ | |
if (!class_exists(Spreadsheet::class)) { | |
throw new \Exception('PHPSpreadsheet is required to export to Excel spreadsheets'); | |
} | |
try { | |
$objPHPExcel = new Spreadsheet(); | |
$objPHPExcel->getProperties()->setTitle($name); | |
$objPHPExcel->createSheet(); | |
$objPHPExcelSheet = $objPHPExcel->getActiveSheet(); | |
$reportData = $reportDataResult->getData(); | |
$rowCount = 1; | |
if (empty($reportData)) { | |
throw new \Exception('No report data to be exported'); | |
} | |
$headersRow = $reportDataResult->getHeaders(); | |
$this->putHeader($headersRow, $objPHPExcelSheet); | |
// build the data rows | |
foreach ($reportData as $count=>$data) { | |
$row = []; | |
foreach ($data as $k => $v) { | |
$type = $reportDataResult->getType($k); | |
$formatted = htmlspecialchars_decode($this->formatterHelper->_($v, $type, true), ENT_QUOTES); | |
$row[] = $formatted; | |
} | |
// write the row | |
$rowCount = $count + 2; | |
$objPHPExcel->getActiveSheet()->fromArray($row, null, "A{$rowCount}"); | |
// free memory | |
unset($row, $reportData['data'][$count]); | |
} | |
// Add totals to export | |
$totalsRow = $reportDataResult->getTotalsToExport($this->formatterHelper); | |
if (!empty($totalsRow)) { | |
$this->putTotals($totalsRow, $objPHPExcelSheet, 'A'.++$rowCount); | |
} | |
$objWriter = IOFactory::createWriter($objPHPExcel, 'Xlsx'); | |
$objWriter->setPreCalculateFormulas(false); | |
$objWriter->save($output); | |
} catch (Exception $e) { | |
throw new \Exception('PHPSpreadsheet Error', 0, $e); | |
} | |
} | |
/** | |
* @param array<string> $headers | |
*/ | |
public function putHeader(array $headers, Worksheet $activeSheet): void | |
{ | |
$activeSheet->fromArray($headers); | |
} | |
/** | |
* @param array<string> $totals | |
*/ | |
public function putTotals(array $totals, Worksheet $activeSheet, string $startCell): void | |
{ | |
// Put label if the first item is empty | |
$key = array_key_first($totals); | |
if (empty($totals[$key])) { | |
$totals[$key] = $this->translator->trans('mautic.report.report.groupby.totals'); | |
} | |
$activeSheet->fromArray($totals, null, $startCell); | |
} | |
} | |