58 if (!isset(self::$_instance) || (self::$_instance === NULL)) {
62 return self::$_instance;
80 return strcasecmp(strlen($a) . $a, strlen($b) . $b);
92 return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b);
104 sscanf($a,
'%[A-Z]%d', $ac, $ar);
105 sscanf($b,
'%[A-Z]%d', $bc, $br);
108 return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc);
110 return ($ar < $br) ? -1 : 1;
122 sscanf($a,
'%[A-Z]%d', $ac, $ar);
123 sscanf($b,
'%[A-Z]%d', $bc, $br);
126 return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc);
128 return ($ar < $br) ? 1 : -1;
146 ($cellRow >= ($beforeRow + $pNumRows)) &&
147 ($cellRow < $beforeRow)) {
149 } elseif ($pNumCols < 0 &&
150 ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) &&
151 ($cellColumnIndex < $beforeColumnIndex)) {
170 ($pNumCols > 0 || $pNumRows > 0) ?
171 uksort($aBreaks,
array(
'PHPExcel_ReferenceHelper',
'cellReverseSort')) :
172 uksort($aBreaks,
array(
'PHPExcel_ReferenceHelper',
'cellSort'));
174 foreach ($aBreaks as $key => $value) {
175 if (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) {
183 if ($key != $newReference) {
184 $pSheet->
setBreak($newReference, $value)
201 protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
203 $aComments = $pSheet->getComments();
204 $aNewComments =
array();
206 foreach ($aComments as $key => &$value) {
208 if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) {
211 $aNewComments[$newReference] = $value;
215 $pSheet->setComments($aNewComments);
228 protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
230 $aHyperlinkCollection = $pSheet->getHyperlinkCollection();
231 ($pNumCols > 0 || $pNumRows > 0) ?
232 uksort($aHyperlinkCollection,
array(
'PHPExcel_ReferenceHelper',
'cellReverseSort')) :
233 uksort($aHyperlinkCollection,
array(
'PHPExcel_ReferenceHelper',
'cellSort'));
235 foreach ($aHyperlinkCollection as $key => $value) {
237 if ($key != $newReference) {
238 $pSheet->setHyperlink( $newReference, $value );
239 $pSheet->setHyperlink( $key, null );
256 $aDataValidationCollection = $pSheet->getDataValidationCollection();
257 ($pNumCols > 0 || $pNumRows > 0) ?
258 uksort($aDataValidationCollection,
array(
'PHPExcel_ReferenceHelper',
'cellReverseSort')) :
259 uksort($aDataValidationCollection,
array(
'PHPExcel_ReferenceHelper',
'cellSort'));
260 foreach ($aDataValidationCollection as $key => $value) {
262 if ($key != $newReference) {
263 $pSheet->setDataValidation( $newReference, $value );
264 $pSheet->setDataValidation( $key, null );
279 protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
281 $aMergeCells = $pSheet->getMergeCells();
282 $aNewMergeCells =
array();
283 foreach ($aMergeCells as $key => &$value) {
285 $aNewMergeCells[$newReference] = $newReference;
287 $pSheet->setMergeCells($aNewMergeCells);
302 $aProtectedCells = $pSheet->getProtectedCells();
303 ($pNumCols > 0 || $pNumRows > 0) ?
304 uksort($aProtectedCells,
array(
'PHPExcel_ReferenceHelper',
'cellReverseSort')) :
305 uksort($aProtectedCells,
array(
'PHPExcel_ReferenceHelper',
'cellSort'));
306 foreach ($aProtectedCells as $key => $value) {
308 if ($key != $newReference) {
309 $pSheet->protectCells( $newReference, $value,
true );
310 $pSheet->unprotectCells( $key );
327 $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(),
true);
328 if (!empty($aColumnDimensions)) {
329 foreach ($aColumnDimensions as $objColumnDimension) {
330 $newReference = $this->
updateCellReference($objColumnDimension->getColumnIndex() .
'1', $pBefore, $pNumCols, $pNumRows);
332 if ($objColumnDimension->getColumnIndex() != $newReference) {
333 $objColumnDimension->setColumnIndex($newReference);
336 $pSheet->refreshColumnDimensions();
350 protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
352 $aRowDimensions = array_reverse($pSheet->getRowDimensions(),
true);
353 if (!empty($aRowDimensions)) {
354 foreach ($aRowDimensions as $objRowDimension) {
355 $newReference = $this->
updateCellReference(
'A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows);
357 if ($objRowDimension->getRowIndex() != $newReference) {
358 $objRowDimension->setRowIndex($newReference);
361 $pSheet->refreshRowDimensions();
363 $copyDimension = $pSheet->getRowDimension($beforeRow - 1);
364 for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) {
365 $newDimension = $pSheet->getRowDimension($i);
366 $newDimension->setRowHeight($copyDimension->getRowHeight());
367 $newDimension->setVisible($copyDimension->getVisible());
368 $newDimension->setOutlineLevel($copyDimension->getOutlineLevel());
369 $newDimension->setCollapsed($copyDimension->getCollapsed());
385 $remove = ($pNumCols < 0 || $pNumRows < 0);
386 $aCellCollection = $pSheet->getCellCollection();
395 $highestColumn = $pSheet->getHighestColumn();
396 $highestRow = $pSheet->getHighestRow();
399 if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) {
400 for ($i = 1; $i <= $highestRow - 1; ++$i) {
401 for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) {
403 $pSheet->removeConditionalStyles($coordinate);
404 if ($pSheet->cellExists($coordinate)) {
406 $pSheet->getCell($coordinate)->setXfIndex(0);
413 if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) {
415 for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) {
417 $pSheet->removeConditionalStyles($coordinate);
418 if ($pSheet->cellExists($coordinate)) {
420 $pSheet->getCell($coordinate)->setXfIndex(0);
429 $aCellCollection = array_reverse($aCellCollection);
431 while ($cellID = array_pop($aCellCollection)) {
432 $cell = $pSheet->getCell($cellID);
435 if ($cellIndex-1 + $pNumCols < 0) {
443 if (($cellIndex >= $beforeColumnIndex) &&
444 ($cell->getRow() >= $beforeRow)) {
447 $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex());
452 $pSheet->getCell($newCoordinates)
454 $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle()));
457 $pSheet->getCell($newCoordinates)->setValue($cell->getValue());
461 $pSheet->getCellCacheController()->deleteCacheData($cellID);
469 $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle()));
476 $highestColumn = $pSheet->getHighestColumn();
477 $highestRow = $pSheet->getHighestRow();
479 if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) {
480 for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) {
484 if ($pSheet->cellExists($coordinate)) {
485 $xfIndex = $pSheet->getCell($coordinate)->getXfIndex();
487 $pSheet->getConditionalStyles($coordinate) :
false;
488 for ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) {
489 $pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex);
493 $cloned[] = clone $conditionalStyle;
503 if ($pNumRows > 0 && $beforeRow - 1 > 0) {
508 if ($pSheet->cellExists($coordinate)) {
509 $xfIndex = $pSheet->getCell($coordinate)->getXfIndex();
511 $pSheet->getConditionalStyles($coordinate) :
false;
512 for ($j = $beforeRow; $j <= $beforeRow - 1 + $pNumRows; ++$j) {
517 $cloned[] = clone $conditionalStyle;
530 $this->
_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
533 $this->
_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
536 $this->
_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
539 $this->
_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
545 $this->
_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
548 $this->
_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
553 if (!empty($autoFilterRange)) {
554 if ($pNumCols != 0) {
555 $autoFilterColumns = array_keys(
$autoFilter->getColumns());
556 if (count($autoFilterColumns) > 0) {
560 if ($columnIndex <= $rangeEnd[0]) {
564 $deleteColumn = $columnIndex + $pNumCols - 1;
565 $deleteCount = abs($pNumCols);
566 for ($i = 1; $i <= $deleteCount; ++$i) {
573 $startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0];
582 $startColRef = $startCol;
583 $endColRef = $rangeEnd[0];
584 $toColRef = $rangeEnd[0]+$pNumCols;
590 }
while ($startColRef <= $endColRef);
600 }
while ($startColID != $endColID);
605 $pSheet->setAutoFilter( $this->
updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) );
609 if ($pSheet->getFreezePane() !=
'') {
610 $pSheet->freezePane( $this->
updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) );
614 if ($pSheet->getPageSetup()->isPrintAreaSet()) {
615 $pSheet->getPageSetup()->setPrintArea( $this->
updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) );
619 $aDrawings = $pSheet->getDrawingCollection();
621 $newReference = $this->
updateCellReference($objDrawing->getCoordinates(), $pBefore, $pNumCols, $pNumRows);
622 if ($objDrawing->getCoordinates() != $newReference) {
623 $objDrawing->setCoordinates($newReference);
628 if (count($pSheet->getParent()->getNamedRanges()) > 0) {
629 foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) {
630 if ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) {
631 $namedRange->setRange(
639 $pSheet->garbageCollect();
655 $formulaBlocks = explode(
'"',$pFormula);
657 foreach($formulaBlocks as &$formulaBlock) {
661 $newCellTokens = $cellTokens =
array();
663 $matchCount = preg_match_all(
'/'.self::REFHELPER_REGEXP_ROWRANGE.
'/i',
' '.$formulaBlock.
' ', $matches, PREG_SET_ORDER);
664 if ($matchCount > 0) {
665 foreach($matches as $match) {
666 $fromString = ($match[2] >
'') ? $match[2].
'!' :
'';
667 $fromString .= $match[3].
':'.$match[4];
668 $modified3 = substr($this->
updateCellReference(
'$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2);
669 $modified4 = substr($this->
updateCellReference(
'$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2);
671 if ($match[3].
':'.$match[4] !== $modified3.
':'.$modified4) {
672 if (($match[2] ==
'') || (trim($match[2],
"'") == $sheetName)) {
673 $toString = ($match[2] >
'') ? $match[2].
'!' :
'';
674 $toString .= $modified3.
':'.$modified4;
677 $row = 10000000+trim($match[3],
'$');
680 $newCellTokens[$cellIndex] = preg_quote($toString);
681 $cellTokens[$cellIndex] =
'/(?<!\d\$\!)'.preg_quote($fromString).
'(?!\d)/i';
688 $matchCount = preg_match_all(
'/'.self::REFHELPER_REGEXP_COLRANGE.
'/i',
' '.$formulaBlock.
' ', $matches, PREG_SET_ORDER);
689 if ($matchCount > 0) {
690 foreach($matches as $match) {
691 $fromString = ($match[2] >
'') ? $match[2].
'!' :
'';
692 $fromString .= $match[3].
':'.$match[4];
693 $modified3 = substr($this->
updateCellReference($match[3].
'$1',$pBefore,$pNumCols,$pNumRows),0,-2);
694 $modified4 = substr($this->
updateCellReference($match[4].
'$1',$pBefore,$pNumCols,$pNumRows),0,-2);
696 if ($match[3].
':'.$match[4] !== $modified3.
':'.$modified4) {
697 if (($match[2] ==
'') || (trim($match[2],
"'") == $sheetName)) {
698 $toString = ($match[2] >
'') ? $match[2].
'!' :
'';
699 $toString .= $modified3.
':'.$modified4;
705 $newCellTokens[$cellIndex] = preg_quote($toString);
706 $cellTokens[$cellIndex] =
'/(?<![A-Z\$\!])'.preg_quote($fromString).
'(?![A-Z])/i';
713 $matchCount = preg_match_all(
'/'.self::REFHELPER_REGEXP_CELLRANGE.
'/i',
' '.$formulaBlock.
' ', $matches, PREG_SET_ORDER);
714 if ($matchCount > 0) {
715 foreach($matches as $match) {
716 $fromString = ($match[2] >
'') ? $match[2].
'!' :
'';
717 $fromString .= $match[3].
':'.$match[4];
721 if ($match[3].$match[4] !== $modified3.$modified4) {
722 if (($match[2] ==
'') || (trim($match[2],
"'") == $sheetName)) {
723 $toString = ($match[2] >
'') ? $match[2].
'!' :
'';
724 $toString .= $modified3.
':'.$modified4;
731 $newCellTokens[$cellIndex] = preg_quote($toString);
732 $cellTokens[$cellIndex] =
'/(?<![A-Z]\$\!)'.preg_quote($fromString).
'(?!\d)/i';
739 $matchCount = preg_match_all(
'/'.self::REFHELPER_REGEXP_CELLREF.
'/i',
' '.$formulaBlock.
' ', $matches, PREG_SET_ORDER);
741 if ($matchCount > 0) {
742 foreach($matches as $match) {
743 $fromString = ($match[2] >
'') ? $match[2].
'!' :
'';
744 $fromString .= $match[3];
747 if ($match[3] !== $modified3) {
748 if (($match[2] ==
'') || (trim($match[2],
"'") == $sheetName)) {
749 $toString = ($match[2] >
'') ? $match[2].
'!' :
'';
750 $toString .= $modified3;
757 $newCellTokens[$cellIndex] = preg_quote($toString);
758 $cellTokens[$cellIndex] =
'/(?<![A-Z\$\!])'.preg_quote($fromString).
'(?!\d)/i';
764 if ($adjustCount > 0) {
765 if ($pNumCols > 0 || $pNumRows > 0) {
767 krsort($newCellTokens);
770 ksort($newCellTokens);
772 $formulaBlock = str_replace(
'\\',
'',preg_replace($cellTokens,$newCellTokens,$formulaBlock));
776 unset($formulaBlock);
779 return implode(
'"',$formulaBlocks);
794 if (strpos($pCellRange,
"!") !==
false) {
797 } elseif (strpos($pCellRange,
':') ===
false && strpos($pCellRange,
',') ===
false) {
800 } elseif (strpos($pCellRange,
':') !==
false || strpos($pCellRange,
',') !==
false) {
802 return $this->
_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows);
817 if ($oldName ==
'') {
822 foreach ($sheet->getCellCollection(
false) as $cellID) {
823 $cell = $sheet->getCell($cellID);
825 $formula = $cell->getValue();
826 if (strpos($formula, $oldName) !==
false) {
827 $formula = str_replace(
"'" . $oldName .
"'!",
"'" . $newName .
"'!", $formula);
828 $formula = str_replace($oldName .
"!", $newName .
"!", $formula);
846 private function _updateCellRange($pCellRange =
'A1:A1', $pBefore =
'A1', $pNumCols = 0, $pNumRows = 0) {
847 if (strpos($pCellRange,
':') !==
false || strpos($pCellRange,
',') !==
false) {
851 for ($i = 0; $i < $ic; ++$i) {
852 $jc = count($range[$i]);
853 for ($j = 0; $j < $jc; ++$j) {
854 if (ctype_alpha($range[$i][$j])) {
856 $range[$i][$j] =
$r[0];
857 } elseif(ctype_digit($range[$i][$j])) {
859 $range[$i][$j] =
$r[1];
884 if (strpos($pCellReference,
':') ===
false && strpos($pCellReference,
',') ===
false) {
892 $updateColumn = (($newColumn{0} !=
'$') && ($beforeColumn{0} !=
'$') &&
894 $updateRow = (($newRow{0} !=
'$') && ($beforeRow{0} !=
'$') &&
895 $newRow >= $beforeRow);
904 $newRow = $newRow + $pNumRows;
908 return $newColumn . $newRow;
910 throw new PHPExcel_Exception(
"Only single cell references may be passed to this method.");
_updateSingleCellReference($pCellReference='A1', $pBefore='A1', $pNumCols=0, $pNumRows=0)
Update single cell reference.
static splitRange($pRange='A1:A1')
Split range into coordinate strings.
static coordinateFromString($pCoordinateString='A1')
Coordinate from string.
const REFHELPER_REGEXP_COLRANGE
_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update row dimensions when inserting/deleting rows/columns.
_adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update page breaks when inserting/deleting rows/columns.
static getInstance()
Get an instance of this class.
static rangeBoundaries($pRange='A1:A1')
Calculate range boundaries.
static cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)
Test whether a cell address falls within a defined range of cells.
updateCellReference($pCellRange='A1', $pBefore='A1', $pNumCols=0, $pNumRows=0)
Update cell reference.
_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update data validations when inserting/deleting rows/columns.
getWorksheetIterator()
Get worksheet iterator.
_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update hyperlinks when inserting/deleting rows/columns.
updateNamedFormulas(PHPExcel $pPhpExcel, $oldName='', $newName='')
Update named formulas (i.e.
static columnSort($a, $b)
Compare two column addresses Intended for use as a Callback function for sorting column addresses by ...
__construct()
Create a new PHPExcel_ReferenceHelper.
static cellReverseSort($a, $b)
Compare two cell addresses Intended for use as a Callback function for sorting cell addresses by colu...
static columnReverseSort($a, $b)
Compare two column addresses Intended for use as a Callback function for reverse sorting column addre...
updateFormulaReferences($pFormula='', $pBefore='A1', $pNumCols=0, $pNumRows=0, $sheetName='')
Update references within formulas.
static buildRange($pRange)
Build range from coordinate strings.
insertNewBefore($pBefore='A1', $pNumCols=0, $pNumRows=0, PHPExcel_Worksheet $pSheet=NULL)
Insert a new column or row, updating all possible related data.
const REFHELPER_REGEXP_CELLRANGE
_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update protected cells when inserting/deleting rows/columns.
Create styles array
The data for the language used.
_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update cell comments when inserting/deleting rows/columns.
static columnIndexFromString($pString='A')
Column index from string.
static stringFromColumnIndex($pColumnIndex=0)
String from columnindex.
__clone()
__clone implementation.
static cellSort($a, $b)
Compare two cell addresses Intended for use as a Callback function for sorting cell addresses by colu...
const REFHELPER_REGEXP_CELLREF
Constants.
const REFHELPER_REGEXP_ROWRANGE
_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update column dimensions when inserting/deleting rows/columns.
_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)
Update merged cells when inserting/deleting rows/columns.
_updateCellRange($pCellRange='A1:A1', $pBefore='A1', $pNumCols=0, $pNumRows=0)
Update cell range.
setBreak($pCell='A1', $pBreak=PHPExcel_Worksheet::BREAK_NONE)
Set break on a cell.