|
7 | 7 | use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
8 | 8 | use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
9 | 9 | use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter;
|
| 10 | +use PhpOffice\PhpSpreadsheet\Worksheet\Table; |
10 | 11 | use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
11 | 12 |
|
12 | 13 | class ReferenceHelper
|
@@ -497,6 +498,9 @@ function ($coordinate) use ($allCoordinates) {
|
497 | 498 | // Update worksheet: autofilter
|
498 | 499 | $this->adjustAutoFilter($worksheet, $beforeCellAddress, $numberOfColumns);
|
499 | 500 |
|
| 501 | + // Update worksheet: table |
| 502 | + $this->adjustTable($worksheet, $beforeCellAddress, $numberOfColumns); |
| 503 | + |
500 | 504 | // Update worksheet: freeze pane
|
501 | 505 | if ($worksheet->getFreezePane()) {
|
502 | 506 | $splitCell = $worksheet->getFreezePane() ?? '';
|
@@ -1026,6 +1030,85 @@ private function adjustAutoFilterDelete(int $startCol, int $numberOfColumns, int
|
1026 | 1030 | } while ($startColID !== $endColID);
|
1027 | 1031 | }
|
1028 | 1032 |
|
| 1033 | + private function adjustTable(Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns): void |
| 1034 | + { |
| 1035 | + $tableCollection = $worksheet->getTableCollection(); |
| 1036 | + |
| 1037 | + foreach ($tableCollection as $table) { |
| 1038 | + $tableRange = $table->getRange(); |
| 1039 | + if (!empty($tableRange)) { |
| 1040 | + if ($numberOfColumns !== 0) { |
| 1041 | + $tableColumns = $table->getColumns(); |
| 1042 | + if (count($tableColumns) > 0) { |
| 1043 | + $column = ''; |
| 1044 | + $row = 0; |
| 1045 | + sscanf($beforeCellAddress, '%[A-Z]%d', $column, $row); |
| 1046 | + $columnIndex = Coordinate::columnIndexFromString($column); |
| 1047 | + [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($tableRange); |
| 1048 | + if ($columnIndex <= $rangeEnd[0]) { |
| 1049 | + if ($numberOfColumns < 0) { |
| 1050 | + $this->adjustTableDeleteRules($columnIndex, $numberOfColumns, $tableColumns, $table); |
| 1051 | + } |
| 1052 | + $startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0]; |
| 1053 | + |
| 1054 | + // Shuffle columns in table range |
| 1055 | + if ($numberOfColumns > 0) { |
| 1056 | + $this->adjustTableInsert($startCol, $numberOfColumns, $rangeEnd[0], $table); |
| 1057 | + } else { |
| 1058 | + $this->adjustTableDelete($startCol, $numberOfColumns, $rangeEnd[0], $table); |
| 1059 | + } |
| 1060 | + } |
| 1061 | + } |
| 1062 | + } |
| 1063 | + |
| 1064 | + $table->setRange($this->updateCellReference($tableRange)); |
| 1065 | + } |
| 1066 | + } |
| 1067 | + } |
| 1068 | + |
| 1069 | + private function adjustTableDeleteRules(int $columnIndex, int $numberOfColumns, array $tableColumns, Table $table): void |
| 1070 | + { |
| 1071 | + // If we're actually deleting any columns that fall within the table range, |
| 1072 | + // then we delete any rules for those columns |
| 1073 | + $deleteColumn = $columnIndex + $numberOfColumns - 1; |
| 1074 | + $deleteCount = abs($numberOfColumns); |
| 1075 | + |
| 1076 | + for ($i = 1; $i <= $deleteCount; ++$i) { |
| 1077 | + $columnName = Coordinate::stringFromColumnIndex($deleteColumn + 1); |
| 1078 | + if (isset($tableColumns[$columnName])) { |
| 1079 | + $table->clearColumn($columnName); |
| 1080 | + } |
| 1081 | + ++$deleteColumn; |
| 1082 | + } |
| 1083 | + } |
| 1084 | + |
| 1085 | + private function adjustTableInsert(int $startCol, int $numberOfColumns, int $rangeEnd, Table $table): void |
| 1086 | + { |
| 1087 | + $startColRef = $startCol; |
| 1088 | + $endColRef = $rangeEnd; |
| 1089 | + $toColRef = $rangeEnd + $numberOfColumns; |
| 1090 | + |
| 1091 | + do { |
| 1092 | + $table->shiftColumn(Coordinate::stringFromColumnIndex($endColRef), Coordinate::stringFromColumnIndex($toColRef)); |
| 1093 | + --$endColRef; |
| 1094 | + --$toColRef; |
| 1095 | + } while ($startColRef <= $endColRef); |
| 1096 | + } |
| 1097 | + |
| 1098 | + private function adjustTableDelete(int $startCol, int $numberOfColumns, int $rangeEnd, Table $table): void |
| 1099 | + { |
| 1100 | + // For delete, we shuffle from beginning to end to avoid overwriting |
| 1101 | + $startColID = Coordinate::stringFromColumnIndex($startCol); |
| 1102 | + $toColID = Coordinate::stringFromColumnIndex($startCol + $numberOfColumns); |
| 1103 | + $endColID = Coordinate::stringFromColumnIndex($rangeEnd + 1); |
| 1104 | + |
| 1105 | + do { |
| 1106 | + $table->shiftColumn($startColID, $toColID); |
| 1107 | + ++$startColID; |
| 1108 | + ++$toColID; |
| 1109 | + } while ($startColID !== $endColID); |
| 1110 | + } |
| 1111 | + |
1029 | 1112 | private function duplicateStylesByColumn(Worksheet $worksheet, int $beforeColumn, int $beforeRow, int $highestRow, int $numberOfColumns): void
|
1030 | 1113 | {
|
1031 | 1114 | $beforeColumnName = Coordinate::stringFromColumnIndex($beforeColumn - 1);
|
|
0 commit comments