Loading src/Calc.php +7 −0 Original line number Diff line number Diff line Loading @@ -114,4 +114,11 @@ class Calc 'row' => (int)$row, ]; } public static function coordsToCellName(int $col, int $row): string { return self::numberToLetter($col).(string)$row; } } No newline at end of file src/Calc/Cell.php +4 −12 Original line number Diff line number Diff line Loading @@ -7,20 +7,12 @@ use DOMNode; class Cell { /** * @var DOMNode */ private $node; private DOMNode $node; /** * @var int */ private $row; private int $row = 1; private int $col = 1; /** * @var int */ private $col; Loading src/Calc/Sheet.php +69 −50 Original line number Diff line number Diff line Loading @@ -9,40 +9,25 @@ use DOMNode; class Sheet { /** * @var Calc */ private Calc $calc; /** * @var int */ private int $index; /** * @var DOMNode */ private $node; private DOMNode $node; /** * @var Cell[][] */ private $cellTab; private array $cells = []; /** * @var Cell[] */ private $cells; private array $cellsByName = []; /** * @var int */ private $maxCol = 0; private int $maxCol = 0; /** * @var int */ private $maxRow = 0; private int $maxRow = 0; Loading @@ -68,8 +53,8 @@ class Sheet public function read() { $this->cellTab = []; $this->cells = []; $this->cellsByName = []; $this->maxRow = 0; $this->maxCol = 0; $rowIndex = 1; Loading @@ -93,36 +78,59 @@ class Sheet { $cells = $rowNode->childNodes; $col = 1; echo '<h2>ROW ' . $row . '</h2>'; xmlDump($rowNode); foreach ($cells as $c) { if ('table:covered-table-cell' == $c->tagName) { $covered = (int)$c->attributes->getNamedItem('number-columns-repeated')?->value ?: 1; $col += $covered; } if ('table:table-cell' == $c->tagName) { $cell = new Cell($c); if ($r = $cell->getRepeated()){ $col += $r; if ($repeated = $cell->getRepeated()) { $col += $repeated; continue; } $init = true; for ($c = 0; $c < $cell->getColSpan(); $c++) { while ($this->hasCellByCoords($col, $row)) { $col++; } for ($r = 0; $r < $cell->getRowSpan(); $r++) { if (!isset($this->cellTab[$col])) { $this->cellTab[$col] = []; } $this->cellTab[$col][$row + $r] = $cell; if ($row + $r > $this->maxRow) $this->maxRow = $row + $r; if ($col > $this->maxCol) $this->maxCol = $col; if ($init) { $colSpan = $cell->getColSpan(); $rowSpan = $cell->getRowSpan(); $cell->setCol($col); $cell->setRow($row + $r); $this->cells[$cell->getName()] = $cell; $init = false; $cell->setRow($row); for ($c = 0; $c < $colSpan; $c++) { for ($r = 0; $r < $rowSpan; $r++) { $this->addCell($cell, $col+$c, $row+$r); } } var_dump([ 'col' => $col, 'value' => $cell->getContent(), 'colSpan' => $colSpan, 'rowSpan' => $rowSpan, ]); $col ++; } } } private function addCell(Cell $cell, $col, $row) { if (!isset($this->cells[$col])) { $this->cells[$col] = []; } $this->cells[$col][$row] = $cell; if ($row > $this->maxRow) $this->maxRow = $row; if ($col > $this->maxCol) $this->maxCol = $col; $name = Calc::coordsToCellName($col, $row); $this->cellsByName[$name] = $cell; } Loading @@ -134,15 +142,21 @@ class Sheet public function getCellsByNames(): array { return $this->cellsByName; } public function getRefCells(Cell $cell, $recursive = false): array { $refs = []; $formule = $cell->getFormule(); foreach( $this->cells as $n => $c){ $row = $c->getRow(); $col = Calc::numberToLetter($c->getCol()); foreach ($this->cellsByName as $name => $cell) { ['col' => $col, 'row' => $row] = Calc::cellNameToCoords($name); $variants = [ "[.$col$row]", "[.\$$col$row]", Loading Loading @@ -186,7 +200,7 @@ class Sheet public function hasCellByCoords(int $col, int $row): bool { return array_key_exists($col, $this->cellTab) && array_key_exists($row, $this->cellTab[$col]); return array_key_exists($col, $this->cells) && array_key_exists($row, $this->cells[$col]) && $this->cells[$col][$row] instanceof Cell; } Loading @@ -194,7 +208,7 @@ class Sheet public function getCellByCoords(int $col, int $row): ?Cell { if ($this->hasCellByCoords($col, $row)) { return $this->cellTab[$col][$row]; return $this->cells[$col][$row]; } return null; Loading @@ -204,18 +218,18 @@ class Sheet public function hasCell(string $name): bool { return array_key_exists($name, $this->cells); ['col' => $col, 'row' => $row] = Calc::cellNameToCoords($name); return $this->hasCellByCoords($col, $row); } public function getCell(string $name): ?Cell { if ($this->hasCell($name)) { return $this->cells[$name]; } ['col' => $col, 'row' => $row] = Calc::cellNameToCoords($name); return null; return $this->getCellByCoords($col, $row); } Loading @@ -232,7 +246,11 @@ class Sheet $h .= '<tr><th>' . $r . '</th>'; for ($c = 1; $c <= $this->getMaxCol(); $c++) { $cell = $this->getCellByCoords($c, $r); $h .= '<td>'.($cell ? $cell->getContent() : '').'</td>'; if ($cell && $cell->getRow() == $r && $cell->getCol() == $c) { $h .= '<td rowspan="' . $cell->getRowSpan() . '" colspan="' . $cell->getColSpan() . '">' . ($cell ? $cell->getContent() : '') . '</td>'; }elseif(!$cell){ $h .= '<td></td>'; } } $h .= '</tr>'; } Loading @@ -241,4 +259,5 @@ class Sheet return $h; } } No newline at end of file Loading
src/Calc.php +7 −0 Original line number Diff line number Diff line Loading @@ -114,4 +114,11 @@ class Calc 'row' => (int)$row, ]; } public static function coordsToCellName(int $col, int $row): string { return self::numberToLetter($col).(string)$row; } } No newline at end of file
src/Calc/Cell.php +4 −12 Original line number Diff line number Diff line Loading @@ -7,20 +7,12 @@ use DOMNode; class Cell { /** * @var DOMNode */ private $node; private DOMNode $node; /** * @var int */ private $row; private int $row = 1; private int $col = 1; /** * @var int */ private $col; Loading
src/Calc/Sheet.php +69 −50 Original line number Diff line number Diff line Loading @@ -9,40 +9,25 @@ use DOMNode; class Sheet { /** * @var Calc */ private Calc $calc; /** * @var int */ private int $index; /** * @var DOMNode */ private $node; private DOMNode $node; /** * @var Cell[][] */ private $cellTab; private array $cells = []; /** * @var Cell[] */ private $cells; private array $cellsByName = []; /** * @var int */ private $maxCol = 0; private int $maxCol = 0; /** * @var int */ private $maxRow = 0; private int $maxRow = 0; Loading @@ -68,8 +53,8 @@ class Sheet public function read() { $this->cellTab = []; $this->cells = []; $this->cellsByName = []; $this->maxRow = 0; $this->maxCol = 0; $rowIndex = 1; Loading @@ -93,36 +78,59 @@ class Sheet { $cells = $rowNode->childNodes; $col = 1; echo '<h2>ROW ' . $row . '</h2>'; xmlDump($rowNode); foreach ($cells as $c) { if ('table:covered-table-cell' == $c->tagName) { $covered = (int)$c->attributes->getNamedItem('number-columns-repeated')?->value ?: 1; $col += $covered; } if ('table:table-cell' == $c->tagName) { $cell = new Cell($c); if ($r = $cell->getRepeated()){ $col += $r; if ($repeated = $cell->getRepeated()) { $col += $repeated; continue; } $init = true; for ($c = 0; $c < $cell->getColSpan(); $c++) { while ($this->hasCellByCoords($col, $row)) { $col++; } for ($r = 0; $r < $cell->getRowSpan(); $r++) { if (!isset($this->cellTab[$col])) { $this->cellTab[$col] = []; } $this->cellTab[$col][$row + $r] = $cell; if ($row + $r > $this->maxRow) $this->maxRow = $row + $r; if ($col > $this->maxCol) $this->maxCol = $col; if ($init) { $colSpan = $cell->getColSpan(); $rowSpan = $cell->getRowSpan(); $cell->setCol($col); $cell->setRow($row + $r); $this->cells[$cell->getName()] = $cell; $init = false; $cell->setRow($row); for ($c = 0; $c < $colSpan; $c++) { for ($r = 0; $r < $rowSpan; $r++) { $this->addCell($cell, $col+$c, $row+$r); } } var_dump([ 'col' => $col, 'value' => $cell->getContent(), 'colSpan' => $colSpan, 'rowSpan' => $rowSpan, ]); $col ++; } } } private function addCell(Cell $cell, $col, $row) { if (!isset($this->cells[$col])) { $this->cells[$col] = []; } $this->cells[$col][$row] = $cell; if ($row > $this->maxRow) $this->maxRow = $row; if ($col > $this->maxCol) $this->maxCol = $col; $name = Calc::coordsToCellName($col, $row); $this->cellsByName[$name] = $cell; } Loading @@ -134,15 +142,21 @@ class Sheet public function getCellsByNames(): array { return $this->cellsByName; } public function getRefCells(Cell $cell, $recursive = false): array { $refs = []; $formule = $cell->getFormule(); foreach( $this->cells as $n => $c){ $row = $c->getRow(); $col = Calc::numberToLetter($c->getCol()); foreach ($this->cellsByName as $name => $cell) { ['col' => $col, 'row' => $row] = Calc::cellNameToCoords($name); $variants = [ "[.$col$row]", "[.\$$col$row]", Loading Loading @@ -186,7 +200,7 @@ class Sheet public function hasCellByCoords(int $col, int $row): bool { return array_key_exists($col, $this->cellTab) && array_key_exists($row, $this->cellTab[$col]); return array_key_exists($col, $this->cells) && array_key_exists($row, $this->cells[$col]) && $this->cells[$col][$row] instanceof Cell; } Loading @@ -194,7 +208,7 @@ class Sheet public function getCellByCoords(int $col, int $row): ?Cell { if ($this->hasCellByCoords($col, $row)) { return $this->cellTab[$col][$row]; return $this->cells[$col][$row]; } return null; Loading @@ -204,18 +218,18 @@ class Sheet public function hasCell(string $name): bool { return array_key_exists($name, $this->cells); ['col' => $col, 'row' => $row] = Calc::cellNameToCoords($name); return $this->hasCellByCoords($col, $row); } public function getCell(string $name): ?Cell { if ($this->hasCell($name)) { return $this->cells[$name]; } ['col' => $col, 'row' => $row] = Calc::cellNameToCoords($name); return null; return $this->getCellByCoords($col, $row); } Loading @@ -232,7 +246,11 @@ class Sheet $h .= '<tr><th>' . $r . '</th>'; for ($c = 1; $c <= $this->getMaxCol(); $c++) { $cell = $this->getCellByCoords($c, $r); $h .= '<td>'.($cell ? $cell->getContent() : '').'</td>'; if ($cell && $cell->getRow() == $r && $cell->getCol() == $c) { $h .= '<td rowspan="' . $cell->getRowSpan() . '" colspan="' . $cell->getColSpan() . '">' . ($cell ? $cell->getContent() : '') . '</td>'; }elseif(!$cell){ $h .= '<td></td>'; } } $h .= '</tr>'; } Loading @@ -241,4 +259,5 @@ class Sheet return $h; } } No newline at end of file