55use PhpOffice \PhpSpreadsheet \Calculation \Calculation ;
66use PhpOffice \PhpSpreadsheet \Cell \Coordinate ;
77use PhpOffice \PhpSpreadsheet \Cell \DataType ;
8+ use PhpOffice \PhpSpreadsheet \Worksheet \AutoFilter ;
89use PhpOffice \PhpSpreadsheet \Worksheet \Worksheet ;
910
1011class ReferenceHelper
@@ -358,8 +359,12 @@ protected function adjustRowDimensions(Worksheet $worksheet, $beforeCellAddress,
358359 * @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
359360 * @param Worksheet $worksheet The worksheet that we're editing
360361 */
361- public function insertNewBefore ($ beforeCellAddress , $ numberOfColumns , $ numberOfRows , Worksheet $ worksheet ): void
362- {
362+ public function insertNewBefore (
363+ string $ beforeCellAddress ,
364+ int $ numberOfColumns ,
365+ int $ numberOfRows ,
366+ Worksheet $ worksheet
367+ ): void {
363368 $ remove = ($ numberOfColumns < 0 || $ numberOfRows < 0 );
364369 $ allCoordinates = $ worksheet ->getCoordinates ();
365370
@@ -448,49 +453,11 @@ function ($coordinate) use ($allCoordinates) {
448453 $ highestRow = $ worksheet ->getHighestRow ();
449454
450455 if ($ numberOfColumns > 0 && $ beforeColumn - 2 > 0 ) {
451- $ beforeColumnName = Coordinate::stringFromColumnIndex ($ beforeColumn - 1 );
452- for ($ i = $ beforeRow ; $ i <= $ highestRow - 1 ; ++$ i ) {
453- // Style
454- $ coordinate = $ beforeColumnName . $ i ;
455- if ($ worksheet ->cellExists ($ coordinate )) {
456- $ xfIndex = $ worksheet ->getCell ($ coordinate )->getXfIndex ();
457- $ conditionalStyles = $ worksheet ->conditionalStylesExists ($ coordinate ) ?
458- $ worksheet ->getConditionalStyles ($ coordinate ) : false ;
459- for ($ j = $ beforeColumn ; $ j <= $ beforeColumn - 1 + $ numberOfColumns ; ++$ j ) {
460- $ worksheet ->getCellByColumnAndRow ($ j , $ i )->setXfIndex ($ xfIndex );
461- if ($ conditionalStyles ) {
462- $ cloned = [];
463- foreach ($ conditionalStyles as $ conditionalStyle ) {
464- $ cloned [] = clone $ conditionalStyle ;
465- }
466- $ worksheet ->setConditionalStyles (Coordinate::stringFromColumnIndex ($ j ) . $ i , $ cloned );
467- }
468- }
469- }
470- }
456+ $ this ->duplicateStylesByColumn ($ worksheet , $ beforeColumn , $ beforeRow , $ highestRow , $ numberOfColumns );
471457 }
472458
473459 if ($ numberOfRows > 0 && $ beforeRow - 1 > 0 ) {
474- $ highestColumnIndex = Coordinate::columnIndexFromString ($ highestColumn );
475- for ($ i = $ beforeColumn ; $ i <= $ highestColumnIndex ; ++$ i ) {
476- // Style
477- $ coordinate = Coordinate::stringFromColumnIndex ($ i ) . ($ beforeRow - 1 );
478- if ($ worksheet ->cellExists ($ coordinate )) {
479- $ xfIndex = $ worksheet ->getCell ($ coordinate )->getXfIndex ();
480- $ conditionalStyles = $ worksheet ->conditionalStylesExists ($ coordinate ) ?
481- $ worksheet ->getConditionalStyles ($ coordinate ) : false ;
482- for ($ j = $ beforeRow ; $ j <= $ beforeRow - 1 + $ numberOfRows ; ++$ j ) {
483- $ worksheet ->getCell (Coordinate::stringFromColumnIndex ($ i ) . $ j )->setXfIndex ($ xfIndex );
484- if ($ conditionalStyles ) {
485- $ cloned = [];
486- foreach ($ conditionalStyles as $ conditionalStyle ) {
487- $ cloned [] = clone $ conditionalStyle ;
488- }
489- $ worksheet ->setConditionalStyles (Coordinate::stringFromColumnIndex ($ i ) . $ j , $ cloned );
490- }
491- }
492- }
493- }
460+ $ this ->duplicateStylesByRow ($ worksheet , $ beforeColumn , $ beforeRow , $ highestColumn , $ numberOfRows );
494461 }
495462
496463 // Update worksheet: column dimensions
@@ -533,7 +500,9 @@ function ($coordinate) use ($allCoordinates) {
533500
534501 // Page setup
535502 if ($ worksheet ->getPageSetup ()->isPrintAreaSet ()) {
536- $ worksheet ->getPageSetup ()->setPrintArea ($ this ->updateCellReference ($ worksheet ->getPageSetup ()->getPrintArea (), $ beforeCellAddress , $ numberOfColumns , $ numberOfRows ));
503+ $ worksheet ->getPageSetup ()->setPrintArea (
504+ $ this ->updateCellReference ($ worksheet ->getPageSetup ()->getPrintArea (), $ beforeCellAddress , $ numberOfColumns , $ numberOfRows )
505+ );
537506 }
538507
539508 // Update worksheet: drawings
@@ -880,7 +849,7 @@ public function updateNamedFormulas(Spreadsheet $spreadsheet, $oldName = '', $ne
880849 foreach ($ spreadsheet ->getWorksheetIterator () as $ sheet ) {
881850 foreach ($ sheet ->getCoordinates (false ) as $ coordinate ) {
882851 $ cell = $ sheet ->getCell ($ coordinate );
883- if (($ cell !== null ) && ($ cell ->getDataType () == DataType::TYPE_FORMULA )) {
852+ if (($ cell !== null ) && ($ cell ->getDataType () === DataType::TYPE_FORMULA )) {
884853 $ formula = $ cell ->getValue ();
885854 if (strpos ($ formula , $ oldName ) !== false ) {
886855 $ formula = str_replace ("' " . $ oldName . "'! " , "' " . $ newName . "'! " , $ formula );
@@ -1005,7 +974,7 @@ private function adjustAutoFilter(Worksheet $worksheet, string $beforeCellAddres
1005974 $ autoFilter = $ worksheet ->getAutoFilter ();
1006975 $ autoFilterRange = $ autoFilter ->getRange ();
1007976 if (!empty ($ autoFilterRange )) {
1008- if ($ numberOfColumns != 0 ) {
977+ if ($ numberOfColumns !== 0 ) {
1009978 $ autoFilterColumns = $ autoFilter ->getColumns ();
1010979 if (count ($ autoFilterColumns ) > 0 ) {
1011980 $ column = '' ;
@@ -1015,45 +984,114 @@ private function adjustAutoFilter(Worksheet $worksheet, string $beforeCellAddres
1015984 [$ rangeStart , $ rangeEnd ] = Coordinate::rangeBoundaries ($ autoFilterRange );
1016985 if ($ columnIndex <= $ rangeEnd [0 ]) {
1017986 if ($ numberOfColumns < 0 ) {
1018- // If we're actually deleting any columns that fall within the autofilter range,
1019- // then we delete any rules for those columns
1020- $ deleteColumn = $ columnIndex + $ numberOfColumns - 1 ;
1021- $ deleteCount = abs ($ numberOfColumns );
1022- for ($ i = 1 ; $ i <= $ deleteCount ; ++$ i ) {
1023- if (isset ($ autoFilterColumns [Coordinate::stringFromColumnIndex ($ deleteColumn + 1 )])) {
1024- $ autoFilter ->clearColumn (Coordinate::stringFromColumnIndex ($ deleteColumn + 1 ));
1025- }
1026- ++$ deleteColumn ;
1027- }
987+ $ this ->adjustAutoFilterDeleteRules ($ columnIndex , $ numberOfColumns , $ autoFilterColumns , $ autoFilter );
1028988 }
1029989 $ startCol = ($ columnIndex > $ rangeStart [0 ]) ? $ columnIndex : $ rangeStart [0 ];
1030990
1031991 // Shuffle columns in autofilter range
1032992 if ($ numberOfColumns > 0 ) {
1033- $ startColRef = $ startCol ;
1034- $ endColRef = $ rangeEnd [0 ];
1035- $ toColRef = $ rangeEnd [0 ] + $ numberOfColumns ;
1036-
1037- do {
1038- $ autoFilter ->shiftColumn (Coordinate::stringFromColumnIndex ($ endColRef ), Coordinate::stringFromColumnIndex ($ toColRef ));
1039- --$ endColRef ;
1040- --$ toColRef ;
1041- } while ($ startColRef <= $ endColRef );
993+ $ this ->adjustAutoFilterInsert ($ startCol , $ numberOfColumns , $ rangeEnd [0 ], $ autoFilter );
1042994 } else {
1043- // For delete, we shuffle from beginning to end to avoid overwriting
1044- $ startColID = Coordinate::stringFromColumnIndex ($ startCol );
1045- $ toColID = Coordinate::stringFromColumnIndex ($ startCol + $ numberOfColumns );
1046- $ endColID = Coordinate::stringFromColumnIndex ($ rangeEnd [0 ] + 1 );
1047- do {
1048- $ autoFilter ->shiftColumn ($ startColID , $ toColID );
1049- ++$ startColID ;
1050- ++$ toColID ;
1051- } while ($ startColID != $ endColID );
995+ $ this ->adjustAutoFilterDelete ($ startCol , $ numberOfColumns , $ rangeEnd [0 ], $ autoFilter );
996+ }
997+ }
998+ }
999+ }
1000+
1001+ $ worksheet ->setAutoFilter (
1002+ $ this ->updateCellReference ($ autoFilterRange , $ beforeCellAddress , $ numberOfColumns , $ numberOfRows )
1003+ );
1004+ }
1005+ }
1006+
1007+ private function adjustAutoFilterDeleteRules (int $ columnIndex , int $ numberOfColumns , array $ autoFilterColumns , AutoFilter $ autoFilter ): void
1008+ {
1009+ // If we're actually deleting any columns that fall within the autofilter range,
1010+ // then we delete any rules for those columns
1011+ $ deleteColumn = $ columnIndex + $ numberOfColumns - 1 ;
1012+ $ deleteCount = abs ($ numberOfColumns );
1013+
1014+ for ($ i = 1 ; $ i <= $ deleteCount ; ++$ i ) {
1015+ $ columnName = Coordinate::stringFromColumnIndex ($ deleteColumn + 1 );
1016+ if (isset ($ autoFilterColumns [$ columnName ])) {
1017+ $ autoFilter ->clearColumn ($ columnName );
1018+ }
1019+ ++$ deleteColumn ;
1020+ }
1021+ }
1022+
1023+ private function adjustAutoFilterInsert (int $ startCol , int $ numberOfColumns , int $ rangeEnd , AutoFilter $ autoFilter ): void
1024+ {
1025+ $ startColRef = $ startCol ;
1026+ $ endColRef = $ rangeEnd ;
1027+ $ toColRef = $ rangeEnd + $ numberOfColumns ;
1028+
1029+ do {
1030+ $ autoFilter ->shiftColumn (Coordinate::stringFromColumnIndex ($ endColRef ), Coordinate::stringFromColumnIndex ($ toColRef ));
1031+ --$ endColRef ;
1032+ --$ toColRef ;
1033+ } while ($ startColRef <= $ endColRef );
1034+ }
1035+
1036+ private function adjustAutoFilterDelete (int $ startCol , int $ numberOfColumns , int $ rangeEnd , AutoFilter $ autoFilter ): void
1037+ {
1038+ // For delete, we shuffle from beginning to end to avoid overwriting
1039+ $ startColID = Coordinate::stringFromColumnIndex ($ startCol );
1040+ $ toColID = Coordinate::stringFromColumnIndex ($ startCol + $ numberOfColumns );
1041+ $ endColID = Coordinate::stringFromColumnIndex ($ rangeEnd + 1 );
1042+
1043+ do {
1044+ $ autoFilter ->shiftColumn ($ startColID , $ toColID );
1045+ ++$ startColID ;
1046+ ++$ toColID ;
1047+ } while ($ startColID !== $ endColID );
1048+ }
1049+
1050+ private function duplicateStylesByColumn (Worksheet $ worksheet , int $ beforeColumn , int $ beforeRow , int $ highestRow , int $ numberOfColumns ): void
1051+ {
1052+ $ beforeColumnName = Coordinate::stringFromColumnIndex ($ beforeColumn - 1 );
1053+ for ($ i = $ beforeRow ; $ i <= $ highestRow - 1 ; ++$ i ) {
1054+ // Style
1055+ $ coordinate = $ beforeColumnName . $ i ;
1056+ if ($ worksheet ->cellExists ($ coordinate )) {
1057+ $ xfIndex = $ worksheet ->getCell ($ coordinate )->getXfIndex ();
1058+ $ conditionalStyles = $ worksheet ->conditionalStylesExists ($ coordinate ) ?
1059+ $ worksheet ->getConditionalStyles ($ coordinate ) : false ;
1060+ for ($ j = $ beforeColumn ; $ j <= $ beforeColumn - 1 + $ numberOfColumns ; ++$ j ) {
1061+ $ worksheet ->getCellByColumnAndRow ($ j , $ i )->setXfIndex ($ xfIndex );
1062+ if ($ conditionalStyles ) {
1063+ $ cloned = [];
1064+ foreach ($ conditionalStyles as $ conditionalStyle ) {
1065+ $ cloned [] = clone $ conditionalStyle ;
1066+ }
1067+ $ worksheet ->setConditionalStyles (Coordinate::stringFromColumnIndex ($ j ) . $ i , $ cloned );
1068+ }
1069+ }
1070+ }
1071+ }
1072+ }
1073+
1074+ private function duplicateStylesByRow (Worksheet $ worksheet , int $ beforeColumn , int $ beforeRow , string $ highestColumn , int $ numberOfRows ): void
1075+ {
1076+ $ highestColumnIndex = Coordinate::columnIndexFromString ($ highestColumn );
1077+ for ($ i = $ beforeColumn ; $ i <= $ highestColumnIndex ; ++$ i ) {
1078+ // Style
1079+ $ coordinate = Coordinate::stringFromColumnIndex ($ i ) . ($ beforeRow - 1 );
1080+ if ($ worksheet ->cellExists ($ coordinate )) {
1081+ $ xfIndex = $ worksheet ->getCell ($ coordinate )->getXfIndex ();
1082+ $ conditionalStyles = $ worksheet ->conditionalStylesExists ($ coordinate ) ?
1083+ $ worksheet ->getConditionalStyles ($ coordinate ) : false ;
1084+ for ($ j = $ beforeRow ; $ j <= $ beforeRow - 1 + $ numberOfRows ; ++$ j ) {
1085+ $ worksheet ->getCell (Coordinate::stringFromColumnIndex ($ i ) . $ j )->setXfIndex ($ xfIndex );
1086+ if ($ conditionalStyles ) {
1087+ $ cloned = [];
1088+ foreach ($ conditionalStyles as $ conditionalStyle ) {
1089+ $ cloned [] = clone $ conditionalStyle ;
10521090 }
1091+ $ worksheet ->setConditionalStyles (Coordinate::stringFromColumnIndex ($ i ) . $ j , $ cloned );
10531092 }
10541093 }
10551094 }
1056- $ worksheet ->setAutoFilter ($ this ->updateCellReference ($ autoFilterRange , $ beforeCellAddress , $ numberOfColumns , $ numberOfRows ));
10571095 }
10581096 }
10591097
0 commit comments