Rapport-Laravel/app/Exports/ZenovaReportExport.php

154 lines
5.7 KiB
PHP

<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
class ZenovaReportExport implements FromArray, WithEvents
{
protected $groups;
protected $body;
protected $totals;
public function __construct(array $groups, array $body, array $totals)
{
$this->groups = $groups;
$this->body = $body;
$this->totals = $totals;
}
public function array(): array
{
$groupRow = [];
$labelRow = [];
foreach ($this->groups as $group) {
$first = true;
foreach ($group['columns'] as $column) {
$groupRow[] = $first ? $group['label'] : '';
$labelRow[] = $column['label'];
$first = false;
}
}
$rows = [$groupRow, $labelRow];
foreach ($this->body as $line) {
$rows[] = $line;
}
if (!empty($this->totals)) {
$rows[] = $this->totals;
}
return $rows;
}
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
$sheet = $event->sheet->getDelegate();
$rows = $this->array();
$rowCount = max(1, count($rows));
$colCount = 0;
foreach ($this->groups as $group) {
$colCount += count($group['columns']);
}
if ($colCount < 1) {
return;
}
$lastCol = Coordinate::stringFromColumnIndex($colCount);
$colors = [
'demo' => 'FFF2CC',
'day' => 'DDEBF7',
'yesterday' => 'E2EFDA',
'today' => 'C6EFCE',
'mtd' => 'FCE4D6',
'ytd' => 'D9E2F3',
];
$sheet->getStyle('A1:' . $lastCol . $rowCount)->applyFromArray([
'font' => [
'name' => 'Calibri',
'size' => 11,
],
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
'color' => ['rgb' => 'B0B0B0'],
],
],
'alignment' => [
'vertical' => Alignment::VERTICAL_CENTER,
],
]);
$col = 1;
foreach ($this->groups as $group) {
$span = count($group['columns']);
$start = Coordinate::stringFromColumnIndex($col);
$end = Coordinate::stringFromColumnIndex($col + $span - 1);
if ($span > 1) {
$sheet->mergeCells($start . '1:' . $end . '1');
}
$sheet->getStyle($start . '1:' . $end . '2')->applyFromArray([
'font' => [
'bold' => true,
'color' => ['rgb' => '000000'],
],
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => ['rgb' => $colors[$group['tone']] ?? 'FFFFFF'],
],
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
'wrapText' => true,
],
]);
foreach ($group['columns'] as $offset => $column) {
$letter = Coordinate::stringFromColumnIndex($col + $offset);
$width = $column['type'] === 'text' ? 24 : 16;
$sheet->getColumnDimension($letter)->setWidth($width);
if ($rowCount < 3) {
continue;
}
$dataRange = $letter . '3:' . $letter . $rowCount;
if ($column['type'] === 'text') {
$sheet->getStyle($dataRange)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
} elseif ($column['type'] === 'percent') {
$sheet->getStyle($dataRange)->getNumberFormat()->setFormatCode('0.00"%"');
$sheet->getStyle($dataRange)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
} else {
$sheet->getStyle($dataRange)->getNumberFormat()->setFormatCode('#,##0');
$sheet->getStyle($dataRange)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
}
}
$col += $span;
}
$sheet->getRowDimension(1)->setRowHeight(22);
$sheet->getRowDimension(2)->setRowHeight(36);
$sheet->freezePane('A3');
if (!empty($this->totals)) {
$sheet->getStyle('A' . $rowCount . ':' . $lastCol . $rowCount)->applyFromArray([
'font' => ['bold' => true],
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => ['rgb' => 'F2F2F2'],
],
]);
}
},
];
}
}