Skip to content

Commit

Permalink
Improve column merging
Browse files Browse the repository at this point in the history
Add field map to formatter method
  • Loading branch information
tansautn committed Oct 14, 2024
1 parent 4479805 commit c7622e1
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 20 deletions.
15 changes: 14 additions & 1 deletion src/Contracts/FormatterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,18 @@
*/
interface FormatterInterface
{
public function formatValue($value);
/**
* Format a value for export.
*
* This method is called once for each cell value that is exported.
* The default implementation simply returns the value as is,
* but you can override this method in your class to change the
* behavior.
*
* @param mixed $value The value that is being exported.
* @param string $mappingKey The key of the mapped column that is being exported.
*
* @return mixed The formatted value.
*/
public function formatValue($value, $mappingKey);
}
21 changes: 12 additions & 9 deletions src/Traits/ExcelExportable.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
namespace Zuko\Flex2Cell\Traits;


use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
Expand Down Expand Up @@ -220,7 +218,9 @@ public function export(string $filename)
$this->writeHeaders($sheet);
}
$rowIndex = $this->appendMode ? $sheet->getHighestRow() + 1 : 3; // Start from row 3 due to double header
if ($this->data instanceof Collection || $this->data instanceof Model) {
/** @noinspection PhpUndefinedClassInspection */
/** @noinspection PhpUndefinedNamespaceInspection */
if ($this->data instanceof \Illuminate\Support\Collection || $this->data instanceof \Illuminate\Database\Eloquent\Model) {
$this->data = $this->data->toArray();
}
foreach (array_chunk($this->data, $this->chunkSize) as $chunk) {
Expand Down Expand Up @@ -259,12 +259,15 @@ public function export(string $filename)
*/
protected function writeHeaders($sheet)
{
$this->headerRowIndex = 1; // Start with assuming headers are in the first row
$columnIndex = 1;
foreach ($this->headers as $header) {
if (!in_array($header, $this->hiddens, true)) {
$sheet->setCellValue([$columnIndex, 1], $this->getHeader($header));
$displayHeader = $this->getHeader($header);
$sheet->setCellValue([$columnIndex, $this->headerRowIndex], $displayHeader);
if (isset($this->subHeaders[$header])) {
$sheet->setCellValue([$columnIndex, 2], $this->getSubHeader($header));
$sheet->setCellValue([$columnIndex, $this->headerRowIndex + 1], $this->getSubHeader($header));
$this->headerRowIndex = 2; // If we have subheaders, main headers are now in row 2
}
$columnIndex++;
}
Expand Down Expand Up @@ -428,7 +431,7 @@ protected function getColumnLetter($mappingKey)
*
* @param string $header The header
*
* @return string The mapping key if found, null otherwise
* @return string|null The mapping key if found, null otherwise
*/
protected function getMappingKeyFromHeader($header)
{
Expand All @@ -440,7 +443,7 @@ protected function getMappingKeyFromHeader($header)
*
* @param string $mappingKey The mapping key
*
* @return string The header if found, null otherwise
* @return string|null The header if found, null otherwise
*/
protected function getHeaderFromMappingKey($mappingKey)
{
Expand All @@ -450,7 +453,7 @@ protected function getHeaderFromMappingKey($mappingKey)
private static function first(array $array, $callback = null, $default = null) {
if (is_null($callback)) {
if (empty($array)) {
return value($default);
return $default;
}

foreach ($array as $item) {
Expand All @@ -464,6 +467,6 @@ private static function first(array $array, $callback = null, $default = null) {
}
}

return value($default);
return $default;
}
}
6 changes: 4 additions & 2 deletions src/Traits/HasExportAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
namespace Zuko\Flex2Cell\Traits;


use Zuko\Flex2Cell\Contracts\FormatterInterface;

/**
* Class HasExportAttributes
*
Expand All @@ -53,7 +55,7 @@ trait HasExportAttributes
public function setFormatters(array $formatters)
{
foreach ($formatters as $key => $formatter) {
if (is_string($formatter) && class_exists($formatter)) {
if (is_string($formatter) && class_exists($formatter) &&(new $formatter()) instanceof FormatterInterface) {
$formatter = new $formatter();
}
if (is_object($formatter) && method_exists($formatter, 'formatValue')) {
Expand Down Expand Up @@ -82,7 +84,7 @@ public function setFormatters(array $formatters)
protected function formatValue($mappingKey, $value)
{
if (isset($this->formatters[$mappingKey])) {
return call_user_func($this->formatters[$mappingKey], $value);
return call_user_func($this->formatters[$mappingKey], [$value, $mappingKey]);
}
if (method_exists($this, 'format' . str_replace('.', '', ucwords($mappingKey, '.')) . 'Attribute')) {
return $this->{'format' . str_replace('.', '', ucwords($mappingKey, '.')) . 'Attribute'}($value);
Expand Down
41 changes: 33 additions & 8 deletions src/Traits/HasExportMerging.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,42 @@ protected function applyMerging($sheet)
}
protected function applyColumnMerging($sheet)
{
$mergedRanges = [];
$hasShifted = false;
foreach ($this->columnMergeRules as $rule) {
$startColumn = $rule['start'];
$endColumn = $rule['end'];
$sheet->mergeCells($startColumn . '1:' . $endColumn . '1');
$sheet->setCellValue($startColumn . '1', $rule['label']);
if ($rule['shiftDown']) {
$sheet->insertNewRowBefore(2);
for ($col = Coordinate::columnIndexFromString($startColumn);$col <= Coordinate::columnIndexFromString($endColumn);$col++) {
$letter = Coordinate::stringFromColumnIndex($col);
$originalHeader = $sheet->getCell($letter . '3')->getValue();
$sheet->setCellValue($letter . '2', $originalHeader);
$targetRow = $this->headerRowIndex;
if ($rule['shiftDown'] ?? false) {
// Insert a new row above the current header row
if(!$hasShifted) {
$sheet->insertNewRowBefore($this->headerRowIndex);
$this->headerRowIndex++;
$targetRow = ($this->headerRowIndex - 1);
$hasShifted = true;
}
// Set the merged header value
$sheet->setCellValue($startColumn . $targetRow, $rule['label']);

// Merge the cells
$sheet->mergeCells($startColumn . $targetRow . ':' . $endColumn . $targetRow);
$startColumn = Coordinate::columnIndexFromString($startColumn);
$endColumn = Coordinate::columnIndexFromString($endColumn);
if(!in_array($ranges = range($startColumn, $endColumn), $mergedRanges, true)){
$mergedRanges[] = $ranges;
}
} else {
// If not shifting down, merge at the current header row
$sheet->mergeCells($startColumn . $this->headerRowIndex . ':' . $endColumn . $this->headerRowIndex);
$sheet->setCellValue($startColumn . $this->headerRowIndex, $rule['label']);
}
}
if($hasShifted){
$flat = array_merge(...$mergedRanges);
foreach ($this->headers as $index => $header) {
if(!in_array($index, $flat, true)){
$curLetter = Coordinate::stringFromColumnIndex($index);
$sheet->mergeCells($curLetter . $this->headerRowIndex . ':' . $curLetter . ($this->headerRowIndex - 1));
}
}
}
Expand Down

0 comments on commit c7622e1

Please sign in to comment.