xlsx improvements (#1518)
This commit is contained in:
@@ -41,7 +41,7 @@ class TimesheetFixtures extends Fixture implements DependentFixtureInterface
|
||||
public const MIN_MINUTES_PER_ENTRY = 15;
|
||||
public const MAX_MINUTES_PER_ENTRY = 840; // 14h
|
||||
public const MAX_TAG_PER_ENTRY = 3;
|
||||
public const MAX_DESCRIPTION_LENGTH = 50;
|
||||
public const MAX_DESCRIPTION_LENGTH = 500;
|
||||
|
||||
public const BATCH_SIZE = 100;
|
||||
|
||||
|
||||
@@ -74,7 +74,10 @@ abstract class AbstractSpreadsheetRenderer
|
||||
'customer' => [],
|
||||
'project' => [],
|
||||
'activity' => [],
|
||||
'description' => [],
|
||||
'description' => [
|
||||
'maxWidth' => 50,
|
||||
'wrapText' => false,
|
||||
],
|
||||
'exported' => [],
|
||||
'tags' => [],
|
||||
'hourlyRate' => [],
|
||||
@@ -264,8 +267,31 @@ abstract class AbstractSpreadsheetRenderer
|
||||
}
|
||||
|
||||
if (isset($columns['description']) && !isset($columns['description']['render'])) {
|
||||
$columns['description']['render'] = function (Worksheet $sheet, int $row, int $column, ExportItemInterface $entity) {
|
||||
$sheet->setCellValueByColumnAndRow($column, $row, $entity->getDescription());
|
||||
$maxWidth = array_key_exists('maxWidth', $columns['description']) ? intval($columns['description']['maxWidth']) : null;
|
||||
$wrapText = array_key_exists('wrapText', $columns['description']) ? (bool) $columns['description']['wrapText'] : false;
|
||||
|
||||
// This column has a column-only formatter to set the maximum width of a column.
|
||||
// It needs to be executed once, so we use this as a flag on when to skip it.
|
||||
$isColumnFormatted = false;
|
||||
|
||||
$columns['description']['render'] = function (Worksheet $sheet, int $row, int $column, ExportItemInterface $entity) use (&$isColumnFormatted, $maxWidth, $wrapText) {
|
||||
$cell = $sheet->getCellByColumnAndRow($column, $row);
|
||||
|
||||
$cell->setValue($entity->getDescription());
|
||||
|
||||
// Apply wrap text if configured
|
||||
if ($wrapText) {
|
||||
$cell->getStyle()->getAlignment()->setWrapText(true);
|
||||
}
|
||||
|
||||
// Apply max width, only needs to be once per column
|
||||
if (!$isColumnFormatted) {
|
||||
if (null !== $maxWidth) {
|
||||
$sheet->getColumnDimensionByColumn($column)
|
||||
->setWidth($maxWidth);
|
||||
}
|
||||
$isColumnFormatted = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -464,6 +490,12 @@ abstract class AbstractSpreadsheetRenderer
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
// Set default row height to automatic, so we can specify wrap text columns later on
|
||||
// without bloating the output file as we would need to store stylesheet info for every cell.
|
||||
// LibreOffice is still not considering this flag, @see https://github.com/PHPOffice/PHPExcel/issues/588
|
||||
// with no solution implemented so nothing we can do about it there.
|
||||
$sheet->getDefaultRowDimension()->setRowHeight(-1);
|
||||
|
||||
$recordsHeaderColumn = 1;
|
||||
$recordsHeaderRow = 1;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Export\Base;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
|
||||
class XlsxRenderer extends AbstractSpreadsheetRenderer
|
||||
{
|
||||
@@ -39,6 +40,36 @@ class XlsxRenderer extends AbstractSpreadsheetRenderer
|
||||
throw new \Exception('Could not open temporary file');
|
||||
}
|
||||
|
||||
// Store expensive calculations for later
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$highestRow = $sheet->getHighestRow();
|
||||
$highestColumn = $sheet->getHighestColumn();
|
||||
|
||||
// Enable auto filter for header row
|
||||
$sheet->setAutoFilter('A1:' . $highestColumn . '1');
|
||||
|
||||
// Freeze first row and date & time columns for easier navigation
|
||||
$sheet->freezePane('D2');
|
||||
|
||||
foreach (range('A', $highestColumn) as $column) {
|
||||
// We default to a reasonable auto-width decided by the client,
|
||||
// sadly ->getDefaultColumnDimension() is not supported so it needs
|
||||
// to be specific about what column should be auto sized.
|
||||
$col = $sheet->getColumnDimension($column);
|
||||
|
||||
// If no other width is specified (which defaults to -1)
|
||||
if ($col->getWidth() === -1) {
|
||||
$col->setAutoSize(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Text inside cells should be top left
|
||||
$sheet
|
||||
->getStyle('A2:' . $highestColumn . $highestRow)
|
||||
->getAlignment()
|
||||
->setVertical(Alignment::VERTICAL_TOP)
|
||||
->setHorizontal(Alignment::HORIZONTAL_LEFT);
|
||||
|
||||
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||
$writer->save($filename);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user