PHPExcel
[ class tree: PHPExcel ] [ index: PHPExcel ] [ all elements ]

Source for file ReferenceHelper.php

Documentation is available at ReferenceHelper.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2010 PHPExcel
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  20.  *
  21.  * @category   PHPExcel
  22.  * @package    PHPExcel
  23.  * @copyright  Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.7.4, 2010-08-26
  26.  */
  27.  
  28.  
  29. /**
  30.  * PHPExcel_ReferenceHelper (Singleton)
  31.  *
  32.  * @category   PHPExcel
  33.  * @package    PHPExcel
  34.  * @copyright  Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  35.  */
  36. {
  37.     /**    Constants                */
  38.     /**    Regular Expressions        */
  39.     const REFHELPER_REGEXP_CELLREF        '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])';
  40.     const REFHELPER_REGEXP_CELLRANGE    '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+)';
  41.     const REFHELPER_REGEXP_ROWRANGE        '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)';
  42.     const REFHELPER_REGEXP_COLRANGE        '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})';
  43.  
  44.     /**
  45.      * Instance of this class
  46.      *
  47.      * @var PHPExcel_ReferenceHelper 
  48.      */
  49.     private static $_instance;
  50.  
  51.     /**
  52.      * Get an instance of this class
  53.      *
  54.      * @return PHPExcel_ReferenceHelper 
  55.      */
  56.     public static function getInstance({
  57.         if (!isset(self::$_instance|| is_null(self::$_instance)) {
  58.             self::$_instance new PHPExcel_ReferenceHelper();
  59.         }
  60.  
  61.         return self::$_instance;
  62.     }
  63.  
  64.     /**
  65.      * Create a new PHPExcel_ReferenceHelper
  66.      */
  67.     protected function __construct({
  68.     }
  69.  
  70.     /**
  71.      * Insert a new column, updating all possible related data
  72.      *
  73.      * @param    int    $pBefore    Insert before this one
  74.      * @param    int    $pNumCols    Number of columns to insert
  75.      * @param    int    $pNumRows    Number of rows to insert
  76.      * @throws    Exception
  77.      */
  78.     public function insertNewBefore($pBefore 'A1'$pNumCols 0$pNumRows 0PHPExcel_Worksheet $pSheet null{
  79.         $aCellCollection $pSheet->getCellCollection();
  80.  
  81.         // Get coordinates of $pBefore
  82.         $beforeColumn    'A';
  83.         $beforeRow        1;
  84.         list($beforeColumn$beforeRowPHPExcel_Cell::coordinateFromString$pBefore );
  85.  
  86.  
  87.         // Clear cells if we are removing columns or rows
  88.         $highestColumn    $pSheet->getHighestColumn();
  89.         $highestRow    $pSheet->getHighestRow();
  90.  
  91.         // 1. Clear column strips if we are removing columns
  92.         if ($pNumCols && PHPExcel_Cell::columnIndexFromString($beforeColumn$pNumCols 0{
  93.             for ($i 1$i <= $highestRow 1++$i{
  94.                 for ($j PHPExcel_Cell::columnIndexFromString($beforeColumn$pNumCols$j <= PHPExcel_Cell::columnIndexFromString($beforeColumn2++$j{
  95.                     $coordinate PHPExcel_Cell::stringFromColumnIndex($j$i;
  96.                     $pSheet->removeConditionalStyles($coordinate);
  97.                     if ($pSheet->cellExists($coordinate)) {
  98.                         $pSheet->getCell($coordinate)->setValueExplicit(''PHPExcel_Cell_DataType::TYPE_NULL);
  99.                         $pSheet->getCell($coordinate)->setXfIndex(0);
  100.                     }
  101.                 }
  102.             }
  103.         }
  104.  
  105.         // 2. Clear row strips if we are removing rows
  106.         if ($pNumRows && $beforeRow $pNumRows 0{
  107.             for ($i PHPExcel_Cell::columnIndexFromString($beforeColumn1$i <= PHPExcel_Cell::columnIndexFromString($highestColumn1++$i{
  108.                 for ($j $beforeRow $pNumRows$j <= $beforeRow 1++$j{
  109.                     $coordinate PHPExcel_Cell::stringFromColumnIndex($i$j;
  110.                     $pSheet->removeConditionalStyles($coordinate);
  111.                     if ($pSheet->cellExists($coordinate)) {
  112.                         $pSheet->getCell($coordinate)->setValueExplicit(''PHPExcel_Cell_DataType::TYPE_NULL);
  113.                         $pSheet->getCell($coordinate)->setXfIndex(0);
  114.                     }
  115.                 }
  116.             }
  117.         }
  118.  
  119.  
  120.         // Loop through cells, bottom-up, and change cell coordinates
  121.         while (($cellID ($pNumCols || $pNumRows 0array_shift($aCellCollectionarray_pop($aCellCollection))) {
  122.             $cell $pSheet->getCell($cellID);
  123.  
  124.             // New coordinates
  125.             $newCoordinates PHPExcel_Cell::stringFromColumnIndexPHPExcel_Cell::columnIndexFromString($cell->getColumn()) $pNumCols ($cell->getRow($pNumRows);
  126.  
  127.             // Should the cell be updated? Move value and cellXf index from one cell to another.
  128.             if ((PHPExcel_Cell::columnIndexFromString$cell->getColumn() ) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)) &&
  129.                 ($cell->getRow(>= $beforeRow)) {
  130.  
  131.                 // Update cell styles
  132.                 $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex());
  133.                 $cell->setXfIndex(0);
  134.  
  135.                 // Insert this cell at its new location
  136.                 if ($cell->getDataType(== PHPExcel_Cell_DataType::TYPE_FORMULA{
  137.                     // Formula should be adjusted
  138.                     $pSheet->getCell($newCoordinates)
  139.                            ->setValue($this->updateFormulaReferences($cell->getValue()$pBefore$pNumCols$pNumRows$pSheet->getTitle()));
  140.                 else {
  141.                     // Formula should not be adjusted
  142.                     $pSheet->getCell($newCoordinates)->setValue($cell->getValue());
  143.                 }
  144.  
  145.                 // Clear the original cell
  146.                 $pSheet->getCell($cell->getCoordinate())->setValue('');
  147.             }
  148.         }
  149.  
  150.  
  151.         // Duplicate styles for the newly inserted cells
  152.         $highestColumn    $pSheet->getHighestColumn();
  153.         $highestRow    $pSheet->getHighestRow();
  154.  
  155.         if ($pNumCols && PHPExcel_Cell::columnIndexFromString($beforeColumn0{
  156.             for ($i $beforeRow$i <= $highestRow 1++$i{
  157.  
  158.                 // Style
  159.                 $coordinate PHPExcel_Cell::stringFromColumnIndexPHPExcel_Cell::columnIndexFromString($beforeColumn$i;
  160.                 if ($pSheet->cellExists($coordinate)) {
  161.                     $xfIndex $pSheet->getCell($coordinate)->getXfIndex();
  162.                     $conditionalStyles $pSheet->conditionalStylesExists($coordinate?
  163.                         $pSheet->getConditionalStyles($coordinatefalse;
  164.                     for ($j PHPExcel_Cell::columnIndexFromString($beforeColumn1$j <= PHPExcel_Cell::columnIndexFromString($beforeColumn$pNumCols++$j{
  165.                         $pSheet->getCellByColumnAndRow($j$i)->setXfIndex($xfIndex);
  166.                         if ($conditionalStyles{
  167.                             $cloned array();
  168.                             foreach ($conditionalStyles as $conditionalStyle{
  169.                                 $cloned[clone $conditionalStyle;
  170.                             }
  171.                             $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j$i$cloned);
  172.                         }
  173.                     }
  174.                 }
  175.  
  176.             }
  177.         }
  178.  
  179.         if ($pNumRows && $beforeRow 0{
  180.             for ($i PHPExcel_Cell::columnIndexFromString($beforeColumn1$i <= PHPExcel_Cell::columnIndexFromString($highestColumn1++$i{
  181.  
  182.                 // Style
  183.                 $coordinate PHPExcel_Cell::stringFromColumnIndex($i($beforeRow 1);
  184.                 if ($pSheet->cellExists($coordinate)) {
  185.                     $xfIndex $pSheet->getCell($coordinate)->getXfIndex();
  186.                     $conditionalStyles $pSheet->conditionalStylesExists($coordinate?
  187.                         $pSheet->getConditionalStyles($coordinatefalse;
  188.                     for ($j $beforeRow$j <= $beforeRow $pNumRows++$j{
  189.                         $pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i$j)->setXfIndex($xfIndex);
  190.                         if ($conditionalStyles{
  191.                             $cloned array();
  192.                             foreach ($conditionalStyles as $conditionalStyle{
  193.                                 $cloned[clone $conditionalStyle;
  194.                             }
  195.                             $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i$j$cloned);
  196.                         }
  197.                     }
  198.                 }
  199.             }
  200.         }
  201.  
  202.  
  203.         // Update worksheet: column dimensions
  204.         $aColumnDimensions array_reverse($pSheet->getColumnDimensions()true);
  205.         if (count($aColumnDimensions0{
  206.             foreach ($aColumnDimensions as $objColumnDimension{
  207.                 $newReference $this->updateCellReference($objColumnDimension->getColumnIndex('1'$pBefore$pNumCols$pNumRows);
  208.                 list($newReferencePHPExcel_Cell::coordinateFromString($newReference);
  209.                 if ($objColumnDimension->getColumnIndex(!= $newReference{
  210.                     $objColumnDimension->setColumnIndex($newReference);
  211.                 }
  212.             }
  213.             $pSheet->refreshColumnDimensions();
  214.         }
  215.  
  216.  
  217.         // Update worksheet: row dimensions
  218.         $aRowDimensions array_reverse($pSheet->getRowDimensions()true);
  219.         if (count($aRowDimensions0{
  220.             foreach ($aRowDimensions as $objRowDimension{
  221.                 $newReference $this->updateCellReference('A' $objRowDimension->getRowIndex()$pBefore$pNumCols$pNumRows);
  222.                 list($newReferencePHPExcel_Cell::coordinateFromString($newReference);
  223.                 if ($objRowDimension->getRowIndex(!= $newReference{
  224.                     $objRowDimension->setRowIndex($newReference);
  225.                 }
  226.             }
  227.             $pSheet->refreshRowDimensions();
  228.  
  229.             $copyDimension $pSheet->getRowDimension($beforeRow 1);
  230.             for ($i $beforeRow$i <= $beforeRow $pNumRows++$i{
  231.                 $newDimension $pSheet->getRowDimension($i);
  232.                 $newDimension->setRowHeight($copyDimension->getRowHeight());
  233.                 $newDimension->setVisible($copyDimension->getVisible());
  234.                 $newDimension->setOutlineLevel($copyDimension->getOutlineLevel());
  235.                 $newDimension->setCollapsed($copyDimension->getCollapsed());
  236.             }
  237.         }
  238.  
  239.  
  240.         // Update worksheet: breaks
  241.         $aBreaks array_reverse($pSheet->getBreaks()true);
  242.         foreach ($aBreaks as $key => $value{
  243.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  244.             if ($key != $newReference{
  245.                 $pSheet->setBreak$newReference$value );
  246.                 $pSheet->setBreak$keyPHPExcel_Worksheet::BREAK_NONE );
  247.             }
  248.         }
  249.  
  250.  
  251.         // Update worksheet: hyperlinks
  252.         $aHyperlinkCollection array_reverse($pSheet->getHyperlinkCollection()true);
  253.         foreach ($aHyperlinkCollection as $key => $value{
  254.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  255.             if ($key != $newReference{
  256.                 $pSheet->setHyperlink$newReference$value );
  257.                 $pSheet->setHyperlink$keynull );
  258.             }
  259.         }
  260.  
  261.  
  262.         // Update worksheet: data validations
  263.         $aDataValidationCollection array_reverse($pSheet->getDataValidationCollection()true);
  264.         foreach ($aDataValidationCollection as $key => $value{
  265.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  266.             if ($key != $newReference{
  267.                 $pSheet->setDataValidation$newReference$value );
  268.                 $pSheet->setDataValidation$keynull );
  269.             }
  270.         }
  271.  
  272.  
  273.         // Update worksheet: merge cells
  274.         $aMergeCells $pSheet->getMergeCells();
  275.         $aNewMergeCells array()// the new array of all merge cells
  276.         foreach ($aMergeCells as $key => &$value{
  277.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  278.             $aNewMergeCells[$newReference$newReference;
  279.         }
  280.         $pSheet->setMergeCells($aNewMergeCells)// replace the merge cells array
  281.  
  282.  
  283.         // Update worksheet: protected cells
  284.         $aProtectedCells array_reverse($pSheet->getProtectedCells()true);
  285.         foreach ($aProtectedCells as $key => $value{
  286.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  287.             if ($key != $newReference{
  288.                 $pSheet->protectCells$newReference$valuetrue );
  289.                 $pSheet->unprotectCells$key );
  290.             }
  291.         }
  292.  
  293.  
  294.         // Update worksheet: autofilter
  295.         if ($pSheet->getAutoFilter(!= ''{
  296.             $pSheet->setAutoFilter$this->updateCellReference($pSheet->getAutoFilter()$pBefore$pNumCols$pNumRows) );
  297.         }
  298.  
  299.  
  300.         // Update worksheet: freeze pane
  301.         if ($pSheet->getFreezePane(!= ''{
  302.             $pSheet->freezePane$this->updateCellReference($pSheet->getFreezePane()$pBefore$pNumCols$pNumRows) );
  303.         }
  304.  
  305.  
  306.         // Page setup
  307.         if ($pSheet->getPageSetup()->isPrintAreaSet()) {
  308.             $pSheet->getPageSetup()->setPrintArea$this->updateCellReference($pSheet->getPageSetup()->getPrintArea()$pBefore$pNumCols$pNumRows) );
  309.         }
  310.  
  311.  
  312.         // Update worksheet: drawings
  313.         $aDrawings $pSheet->getDrawingCollection();
  314.         foreach ($aDrawings as $objDrawing{
  315.             $newReference $this->updateCellReference($objDrawing->getCoordinates()$pBefore$pNumCols$pNumRows);
  316.             if ($objDrawing->getCoordinates(!= $newReference{
  317.                 $objDrawing->setCoordinates($newReference);
  318.             }
  319.         }
  320.  
  321.  
  322.         // Update workbook: named ranges
  323.         if (count($pSheet->getParent()->getNamedRanges()) 0{
  324.             foreach ($pSheet->getParent()->getNamedRanges(as $namedRange{
  325.                 if ($namedRange->getWorksheet()->getHashCode(== $pSheet->getHashCode()) {
  326.                     $namedRange->setRange(
  327.                         $this->updateCellReference($namedRange->getRange()$pBefore$pNumCols$pNumRows)
  328.                     );
  329.                 }
  330.             }
  331.         }
  332.  
  333.         // Garbage collect
  334.         $pSheet->garbageCollect();
  335.     }
  336.  
  337.     /**
  338.      * Update references within formulas
  339.      *
  340.      * @param    string    $pFormula    Formula to update
  341.      * @param    int        $pBefore    Insert before this one
  342.      * @param    int        $pNumCols    Number of columns to insert
  343.      * @param    int        $pNumRows    Number of rows to insert
  344.      * @return    string    Updated formula
  345.      * @throws    Exception
  346.      */
  347.     public function updateFormulaReferences($pFormula ''$pBefore 'A1'$pNumCols 0$pNumRows 0$sheetName ''{
  348.         //    Update cell references in the formula
  349.         $formulaBlocks explode('"',$pFormula);
  350.         foreach($formulaBlocks as $i => &$formulaBlock{
  351.             //    Ignore blocks that were enclosed in quotes (even entries in the $formulaBlocks array after the explode)
  352.             if (($i 2== 0{
  353.                 $adjustCount 0;
  354.                 $newCellTokens $cellTokens array();
  355.                 //    Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5)
  356.                 $matchCount preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i'' '.$formulaBlock.' '$matchesPREG_SET_ORDER);
  357.                 if ($matchCount 0{
  358.                     foreach($matches as $match{
  359.                         $fromString ($match[2''$match[2].'!' '';
  360.                         $fromString .= $match[3].':'.$match[4];
  361.                         $modified3 substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2);
  362.                         $modified4 substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2);
  363.  
  364.                         if ($match[3].':'.$match[4!== $modified3.':'.$modified4{
  365.                             if (($match[2== ''|| (trim($match[2],"'"== $sheetName)) {
  366.                                 $toString ($match[2''$match[2].'!' '';
  367.                                 $toString .= $modified3.':'.$modified4;
  368.                                 //    Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
  369.                                 $column 100000;
  370.                                 $row 10000000+trim($match[3],'$');
  371.                                 $cellIndex $column.$row;
  372.  
  373.                                 $newCellTokens[$cellIndexpreg_quote($toString);
  374.                                 $cellTokens[$cellIndex'/(?<!\d)'.preg_quote($fromString).'(?!\d)/i';
  375.                                 ++$adjustCount;
  376.                             }
  377.                         }
  378.                     }
  379.                 }
  380.                 //    Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E)
  381.                 $matchCount preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i'' '.$formulaBlock.' '$matchesPREG_SET_ORDER);
  382.                 if ($matchCount 0{
  383.                     foreach($matches as $match{
  384.                         $fromString ($match[2''$match[2].'!' '';
  385.                         $fromString .= $match[3].':'.$match[4];
  386.                         $modified3 substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2);
  387.                         $modified4 substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2);
  388.  
  389.                         if ($match[3].':'.$match[4!== $modified3.':'.$modified4{
  390.                             if (($match[2== ''|| (trim($match[2],"'"== $sheetName)) {
  391.                                 $toString ($match[2''$match[2].'!' '';
  392.                                 $toString .= $modified3.':'.$modified4;
  393.                                 //    Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
  394.                                 $column PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) 100000;
  395.                                 $row 10000000;
  396.                                 $cellIndex $column.$row;
  397.  
  398.                                 $newCellTokens[$cellIndexpreg_quote($toString);
  399.                                 $cellTokens[$cellIndex'/(?<![A-Z])'.preg_quote($fromString).'(?![A-Z])/i';
  400.                                 ++$adjustCount;
  401.                             }
  402.                         }
  403.                     }
  404.                 }
  405.                 //    Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5)
  406.                 $matchCount preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i'' '.$formulaBlock.' '$matchesPREG_SET_ORDER);
  407.                 if ($matchCount 0{
  408.                     foreach($matches as $match{
  409.                         $fromString ($match[2''$match[2].'!' '';
  410.                         $fromString .= $match[3].':'.$match[4];
  411.                         $modified3 $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows);
  412.                         $modified4 $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows);
  413.  
  414.                         if ($match[3].$match[4!== $modified3.$modified4{
  415.                             if (($match[2== ''|| (trim($match[2],"'"== $sheetName)) {
  416.                                 $toString ($match[2''$match[2].'!' '';
  417.                                 $toString .= $modified3.':'.$modified4;
  418.                                 list($column,$rowPHPExcel_Cell::coordinateFromString($match[3]);
  419.                                 //    Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
  420.                                 $column PHPExcel_Cell::columnIndexFromString(trim($column,'$')) 100000;
  421.                                 $row trim($row,'$'10000000;
  422.                                 $cellIndex $column.$row;
  423.  
  424.                                 $newCellTokens[$cellIndexpreg_quote($toString);
  425.                                 $cellTokens[$cellIndex'/(?<![A-Z])'.preg_quote($fromString).'(?!\d)/i';
  426.                                 ++$adjustCount;
  427.                             }
  428.                         }
  429.                     }
  430.                 }
  431.                 //    Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5)
  432.                 $matchCount preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i'' '.$formulaBlock.' '$matchesPREG_SET_ORDER);
  433.                 if ($matchCount 0{
  434.                     foreach($matches as $match{
  435.                         $fromString ($match[2''$match[2].'!' '';
  436.                         $fromString .= $match[3];
  437.                         $modified3 $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows);
  438.  
  439.                         if ($match[3!== $modified3{
  440.                             if (($match[2== ''|| (trim($match[2],"'"== $sheetName)) {
  441.                                 $toString ($match[2''$match[2].'!' '';
  442.                                 $toString .= $modified3;
  443.                                 list($column,$rowPHPExcel_Cell::coordinateFromString($match[3]);
  444.                                 //    Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
  445.                                 $column PHPExcel_Cell::columnIndexFromString(trim($column,'$')) 100000;
  446.                                 $row trim($row,'$'10000000;
  447.                                 $cellIndex $column.$row;
  448.  
  449.                                 $newCellTokens[$cellIndexpreg_quote($toString);
  450.                                 $cellTokens[$cellIndex'/(?<![A-Z])'.preg_quote($fromString).'(?!\d)/i';
  451.                                 ++$adjustCount;
  452.                             }
  453.                         }
  454.                     }
  455.                 }
  456.                 if ($adjustCount 0{
  457.                     krsort($cellTokens);
  458.                     krsort($newCellTokens);
  459.                     //    Update cell references in the formula
  460.                     $formulaBlock str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock));
  461.                 }
  462.             }
  463.         }
  464.         unset($formulaBlock);
  465.  
  466.         //    Then rebuild the formula string
  467.         return implode('"',$formulaBlocks);
  468.     }
  469.  
  470.     /**
  471.      * Update cell reference
  472.      *
  473.      * @param    string    $pCellRange            Cell range
  474.      * @param    int        $pBefore            Insert before this one
  475.      * @param    int        $pNumCols            Number of columns to increment
  476.      * @param    int        $pNumRows            Number of rows to increment
  477.      * @return    string    Updated cell range
  478.      * @throws    Exception
  479.      */
  480.     public function updateCellReference($pCellRange 'A1'$pBefore 'A1'$pNumCols 0$pNumRows 0{
  481.         // Is it in another worksheet? Will not have to update anything.
  482.         if (strpos($pCellRange"!"!== false{
  483.             return $pCellRange;
  484.         // Is it a range or a single cell?
  485.         elseif (strpos($pCellRange':'=== false && strpos($pCellRange','=== false{
  486.             // Single cell
  487.             return $this->_updateSingleCellReference($pCellRange$pBefore$pNumCols$pNumRows);
  488.         elseif (strpos($pCellRange':'!== false || strpos($pCellRange','!== false{
  489.             // Range
  490.             return $this->_updateCellRange($pCellRange$pBefore$pNumCols$pNumRows);
  491.         else {
  492.             // Return original
  493.             return $pCellRange;
  494.         }
  495.     }
  496.  
  497.     /**
  498.      * Update named formulas (i.e. containing worksheet references / named ranges)
  499.      *
  500.      * @param PHPExcel $pPhpExcel    Object to update
  501.      * @param string $oldName        Old name (name to replace)
  502.      * @param string $newName        New name
  503.      */
  504.     public function updateNamedFormulas(PHPExcel $pPhpExcel$oldName ''$newName ''{
  505.         if ($oldName == ''{
  506.             return;
  507.         }
  508.  
  509.         foreach ($pPhpExcel->getWorksheetIterator(as $sheet{
  510.             foreach ($sheet->getCellCollection(falseas $cellID{
  511.                 $cell $sheet->getCell($cellID);
  512.                 if (!is_null($cell&& $cell->getDataType(== PHPExcel_Cell_DataType::TYPE_FORMULA{
  513.                     $formula $cell->getValue();
  514.                     if (strpos($formula$oldName!== false{
  515.                         $formula str_replace("'" $oldName "'!""'" $newName "'!"$formula);
  516.                         $formula str_replace($oldName "!"$newName "!"$formula);
  517.                         $cell->setValueExplicit($formulaPHPExcel_Cell_DataType::TYPE_FORMULA);
  518.                     }
  519.                 }
  520.             }
  521.         }
  522.     }
  523.  
  524.     /**
  525.      * Update cell range
  526.      *
  527.      * @param    string    $pCellRange            Cell range
  528.      * @param    int        $pBefore            Insert before this one
  529.      * @param    int        $pNumCols            Number of columns to increment
  530.      * @param    int        $pNumRows            Number of rows to increment
  531.      * @return    string    Updated cell range
  532.      * @throws    Exception
  533.      */
  534.     private function _updateCellRange($pCellRange 'A1:A1'$pBefore 'A1'$pNumCols 0$pNumRows 0{
  535.         if (strpos($pCellRange,':'!== false || strpos($pCellRange','!== false{
  536.             // Update range
  537.             $range PHPExcel_Cell::splitRange($pCellRange);
  538.             for ($i 0$i count($range)++$i{
  539.                 for ($j 0$j count($range[$i])++$j{
  540.                     $range[$i][$j$this->_updateSingleCellReference($range[$i][$j]$pBefore$pNumCols$pNumRows);
  541.                 }
  542.             }
  543.  
  544.             // Recreate range string
  545.             return PHPExcel_Cell::buildRange($range);
  546.         else {
  547.             throw new Exception("Only cell ranges may be passed to this method.");
  548.         }
  549.     }
  550.  
  551.     /**
  552.      * Update single cell reference
  553.      *
  554.      * @param    string    $pCellReference        Single cell reference
  555.      * @param    int        $pBefore            Insert before this one
  556.      * @param    int        $pNumCols            Number of columns to increment
  557.      * @param    int        $pNumRows            Number of rows to increment
  558.      * @return    string    Updated cell reference
  559.      * @throws    Exception
  560.      */
  561.     private function _updateSingleCellReference($pCellReference 'A1'$pBefore 'A1'$pNumCols 0$pNumRows 0{
  562.         if (strpos($pCellReference':'=== false && strpos($pCellReference','=== false{
  563.             // Get coordinates of $pBefore
  564.             $beforeColumn    'A';
  565.             $beforeRow        1;
  566.             list($beforeColumn$beforeRowPHPExcel_Cell::coordinateFromString$pBefore );
  567.  
  568.             // Get coordinates
  569.             $newColumn    'A';
  570.             $newRow    1;
  571.             list($newColumn$newRowPHPExcel_Cell::coordinateFromString$pCellReference );
  572.  
  573.             // Make sure the reference can be used
  574.             if ($newColumn == '' && $newRow == '')
  575.             {
  576.                 return $pCellReference;
  577.             }
  578.  
  579.             // Verify which parts should be updated
  580.             $updateColumn (PHPExcel_Cell::columnIndexFromString($newColumn>= PHPExcel_Cell::columnIndexFromString($beforeColumn))
  581.                             && (strpos($newColumn'$'=== false)
  582.                             && (strpos($beforeColumn'$'=== false);
  583.  
  584.             $updateRow ($newRow >= $beforeRow)
  585.                             && (strpos($newRow'$'=== false)
  586.                             && (strpos($beforeRow'$'=== false);
  587.  
  588.             // Create new column reference
  589.             if ($updateColumn{
  590.                 $newColumn    PHPExcel_Cell::stringFromColumnIndexPHPExcel_Cell::columnIndexFromString($newColumn$pNumCols );
  591.             }
  592.  
  593.             // Create new row reference
  594.             if ($updateRow{
  595.                 $newRow    $newRow $pNumRows;
  596.             }
  597.  
  598.             // Return new reference
  599.             return $newColumn $newRow;
  600.         else {
  601.             throw new Exception("Only single cell references may be passed to this method.");
  602.         }
  603.     }
  604.  
  605.     /**
  606.      * __clone implementation. Cloning should not be allowed in a Singleton!
  607.      *
  608.      * @throws    Exception
  609.      */
  610.     public final function __clone({
  611.         throw new Exception("Cloning a Singleton is not allowed!");
  612.     }
  613. }

Documentation generated on Thu, 26 Aug 2010 17:44:10 +0200 by phpDocumentor 1.4.3