Skip to content

Commit

Permalink
patch
Browse files Browse the repository at this point in the history
  • Loading branch information
AnourValar committed Apr 28, 2023
1 parent 04a44eb commit e170099
Show file tree
Hide file tree
Showing 9 changed files with 850 additions and 555 deletions.
8 changes: 5 additions & 3 deletions src/Drivers/PhpSpreadsheetDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

class PhpSpreadsheetDriver implements SheetsInterface, GridInterface, MixInterface
{
use \AnourValar\Office\Traits\Parser;

/**
* @var string
*/
Expand Down Expand Up @@ -526,8 +528,8 @@ public function duplicateRows(string $ceilRange, callable $value, int $indentRow
if (
$item[0][1] >= $range[0][1] && $item[0][1] <= $range[1][1] // rows
&& $item[1][1] >= $range[0][1] && $item[1][1] <= $range[1][1]
&& $item[0][0] >= $range[0][0] && $item[0][0] <= $range[1][0] // columns
&& $item[1][0] >= $range[0][0] && $item[1][0] <= $range[1][0]
&& $this->isColumnGE($item[0][0], $range[0][0]) && $this->isColumnLE($item[0][0], $range[1][0]) // columns
&& $this->isColumnGE($item[1][0], $range[0][0]) && $this->isColumnLE($item[1][0], $range[1][0])
) {
$this->mergeCells($item[0][0].($item[0][1]+$shift) . ':' . $item[1][0].($item[1][1]+$shift));
}
Expand All @@ -540,7 +542,7 @@ public function duplicateRows(string $ceilRange, callable $value, int $indentRow

// Style, CellFormat, Value
$column = $range[0][0];
while ($column <= $range[1][0]) {
while ($this->isColumnLE($column, $range[1][0])) {
$this->copyStyle($column . $curr, $column . ($curr + $shift));
$this->copyCellFormat($column . $curr, $column . ($curr + $shift));

Expand Down
5 changes: 3 additions & 2 deletions src/Drivers/ZipDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class ZipDriver implements DocumentInterface, GridInterface
{
use \Anourvalar\Office\Traits\Parser;
use \AnourValar\Office\Traits\XFormat;

/**
Expand Down Expand Up @@ -192,7 +193,7 @@ public function setGrid(iterable $data): self

if ($value === null || $value === '') {

if ($column >= $firstColumn) {
if ($this->isColumnGE($column, $firstColumn)) {
$sheet .= '<c r="'.$column.$row.'" s="'.($styles[$column] ?? $styles['string']).'"/>';
}

Expand Down Expand Up @@ -239,7 +240,7 @@ public function setGrid(iterable $data): self
// Columns
$column = 'A';
for ($index = 1; $index <= $columnsCount; $index++) {
if ($column >= $firstColumn) {
if ($this->isColumnGE($column, $firstColumn)) {
$width = ($this->gridOptions['width'][$column] ?? 20);
$cols .= '<col min="'.$index.'" max="'.$index.'" width="'.$width.'" customWidth="1"/>';
}
Expand Down
6 changes: 4 additions & 2 deletions src/GridService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

class GridService
{
use \AnourValar\Office\Traits\Parser;

/**
* @var \AnourValar\Office\Drivers\GridInterface
*/
Expand Down Expand Up @@ -198,7 +200,7 @@ protected function getGenerator(
// left top corner: column
$firstColumn = 'A';
$indent = [];
while ($firstColumn < $ltc[0]) {
while ($this->isColumnLE($firstColumn, $ltc[0]) && $firstColumn != $ltc[0]) {
$firstColumn++;
$indent[] = '';
}
Expand Down Expand Up @@ -285,7 +287,7 @@ protected function getGenerator(
if ($totalRange) {
$keys = array_keys($headers);

while ($firstColumn <= $lastColumn) {
while ($this->isColumnLE($firstColumn, $lastColumn)) {
if (! $keys) {
$columns[] = $firstColumn;
} else {
Expand Down
66 changes: 56 additions & 10 deletions src/Sheets/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ public function schema(array $values, array $data, array $mergeCells): SchemaMap
$schema = new SchemaMapper();

// Step 0: Parse input arguments to a canon format
$values = $this->parseValues($values);
$values = $this->parseValues($values, $lastColumn);
$data = $this->parseData($data);
$mergeCells = $this->parseMergeCells($mergeCells);

// Step 1: Short path -> full path
$this->canonizeMarkers($values, $data);

// Step 2: Calculate additional rows & columns, redundant data
$dataSchema = $this->calculateDataSchema($values, $data, $mergeCells, $schema);
$dataSchema = $this->calculateDataSchema($values, $data, $mergeCells, $schema, $lastColumn);

// Step 3: Shift formulas
$this->shiftFormulas($dataSchema, $schema, $mergeCells);
Expand All @@ -55,11 +55,21 @@ public function schema(array $values, array $data, array $mergeCells): SchemaMap

/**
* @param array $values
* @param mixed $lastColumn
* @return array
*/
protected function parseValues(array $values): array
protected function parseValues(array $values, &$lastColumn): array
{
ksort($values); // just in case ;)
$lastColumn = 'A';
foreach ($values as $row => &$columns) {
$currLastColumn = array_key_last($columns);
if ($this->isColumnLE($lastColumn, $currLastColumn)) {
$lastColumn = $currLastColumn;
}

$columns = array_filter($columns, fn ($item) => $item !== null && $item !== '');
}
unset($columns);

return $values;
}
Expand Down Expand Up @@ -167,10 +177,15 @@ function ($patterns) use ($data) {
* @param array $data
* @param array $mergeCells
* @param \AnourValar\Office\Sheets\SchemaMapper $schema
* @param string $lastColumn
* @return array
*/
protected function calculateDataSchema(array &$values, array &$data, array &$mergeCells, SchemaMapper &$schema): array
{
protected function calculateDataSchema(
array &$values, array &$data,
array &$mergeCells,
SchemaMapper &$schema,
string $lastColumn
): array {
$dataSchema = [];
$shift = 0;
$step = 0;
Expand Down Expand Up @@ -260,7 +275,7 @@ protected function calculateDataSchema(array &$values, array &$data, array &$mer
$mergeMapX = [];
foreach ($mergeCells as $item) {
if ($additionColumn.($row + $shift) == $item[0][0].$item[0][1] && $item[0][1] == $item[1][1]) {
while ($item[0][0] < $item[1][0]) {
while ($this->isColumnLE($item[0][0], $item[1][0]) && $item[0][0] != $item[1][0]) {
$item[0][0]++;
$mergeMapX[] = $item[0][0];
}
Expand All @@ -278,7 +293,6 @@ protected function calculateDataSchema(array &$values, array &$data, array &$mer
$additionColumnValue = $this->increments($additionColumnValue, false);
$columns[$curr] = $additionColumnValue;
$schema->copyStyle($additionColumn.($row + $shift), $curr.($row + $shift));
$schema->copyCellFormat($additionColumn.($row + $shift), $curr.($row + $shift));
$schema->copyWidth($additionColumn, $curr);

if ($mergeMapX) {
Expand All @@ -294,10 +308,20 @@ protected function calculateDataSchema(array &$values, array &$data, array &$mer
}
}

$dataSchema[$row + $shift] = array_filter($columns, fn ($item) => $item !== null && $item !== '');
$dataSchema[$row + $shift] = $columns;
$originalRow = ($row + $shift);

if ($additionRows) {
$firstColumn = 'A';
while ($this->isColumnLE($firstColumn, $lastColumn)) {
if (! isset($columns[$firstColumn]) && ! $this->insideMerge($firstColumn, $originalRow, $mergeCells)) {
$columns[$firstColumn] = null;
}

$firstColumn++;
}
uksort($columns, fn ($a, $b) => $this->isColumnLE($a, $b) ? -1 : 1);

foreach ($columns as $currKey => $currValue) {
$hasMarker = preg_match('#\[([a-z][a-z\d\.\_]+)\]#iS', (string) $currValue);

Expand Down Expand Up @@ -335,7 +359,6 @@ protected function calculateDataSchema(array &$values, array &$data, array &$mer

foreach (array_keys($columns) as $curr) {
$schema->copyStyle($curr.$originalRow, $curr.($row + $shift));
$schema->copyCellFormat($curr.$originalRow, $curr.($row + $shift));

foreach ($mergeCells as $item) {
if ($curr.$originalRow == $item[0][0].$item[0][1]) {
Expand Down Expand Up @@ -755,4 +778,27 @@ private function deleteRow(SchemaMapper &$schema, array &$mergeCells, int $row):
}
unset($mergeCell);
}

/**
* @param string $column
* @param int $row
* @param array $mergeCells
* @return bool
*/
private function insideMerge(string $column, int $row, array &$mergeCells): bool
{
foreach ($mergeCells as $item) {
if (
$this->isColumnLE($item[0][0], $column)
&& $this->isColumnGE($item[1][0], $column)
&& $item[0][1] <= $row
&& $item[1][1] >= $row
&& ($item[0][0] != $column || $item[0][1] != $row)
) {
return true;
}
}

return false;
}
}
16 changes: 0 additions & 16 deletions src/Sheets/SchemaMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ class SchemaMapper
'merge_cells' => [], //[ 'A1:B1', 'C1:D1']

'copy_width' => [], //[ ['from' => 'B', 'to' => 'C'] ]

'copy_cell_format' => [], //[ ['from' => 'A1', 'to' => 'A2'] ]
];

/**
Expand All @@ -34,8 +32,6 @@ public function toArray(): array

sort($this->payload['copy_width']);

$this->normalizeCells($this->payload['copy_cell_format']);

return $this->payload;
}

Expand Down Expand Up @@ -117,18 +113,6 @@ public function copyWidth(string $from, string $to): self
return $this;
}

/**
* @param string $from
* @param string $to
* @return self
*/
public function copyCellFormat(string $from, string $to): self
{
$this->payload['copy_cell_format'][$from.$to] = ['from' => $from, 'to' => $to];

return $this;
}

/**
* @param array $rows
* @return void
Expand Down
13 changes: 5 additions & 8 deletions src/SheetsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,13 @@ protected function handleSheet(SheetsInterface &$driver, array &$data, int $shee
}
}

// Copy style
// Copy style & cell format
foreach ($schema['copy_style'] as $item) {
$driver->copyStyle($item['from'], $item['to']);

if (! $autoCellFormat) {
$driver->copyCellFormat($item['from'], $item['to']);
}
}

// Merge cells
Expand All @@ -194,13 +198,6 @@ protected function handleSheet(SheetsInterface &$driver, array &$data, int $shee
$driver->copyWidth($item['from'], $item['to']);
}

// Copy cell format
if (! $autoCellFormat) {
foreach ($schema['copy_cell_format'] as $item) {
$driver->copyCellFormat($item['from'], $item['to']);
}
}

// Data
$driver->setValues($this->handleData($schema['data'], $driver, $sheetIndex), $autoCellFormat);
}
Expand Down
42 changes: 42 additions & 0 deletions src/Traits/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,46 @@ protected function dot(array $data, string $prefix = ''): array

return $result;
}

/**
* @param string $compareColumn
* @param string $referenceColumn
* @return bool
*/
protected function isColumnLE(string $compareColumn, string $referenceColumn): bool
{
$compareLength = strlen($compareColumn);
$referenceLength = strlen($referenceColumn);

if ($compareLength < $referenceLength) {
return true;
}

if ($compareLength > $referenceLength) {
return false;
}

return $compareColumn <= $referenceColumn;
}

/**
* @param string $compareColumn
* @param string $referenceColumn
* @return bool
*/
protected function isColumnGE(string $compareColumn, string $referenceColumn): bool
{
$compareLength = strlen($compareColumn);
$referenceLength = strlen($referenceColumn);

if ($compareLength > $referenceLength) {
return true;
}

if ($compareLength < $referenceLength) {
return false;
}

return $compareColumn >= $referenceColumn;
}
}
Loading

0 comments on commit e170099

Please sign in to comment.