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

Source for file Worksheet.php

Documentation is available at Worksheet.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2009 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_Worksheet
  23.  * @copyright  Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.6.7, 2009-04-22
  26.  */
  27.  
  28.  
  29. /** PHPExcel */
  30. require_once 'PHPExcel.php';
  31.  
  32. /** PHPExcel_Cell */
  33. require_once 'PHPExcel/Cell.php';
  34.  
  35. /** PHPExcel_Cell_DataType */
  36. require_once 'PHPExcel/Cell/DataType.php';
  37.  
  38. /** PHPExcel_Worksheet_RowDimension */
  39. require_once 'PHPExcel/Worksheet/RowDimension.php';
  40.  
  41. /** PHPExcel_Worksheet_ColumnDimension */
  42. require_once 'PHPExcel/Worksheet/ColumnDimension.php';
  43.  
  44. /** PHPExcel_Worksheet_PageSetup */
  45. require_once 'PHPExcel/Worksheet/PageSetup.php';
  46.  
  47. /** PHPExcel_Worksheet_PageMargins */
  48. require_once 'PHPExcel/Worksheet/PageMargins.php';
  49.  
  50. /** PHPExcel_Worksheet_HeaderFooter */
  51. require_once 'PHPExcel/Worksheet/HeaderFooter.php';
  52.  
  53. /** PHPExcel_Worksheet_BaseDrawing */
  54. require_once 'PHPExcel/Worksheet/BaseDrawing.php';
  55.  
  56. /** PHPExcel_Worksheet_Drawing */
  57. require_once 'PHPExcel/Worksheet/Drawing.php';
  58.  
  59. /** PHPExcel_Worksheet_MemoryDrawing */
  60. require_once 'PHPExcel/Worksheet/MemoryDrawing.php';
  61.  
  62. /** PHPExcel_Worksheet_HeaderFooterDrawing */
  63. require_once 'PHPExcel/Worksheet/HeaderFooterDrawing.php';
  64.  
  65. /** PHPExcel_Worksheet_SheetView */
  66. require_once 'PHPExcel/Worksheet/SheetView.php';
  67.  
  68. /** PHPExcel_Worksheet_Protection */
  69. require_once 'PHPExcel/Worksheet/Protection.php';
  70.  
  71. /** PHPExcel_Worksheet_RowIterator */
  72. require_once 'PHPExcel/Worksheet/RowIterator.php';
  73.  
  74. /** PHPExcel_Comment */
  75. require_once 'PHPExcel/Comment.php';
  76.  
  77. /** PHPExcel_Style */
  78. require_once 'PHPExcel/Style.php';
  79.  
  80. /** PHPExcel_Style_Fill */
  81. require_once 'PHPExcel/Style/Fill.php';
  82.  
  83. /** PHPExcel_Style_NumberFormat */
  84. require_once 'PHPExcel/Style/NumberFormat.php';
  85.  
  86. /** PHPExcel_IComparable */
  87. require_once 'PHPExcel/IComparable.php';
  88.  
  89. /** PHPExcel_Shared_Font */
  90. require_once 'PHPExcel/Shared/Font.php';
  91.  
  92. /** PHPExcel_Shared_String */
  93. require_once 'PHPExcel/Shared/String.php';
  94.  
  95. /** PHPExcel_Shared_PasswordHasher */
  96. require_once 'PHPExcel/Shared/PasswordHasher.php';
  97.  
  98. /** PHPExcel_ReferenceHelper */
  99. require_once 'PHPExcel/ReferenceHelper.php';
  100.  
  101.  
  102. /**
  103.  * PHPExcel_Worksheet
  104.  *
  105.  * @category   PHPExcel
  106.  * @package    PHPExcel_Worksheet
  107.  * @copyright  Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  108.  */
  109. class PHPExcel_Worksheet implements PHPExcel_IComparable
  110. {
  111.     /* Break types */
  112.     const BREAK_NONE    0;
  113.     const BREAK_ROW        1;
  114.     const BREAK_COLUMN    2;
  115.  
  116.     /**
  117.      * Parent spreadsheet
  118.      *
  119.      * @var PHPExcel 
  120.      */
  121.     private $_parent;
  122.  
  123.     /**
  124.      * Collection of cells
  125.      *
  126.      * @var PHPExcel_Cell[] 
  127.      */
  128.     private $_cellCollection = array();
  129.  
  130.     /**
  131.      * Collection of row dimensions
  132.      *
  133.      * @var PHPExcel_Worksheet_RowDimension[] 
  134.      */
  135.     private $_rowDimensions = array();
  136.  
  137.     /**
  138.      * Default row dimension
  139.      *
  140.      * @var PHPExcel_Worksheet_RowDimension 
  141.      */
  142.     private $_defaultRowDimension = null;
  143.  
  144.     /**
  145.      * Collection of column dimensions
  146.      *
  147.      * @var PHPExcel_Worksheet_ColumnDimension[] 
  148.      */
  149.     private $_columnDimensions = array();
  150.  
  151.     /**
  152.      * Default column dimension
  153.      *
  154.      * @var PHPExcel_Worksheet_ColumnDimension 
  155.      */
  156.     private $_defaultColumnDimension = null;
  157.  
  158.     /**
  159.      * Collection of drawings
  160.      *
  161.      * @var PHPExcel_Worksheet_BaseDrawing[] 
  162.      */
  163.     private $_drawingCollection = null;
  164.  
  165.     /**
  166.      * Worksheet title
  167.      *
  168.      * @var string 
  169.      */
  170.     private $_title;
  171.  
  172.     /**
  173.      * Page setup
  174.      *
  175.      * @var PHPExcel_Worksheet_PageSetup 
  176.      */
  177.     private $_pageSetup;
  178.  
  179.     /**
  180.      * Page margins
  181.      *
  182.      * @var PHPExcel_Worksheet_PageMargins 
  183.      */
  184.     private $_pageMargins;
  185.  
  186.     /**
  187.      * Page header/footer
  188.      *
  189.      * @var PHPExcel_Worksheet_HeaderFooter 
  190.      */
  191.     private $_headerFooter;
  192.     
  193.     /**
  194.      * Sheet view
  195.      *
  196.      * @var PHPExcel_Worksheet_SheetView 
  197.      */
  198.     private $_sheetView;
  199.  
  200.     /**
  201.      * Protection
  202.      *
  203.      * @var PHPExcel_Worksheet_Protection 
  204.      */
  205.     private $_protection;
  206.  
  207.     /**
  208.      * Collection of styles
  209.      *
  210.      * @var PHPExcel_Style[] 
  211.      */
  212.     private $_styles = array();
  213.  
  214.     /**
  215.      * Is the current cell collection sorted already?
  216.      *
  217.      * @var boolean 
  218.      */
  219.     private $_cellCollectionIsSorted = false;
  220.  
  221.     /**
  222.      * Collection of breaks
  223.      *
  224.      * @var array 
  225.      */
  226.     private $_breaks = array();
  227.  
  228.     /**
  229.      * Collection of merged cell ranges
  230.      *
  231.      * @var array 
  232.      */
  233.     private $_mergeCells = array();
  234.  
  235.     /**
  236.      * Collection of protected cell ranges
  237.      *
  238.      * @var array 
  239.      */
  240.     private $_protectedCells = array();
  241.  
  242.     /**
  243.      * Autofilter Range
  244.      *
  245.      * @var string 
  246.      */
  247.     private $_autoFilter = '';
  248.  
  249.     /**
  250.      * Freeze pane
  251.      *
  252.      * @var string 
  253.      */
  254.     private $_freezePane = '';
  255.  
  256.     /**
  257.      * Show gridlines?
  258.      *
  259.      * @var boolean 
  260.      */
  261.     private $_showGridlines = true;
  262.  
  263.     /**
  264.     * Print gridlines?
  265.     *
  266.     * @var boolean 
  267.     */
  268.     private $_printGridlines = false;
  269.  
  270.     /**
  271.      * Show summary below? (Row/Column outline)
  272.      *
  273.      * @var boolean 
  274.      */
  275.     private $_showSummaryBelow = true;
  276.  
  277.     /**
  278.      * Show summary right? (Row/Column outline)
  279.      *
  280.      * @var boolean 
  281.      */
  282.     private $_showSummaryRight = true;
  283.  
  284.     /**
  285.      * Collection of comments
  286.      *
  287.      * @var PHPExcel_Comment[] 
  288.      */
  289.     private $_comments = array();
  290.  
  291.     /**
  292.      * Selected cell
  293.      *
  294.      * @var string 
  295.      */
  296.     private $_selectedCell = 'A1';
  297.  
  298.     /**
  299.      * Cached highest column
  300.      *
  301.      * @var string 
  302.      */
  303.     private $_cachedHighestColumn = null;
  304.  
  305.     /**
  306.      * Cached highest row
  307.      *
  308.      * @var int 
  309.      */
  310.     private $_cachedHighestRow = null;
  311.  
  312.     /**
  313.      * Create a new worksheet
  314.      *
  315.      * @param PHPExcel         $pParent 
  316.      * @param string         $pTitle 
  317.      */
  318.     public function __construct(PHPExcel $pParent null$pTitle 'Worksheet')
  319.     {
  320.         // Set parent and title
  321.         $this->_parent = $pParent;
  322.         $this->setTitle($pTitle);
  323.  
  324.         // Set page setup
  325.         $this->_pageSetup             = new PHPExcel_Worksheet_PageSetup();
  326.  
  327.         // Set page margins
  328.         $this->_pageMargins         = new PHPExcel_Worksheet_PageMargins();
  329.  
  330.         // Set page header/footer
  331.         $this->_headerFooter         = new PHPExcel_Worksheet_HeaderFooter();
  332.         
  333.         // Set sheet view
  334.         $this->_sheetView           = new PHPExcel_Worksheet_SheetView();
  335.  
  336.         // Create a default style and a default gray125 style
  337.         if (is_null(PHPExcel_Style::getDefaultStyle())) $dummy new PHPExcel_Style();
  338.         $this->_styles['default']     PHPExcel_Style::getDefaultStyle();
  339.         $this->_styles['gray125']     new PHPExcel_Style();
  340.         $this->_styles['gray125']->getFill()->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125);
  341.  
  342.         // Drawing collection
  343.         $this->_drawingCollection     = new ArrayObject();
  344.  
  345.         // Protection
  346.         $this->_protection            = new PHPExcel_Worksheet_Protection();
  347.  
  348.         // Gridlines
  349.         $this->_showGridlines        = true;
  350.         $this->_printGridlines        = false;
  351.  
  352.         // Outline summary
  353.         $this->_showSummaryBelow    = true;
  354.         $this->_showSummaryRight    = true;
  355.  
  356.         // Default row dimension
  357.         $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null);
  358.  
  359.         // Default column dimension
  360.         $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null);
  361.     }
  362.  
  363.     /**
  364.      * Get collection of cells
  365.      *
  366.      * @return PHPExcel_Cell[] 
  367.      */
  368.     public function getCellCollection()
  369.     {
  370.         // Garbage collect...
  371.         $this->garbageCollect();
  372.         
  373.         // Re-order cell collection
  374.         $this->sortCellCollection();
  375.         
  376.         return $this->_cellCollection;
  377.     }
  378.  
  379.     /**
  380.      * Sort collection of cells
  381.      */
  382.     public function sortCellCollection()
  383.     {
  384.         if (!$this->_cellCollectionIsSorted{
  385.             // Re-order cell collection
  386.             // uasort($this->_cellCollection, array('PHPExcel_Cell', 'compareCells')); <-- slow
  387.             
  388.             $indexed array();
  389.             foreach (array_keys($this->_cellCollectionas $index{
  390.                 $rowNum $this->_cellCollection[$index]->getRow();
  391.                 $colNum PHPExcel_Cell::columnIndexFromString($this->_cellCollection[$index]->getColumn());
  392.  
  393.                 // Columns are limited to ZZZ (18278), so 20000 is plenty to assure no conflicts
  394.                 $key =  $rowNum 20000 $colNum;
  395.  
  396.                 $indexed[$key$index// &$this->_cellCollection[$index];
  397.             }
  398.             ksort($indexed);
  399.             
  400.             // Rebuild cellCollection from the sorted index
  401.             $newCellCollection array();
  402.             foreach ($indexed as $index{
  403.                 $newCellCollection[$index$this->_cellCollection[$index];
  404.             }
  405.             
  406.             $this->_cellCollection = $newCellCollection;
  407.             
  408.             $this->_cellCollectionIsSorted = true;
  409.         }
  410.     }
  411.  
  412.     /**
  413.      * Get collection of row dimensions
  414.      *
  415.      * @return PHPExcel_Worksheet_RowDimension[] 
  416.      */
  417.     public function getRowDimensions()
  418.     {
  419.         return $this->_rowDimensions;
  420.     }
  421.  
  422.     /**
  423.      * Get default row dimension
  424.      *
  425.      * @return PHPExcel_Worksheet_RowDimension 
  426.      */
  427.     public function getDefaultRowDimension()
  428.     {
  429.         return $this->_defaultRowDimension;
  430.     }
  431.  
  432.     /**
  433.      * Get collection of column dimensions
  434.      *
  435.      * @return PHPExcel_Worksheet_ColumnDimension[] 
  436.      */
  437.     public function getColumnDimensions()
  438.     {
  439.         return $this->_columnDimensions;
  440.     }
  441.  
  442.     /**
  443.      * Get default column dimension
  444.      *
  445.      * @return PHPExcel_Worksheet_ColumnDimension 
  446.      */
  447.     public function getDefaultColumnDimension()
  448.     {
  449.         return $this->_defaultColumnDimension;
  450.     }
  451.  
  452.     /**
  453.      * Get collection of drawings
  454.      *
  455.      * @return PHPExcel_Worksheet_BaseDrawing[] 
  456.      */
  457.     public function getDrawingCollection()
  458.     {
  459.         return $this->_drawingCollection;
  460.     }
  461.  
  462.     /**
  463.      * Refresh column dimensions
  464.      */
  465.     public function refreshColumnDimensions()
  466.     {
  467.         $currentColumnDimensions $this->getColumnDimensions();
  468.         $newColumnDimensions array();
  469.  
  470.         foreach ($currentColumnDimensions as $objColumnDimension{
  471.             $newColumnDimensions[$objColumnDimension->getColumnIndex()$objColumnDimension;
  472.         }
  473.  
  474.         $this->_columnDimensions = $newColumnDimensions;
  475.     }
  476.  
  477.     /**
  478.      * Refresh row dimensions
  479.      */
  480.     public function refreshRowDimensions()
  481.     {
  482.         $currentRowDimensions $this->getRowDimensions();
  483.         $newRowDimensions array();
  484.  
  485.         foreach ($currentRowDimensions as $objRowDimension{
  486.             $newRowDimensions[$objRowDimension->getRowIndex()$objRowDimension;
  487.         }
  488.  
  489.         $this->_rowDimensions = $newRowDimensions;
  490.     }
  491.  
  492.     /**
  493.      * Calculate worksheet dimension
  494.      *
  495.      * @return string  String containing the dimension of this worksheet
  496.      */
  497.     public function calculateWorksheetDimension()
  498.     {
  499.         // Return
  500.         return 'A1' ':' .  $this->getHighestColumn($this->getHighestRow();
  501.     }
  502.  
  503.     /**
  504.      * Calculate widths for auto-size columns
  505.      *
  506.      * @param  boolean  $calculateMergeCells  Calculate merge cell width
  507.      */
  508.     public function calculateColumnWidths($calculateMergeCells false)
  509.     {
  510.         $autoSizes array();
  511.         foreach ($this->getColumnDimensions(as $colDimension{
  512.             if ($colDimension->getAutoSize()) {
  513.                 $autoSizes[$colDimension->getColumnIndex()= -1;
  514.             }
  515.         }
  516.  
  517.         foreach ($this->getCellCollection(as $cell{
  518.             if (isset($autoSizes[$cell->getColumn()])) {
  519.                 $cellValue $cell->getCalculatedValue();
  520.  
  521.                 foreach ($this->getMergeCells(as $cells{
  522.                     if ($cell->isInRange($cells&& !$calculateMergeCells{
  523.                         $cellValue ''// do not calculate merge cells
  524.                     }
  525.                 }
  526.  
  527.                 $autoSizes[$cell->getColumn()max(
  528.                     (float)$autoSizes[$cell->getColumn()],
  529.                     (float)PHPExcel_Shared_Font::calculateColumnWidth(
  530.                         $this->getStyle($cell->getCoordinate())->getFont()->getSize(),
  531.                         false,
  532.                         $cellValue,
  533.                         $this->getStyle($cell->getCoordinate())->getAlignment()->getTextRotation()
  534.                     )
  535.                 );
  536.             }
  537.         }
  538.         foreach ($autoSizes as $columnIndex => $width{
  539.             if ($width == -1$width $this->getDefaultColumnDimension()->getWidth();
  540.             $this->getColumnDimension($columnIndex)->setWidth($width);
  541.         }
  542.     }
  543.  
  544.     /**
  545.      * Get parent
  546.      *
  547.      * @return PHPExcel 
  548.      */
  549.     public function getParent({
  550.         return $this->_parent;
  551.     }
  552.  
  553.     /**
  554.      * Re-bind parent
  555.      *
  556.      * @param PHPExcel $parent 
  557.      */
  558.     public function rebindParent(PHPExcel $parent{
  559.         $namedRanges $this->_parent->getNamedRanges();
  560.         foreach ($namedRanges as $namedRange{
  561.             $parent->addNamedRange($namedRange);
  562.         }
  563.  
  564.         $this->_parent->removeSheetByIndex(
  565.             $this->_parent->getIndex($this)
  566.         );
  567.         $this->_parent = $parent;
  568.     }
  569.  
  570.     /**
  571.      * Get title
  572.      *
  573.      * @return string 
  574.      */
  575.     public function getTitle()
  576.     {
  577.         return $this->_title;
  578.     }
  579.  
  580.     /**
  581.      * Set title
  582.      *
  583.      * @param string $pValue String containing the dimension of this worksheet
  584.      * @throws Exception
  585.      */
  586.     public function setTitle($pValue 'Worksheet')
  587.     {
  588.         // Is this a 'rename' or not?
  589.         if ($this->getTitle(== $pValue{
  590.             return;
  591.         }
  592.  
  593.         // Maximum 31 characters allowed for sheet title
  594.         if (PHPExcel_Shared_String::CountCharacters($pValue31{
  595.             throw new Exception('Maximum 31 characters allowed in sheet title.');
  596.         }
  597.         
  598.         // Old title
  599.         $oldTitle $this->getTitle();
  600.  
  601.         // Loop trough all sheets in parent PHPExcel and verify unique names
  602.         $titleCount    0;
  603.         $aNames     $this->getParent()->getSheetNames();
  604.  
  605.         foreach ($aNames as $strName{
  606.             if ($strName == $pValue || substr($strName0strrpos($strName' ')) == $pValue{
  607.                 ++$titleCount;
  608.             }
  609.         }
  610.  
  611.         // Eventually, add a number to the sheet name
  612.         if ($titleCount 0{
  613.             $this->setTitle($pValue ' ' $titleCount);
  614.             return;
  615.         }
  616.  
  617.         // Set title
  618.         $this->_title = $pValue;
  619.         
  620.         // New title
  621.         $newTitle $this->getTitle();
  622.         PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->getParent()$oldTitle$newTitle);
  623.     }
  624.  
  625.     /**
  626.      * Get page setup
  627.      *
  628.      * @return PHPExcel_Worksheet_PageSetup 
  629.      */
  630.     public function getPageSetup()
  631.     {
  632.         return $this->_pageSetup;
  633.     }
  634.  
  635.     /**
  636.      * Set page setup
  637.      *
  638.      * @param PHPExcel_Worksheet_PageSetup    $pValue 
  639.      */
  640.     public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue)
  641.     {
  642.            $this->_pageSetup = $pValue;
  643.     }
  644.  
  645.     /**
  646.      * Get page margins
  647.      *
  648.      * @return PHPExcel_Worksheet_PageMargins 
  649.      */
  650.     public function getPageMargins()
  651.     {
  652.         return $this->_pageMargins;
  653.     }
  654.  
  655.     /**
  656.      * Set page margins
  657.      *
  658.      * @param PHPExcel_Worksheet_PageMargins    $pValue 
  659.      */
  660.     public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue)
  661.     {
  662.            $this->_pageMargins = $pValue;
  663.     }
  664.  
  665.     /**
  666.      * Get page header/footer
  667.      *
  668.      * @return PHPExcel_Worksheet_HeaderFooter 
  669.      */
  670.     public function getHeaderFooter()
  671.     {
  672.         return $this->_headerFooter;
  673.     }
  674.  
  675.     /**
  676.      * Set page header/footer
  677.      *
  678.      * @param PHPExcel_Worksheet_HeaderFooter    $pValue 
  679.      */
  680.     public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue)
  681.     {
  682.         $this->_headerFooter = $pValue;
  683.     }
  684.     
  685.     /**
  686.      * Get sheet view
  687.      *
  688.      * @return PHPExcel_Worksheet_HeaderFooter 
  689.      */
  690.     public function getSheetView()
  691.     {
  692.         return $this->_sheetView;
  693.     }
  694.  
  695.     /**
  696.      * Set sheet view
  697.      *
  698.      * @param PHPExcel_Worksheet_SheetView    $pValue 
  699.      */
  700.     public function setSheetView(PHPExcel_Worksheet_SheetView $pValue)
  701.     {
  702.         $this->_sheetView = $pValue;
  703.     }
  704.  
  705.     /**
  706.      * Get Protection
  707.      *
  708.      * @return PHPExcel_Worksheet_Protection 
  709.      */
  710.     public function getProtection()
  711.     {
  712.         return $this->_protection;
  713.     }
  714.  
  715.     /**
  716.      * Set Protection
  717.      *
  718.      * @param PHPExcel_Worksheet_Protection    $pValue 
  719.      */
  720.     public function setProtection(PHPExcel_Worksheet_Protection $pValue)
  721.     {
  722.            $this->_protection = $pValue;
  723.     }
  724.  
  725.     /**
  726.      * Get highest worksheet column
  727.      *
  728.      * @return string Highest column name
  729.      */
  730.     public function getHighestColumn()
  731.     {
  732.         // Cached?
  733.         if (!is_null($this->_cachedHighestColumn)) {
  734.             return $this->_cachedHighestColumn;
  735.         }
  736.     
  737.         // Highest column
  738.         $highestColumn = -1;
  739.  
  740.         // Loop trough cells
  741.         foreach ($this->_cellCollection as $cell{
  742.             if ($highestColumn PHPExcel_Cell::columnIndexFromString($cell->getColumn())) {
  743.                 $highestColumn PHPExcel_Cell::columnIndexFromString($cell->getColumn());
  744.             }
  745.         }
  746.  
  747.         // Loop trough column dimensions
  748.         foreach ($this->_columnDimensions as $dimension{
  749.             if ($highestColumn PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())) {
  750.                 $highestColumn PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex());
  751.             }
  752.         }
  753.  
  754.         // Return & cache
  755.         if ($highestColumn 0{
  756.             $this->_cachedHighestColumn = 'A';
  757.         else {
  758.             $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn);
  759.         }
  760.         
  761.         return $this->_cachedHighestColumn;
  762.     }
  763.  
  764.     /**
  765.      * Get highest worksheet row
  766.      *
  767.      * @return int Highest row number
  768.      */
  769.     public function getHighestRow()
  770.     {
  771.         // Cached?
  772.         if (!is_null($this->_cachedHighestRow)) {
  773.             return $this->_cachedHighestRow;
  774.         }
  775.     
  776.         // Highest row
  777.         $highestRow 1;
  778.  
  779.         // Loop trough cells
  780.         foreach ($this->_cellCollection as $cell{
  781.             if ($cell->getRow($highestRow{
  782.                 $highestRow $cell->getRow();
  783.             }
  784.         }
  785.  
  786.         // Loop trough row dimensions
  787.         foreach ($this->_rowDimensions as $dimension{
  788.             if ($highestRow $dimension->getRowIndex()) {
  789.                 $highestRow $dimension->getRowIndex();
  790.             }
  791.         }
  792.         
  793.         // Cache
  794.         $this->_cachedHighestRow = $highestRow;
  795.  
  796.         // Return
  797.         return $highestRow;
  798.     }
  799.  
  800.     /**
  801.      * Set a cell value
  802.      *
  803.      * @param string     $pCoordinate    Coordinate of the cell
  804.      * @param mixed     $pValue            Value of the cell
  805.      */
  806.     public function setCellValue($pCoordinate 'A1'$pValue null)
  807.     {
  808.         // Set value
  809.         $this->getCell($pCoordinate)->setValue($pValuetrue);
  810.     }
  811.  
  812.     /**
  813.      * Set a cell value by using numeric cell coordinates
  814.      *
  815.      * @param string     $pColumn        Numeric column coordinate of the cell
  816.      * @param string     $pRow            Numeric row coordinate of the cell
  817.      * @param mixed     $pValue            Value of the cell
  818.      */
  819.     public function setCellValueByColumnAndRow($pColumn 0$pRow 0$pValue null)
  820.     {
  821.         $this->setCellValue(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow$pValue);
  822.     }
  823.  
  824.     /**
  825.      * Set a cell value
  826.      *
  827.      * @param string     $pCoordinate    Coordinate of the cell
  828.      * @param mixed     $pValue            Value of the cell
  829.      * @param string    $pDataType        Explicit data type
  830.      */
  831.     public function setCellValueExplicit($pCoordinate 'A1'$pValue null$pDataType PHPExcel_Cell_DataType::TYPE_STRING)
  832.     {
  833.         // Set value
  834.         $this->getCell($pCoordinate)->setValueExplicit($pValue$pDataType);
  835.     }
  836.  
  837.     /**
  838.      * Set a cell value by using numeric cell coordinates
  839.      *
  840.      * @param string     $pColumn        Numeric column coordinate of the cell
  841.      * @param string     $pRow            Numeric row coordinate of the cell
  842.      * @param mixed     $pValue            Value of the cell
  843.      * @param string    $pDataType        Explicit data type
  844.      */
  845.     public function setCellValueExplicitByColumnAndRow($pColumn 0$pRow 0$pValue null$pDataType PHPExcel_Cell_DataType::TYPE_STRING)
  846.     {
  847.         $this->setCellValueExplicit(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow$pValue$pDataType);
  848.     }
  849.  
  850.     /**
  851.      * Get cell at a specific coordinate
  852.      *
  853.      * @param     string             $pCoordinate    Coordinate of the cell
  854.      * @throws     Exception
  855.      * @return     PHPExcel_Cell     Cell that was found
  856.      */
  857.     public function getCell($pCoordinate 'A1')
  858.     {
  859.         // Worksheet reference?
  860.         if (strpos($pCoordinate'!'!== false{
  861.             $worksheetReference PHPExcel_Worksheet::extractSheetTitle($pCoordinatetrue);
  862.             return $this->getParent()->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]);
  863.         }
  864.  
  865.         // Named range?
  866.         $namedRange PHPExcel_NamedRange::resolveRange($pCoordinate$this);
  867.         if (!is_null($namedRange)) {
  868.             $pCoordinate $namedRange->getRange();
  869.             if ($this->getHashCode(!= $namedRange->getWorksheet()->getHashCode()) {
  870.                 if (!$namedRange->getLocalOnly()) {
  871.                     return $namedRange->getWorksheet()->getCell($pCoordinate);
  872.                 else {
  873.                     throw new Exception('Named range ' $namedRange->getName(' is not accessible from within sheet ' $this->getTitle());
  874.                 }
  875.             }
  876.         }
  877.  
  878.         // Uppercase coordinate
  879.         $pCoordinate strtoupper($pCoordinate);
  880.  
  881.         if (strpos($pCoordinate,':'!== false || strpos($pCoordinate,','!== false{
  882.             throw new Exception('Cell coordinate can not be a range of cells.');
  883.         elseif (strpos($pCoordinate,'$'!== false{
  884.             throw new Exception('Cell coordinate must not be absolute.');
  885.         else {
  886.             // Coordinates
  887.             $aCoordinates PHPExcel_Cell::coordinateFromString($pCoordinate);
  888.  
  889.             // Cell exists?
  890.             if (!isset($this->_cellCollection[$pCoordinate])) {
  891.                 $this->_cellCollection[$pCoordinatenew PHPExcel_Cell($aCoordinates[0]$aCoordinates[1]nullnull$this);
  892.                 $this->_cellCollectionIsSorted = false;
  893.                 
  894.                 $this->_cachedHighestColumn = null;
  895.                 $this->_cachedHighestRow = null;
  896.             }
  897.  
  898.             return $this->_cellCollection[$pCoordinate];
  899.         }
  900.     }
  901.  
  902.     /**
  903.      * Get cell at a specific coordinate by using numeric cell coordinates
  904.      *
  905.      * @param     string $pColumn        Numeric column coordinate of the cell
  906.      * @param     string $pRow        Numeric row coordinate of the cell
  907.      * @return     PHPExcel_Cell         Cell that was found
  908.      */
  909.     public function getCellByColumnAndRow($pColumn 0$pRow 0)
  910.     {
  911.         return $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow);
  912.     }
  913.  
  914.     /**
  915.      * Cell at a specific coordinate exists?
  916.      *
  917.      * @param     string             $pCoordinate    Coordinate of the cell
  918.      * @throws     Exception
  919.      * @return     boolean 
  920.      */
  921.     public function cellExists($pCoordinate 'A1')
  922.     {
  923.         // Worksheet reference?
  924.         if (strpos($pCoordinate'!'!== false{
  925.             $worksheetReference PHPExcel_Worksheet::extractSheetTitle($pCoordinatetrue);
  926.             return $this->getParent()->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]);
  927.         }
  928.  
  929.         // Named range?
  930.         $namedRange PHPExcel_NamedRange::resolveRange($pCoordinate$this);
  931.         if (!is_null($namedRange)) {
  932.             $pCoordinate $namedRange->getRange();
  933.             if ($this->getHashCode(!= $namedRange->getWorksheet()->getHashCode()) {
  934.                 if (!$namedRange->getLocalOnly()) {
  935.                     return $namedRange->getWorksheet()->cellExists($pCoordinate);
  936.                 else {
  937.                     throw new Exception('Named range ' $namedRange->getName(' is not accessible from within sheet ' $this->getTitle());
  938.                 }
  939.             }
  940.         }
  941.  
  942.         // Uppercase coordinate
  943.         $pCoordinate strtoupper($pCoordinate);
  944.  
  945.         if (strpos($pCoordinate,':'!== false || strpos($pCoordinate,','!== false{
  946.             throw new Exception('Cell coordinate can not be a range of cells.');
  947.         elseif (strpos($pCoordinate,'$'!== false{
  948.             throw new Exception('Cell coordinate must not be absolute.');
  949.         else {
  950.             // Coordinates
  951.             $aCoordinates PHPExcel_Cell::coordinateFromString($pCoordinate);
  952.  
  953.             // Cell exists?
  954.             return isset($this->_cellCollection[$pCoordinate]);
  955.         }
  956.     }
  957.  
  958.     /**
  959.      * Cell at a specific coordinate by using numeric cell coordinates exists?
  960.      *
  961.      * @param     string $pColumn        Numeric column coordinate of the cell
  962.      * @param     string $pRow        Numeric row coordinate of the cell
  963.      * @return     boolean 
  964.      */
  965.     public function cellExistsByColumnAndRow($pColumn 0$pRow 0)
  966.     {
  967.         return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow);
  968.     }
  969.  
  970.     /**
  971.      * Get row dimension at a specific row
  972.      *
  973.      * @param int $pRow    Numeric index of the row
  974.      * @return PHPExcel_Worksheet_RowDimension 
  975.      */
  976.     public function getRowDimension($pRow 0)
  977.     {
  978.         // Found
  979.         $found null;
  980.  
  981.         // Get row dimension
  982.         if (!isset($this->_rowDimensions[$pRow])) {
  983.             $this->_rowDimensions[$pRownew PHPExcel_Worksheet_RowDimension($pRow);
  984.             $this->_cachedHighestRow = null;
  985.         }
  986.         return $this->_rowDimensions[$pRow];
  987.     }
  988.  
  989.     /**
  990.      * Get column dimension at a specific column
  991.      *
  992.      * @param string $pColumn    String index of the column
  993.      * @return PHPExcel_Worksheet_ColumnDimension 
  994.      */
  995.     public function getColumnDimension($pColumn 'A')
  996.     {
  997.         // Uppercase coordinate
  998.         $pColumn strtoupper($pColumn);
  999.  
  1000.         // Fetch dimensions
  1001.         if (!isset($this->_columnDimensions[$pColumn])) {
  1002.             $this->_columnDimensions[$pColumnnew PHPExcel_Worksheet_ColumnDimension($pColumn);
  1003.             $this->_cachedHighestColumn = null;
  1004.         }
  1005.         return $this->_columnDimensions[$pColumn];
  1006.     }
  1007.  
  1008.     /**
  1009.      * Get column dimension at a specific column by using numeric cell coordinates
  1010.      *
  1011.      * @param     string $pColumn        Numeric column coordinate of the cell
  1012.      * @param     string $pRow        Numeric row coordinate of the cell
  1013.      * @return     PHPExcel_Worksheet_ColumnDimension 
  1014.      */
  1015.     public function getColumnDimensionByColumn($pColumn 0)
  1016.     {
  1017.         return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn));
  1018.     }
  1019.  
  1020.     /**
  1021.      * Get styles
  1022.      *
  1023.      * @return PHPExcel_Style[] 
  1024.      */
  1025.     public function getStyles()
  1026.     {
  1027.         return $this->_styles;
  1028.     }
  1029.  
  1030.     /**
  1031.      * Get default style
  1032.      *
  1033.      * @return     PHPExcel_Style 
  1034.      * @throws     Exception
  1035.      */
  1036.     public function getDefaultStyle()
  1037.     {
  1038.         return PHPExcel_Style::getDefaultStyle();
  1039.     }
  1040.     
  1041.     /**
  1042.      * Set default style - should only be used by PHPExcel_IReader implementations!
  1043.      *
  1044.      * @param     PHPExcel_Style $value 
  1045.      * @throws     Exception
  1046.      */
  1047.     public function setDefaultStyle(PHPExcel_Style $value)
  1048.     {
  1049.         $this->_styles['default'$value// just a reference for PHPExcel_IWriter
  1050.         PHPExcel_Style::setDefaultStyle($value);
  1051.     }
  1052.     
  1053.     /**
  1054.      * Get style for cell
  1055.      *
  1056.      * @param     string     $pCellCoordinate    Cell coordinate to get style for
  1057.      * @return     PHPExcel_Style 
  1058.      * @throws     Exception
  1059.      */
  1060.     public function getStyle($pCellCoordinate 'A1')
  1061.     {
  1062.         // Worksheet reference?
  1063.         if (strpos($pCellCoordinate'!'!== false{
  1064.             $worksheetReference PHPExcel_Worksheet::extractSheetTitle($pCellCoordinatetrue);
  1065.             return $this->getParent()->getSheetByName($worksheetReference[0])->getStyle($worksheetReference[1]);
  1066.         }
  1067.  
  1068.         // Named range?
  1069.         $namedRange PHPExcel_NamedRange::resolveRange($pCellCoordinate$this);
  1070.         if (!is_null($namedRange)) {
  1071.             $pCoordinate $namedRange->getRange();
  1072.             if ($this->getHashCode(!= $namedRange->getWorksheet()->getHashCode()) {
  1073.                 if (!$namedRange->getLocalOnly()) {
  1074.                     return $namedRange->getWorksheet()->getStyle($pCellCoordinate);
  1075.                 else {
  1076.                     throw new Exception('Named range ' $namedRange->getName(' is not accessible from within sheet ' $this->getTitle());
  1077.                 }
  1078.             }
  1079.         }
  1080.  
  1081.         // Uppercase coordinate
  1082.         $pCellCoordinate strtoupper($pCellCoordinate);
  1083.  
  1084.         if (strpos($pCellCoordinate,':'!== false || strpos($pCellCoordinate,','!== false{
  1085.             throw new Exception('Cell coordinate string can not be a range of cells.');
  1086.         else if (strpos($pCellCoordinate,'$'!== false{
  1087.             throw new Exception('Cell coordinate string must not be absolute.');
  1088.         else if ($pCellCoordinate == ''{
  1089.             throw new Exception('Cell coordinate can not be zero-length string.');
  1090.         else {
  1091.             // Create a cell for this coordinate.
  1092.             // Reason: When we have an empty cell that has style information,
  1093.             // it should exist for our IWriter
  1094.             $this->getCell($pCellCoordinate);
  1095.  
  1096.             // Check if we already have style information for this cell.
  1097.             // If not, create a new style.
  1098.             if (isset($this->_styles[$pCellCoordinate])) {
  1099.                 return $this->_styles[$pCellCoordinate];
  1100.             else {
  1101.                 $newStyle clone $this->getDefaultStyle();
  1102.                 $this->_styles[$pCellCoordinate$newStyle;
  1103.                 return $newStyle;
  1104.             }
  1105.         }
  1106.     }
  1107.  
  1108.     /**
  1109.      * Get style for cell by using numeric cell coordinates
  1110.      *
  1111.      * @param     int $pColumn    Numeric column coordinate of the cell
  1112.      * @param     int $pRow        Numeric row coordinate of the cell
  1113.      * @return     PHPExcel_Style 
  1114.      */
  1115.     public function getStyleByColumnAndRow($pColumn 0$pRow 0)
  1116.     {
  1117.         return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow);
  1118.     }
  1119.  
  1120.     /**
  1121.      * Set shared cell style to a range of cells
  1122.      *
  1123.      * Please note that this will overwrite existing cell styles for cells in range!
  1124.      *
  1125.      * @param     PHPExcel_Style    $pSharedCellStyle    Cell style to share
  1126.      * @param     string            $pRange                Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1127.      * @throws    Exception
  1128.      */
  1129.      public function setSharedStyle(PHPExcel_Style $pSharedCellStyle null$pRange '')
  1130.     {
  1131.         // Uppercase coordinate
  1132.         $pRange strtoupper($pRange);
  1133.  
  1134.            // Is it a cell range or a single cell?
  1135.            $rangeA     '';
  1136.            $rangeB     '';
  1137.            if (strpos($pRange':'=== false{
  1138.                $rangeA $pRange;
  1139.                $rangeB $pRange;
  1140.            else {
  1141.                list($rangeA$rangeBexplode(':'$pRange);
  1142.            }
  1143.  
  1144.            // Calculate range outer borders
  1145.            $rangeStart PHPExcel_Cell::coordinateFromString($rangeA);
  1146.            $rangeEnd     PHPExcel_Cell::coordinateFromString($rangeB);
  1147.  
  1148.            // Translate column into index
  1149.            $rangeStart[0]    PHPExcel_Cell::columnIndexFromString($rangeStart[0]1;
  1150.            $rangeEnd[0]    PHPExcel_Cell::columnIndexFromString($rangeEnd[0]1;
  1151.  
  1152.            // Make sure we can loop upwards on rows and columns
  1153.            if ($rangeStart[0$rangeEnd[0&& $rangeStart[1$rangeEnd[1]{
  1154.                $tmp $rangeStart;
  1155.                $rangeStart $rangeEnd;
  1156.                $rangeEnd $tmp;
  1157.            }
  1158.  
  1159.            // Loop trough cells and apply styles
  1160.            for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  1161.                for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  1162.                    $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col$row);
  1163.                    $this->_stylesPHPExcel_Cell::stringFromColumnIndex($col$row $pSharedCellStyle;
  1164.                }
  1165.            }
  1166.     }
  1167.  
  1168.     /**
  1169.      * Duplicate cell style to a range of cells
  1170.      *
  1171.      * Please note that this will overwrite existing cell styles for cells in range!
  1172.      *
  1173.      * @param     PHPExcel_Style    $pCellStyle    Cell style to duplicate
  1174.      * @param     string            $pRange        Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1175.      * @throws    Exception
  1176.      */
  1177.     public function duplicateStyle(PHPExcel_Style $pCellStyle null$pRange '')
  1178.     {
  1179.         // Uppercase coordinate
  1180.         $pRange strtoupper($pRange);
  1181.  
  1182.            // Is it a cell range or a single cell?
  1183.            $rangeA     '';
  1184.            $rangeB     '';
  1185.            if (strpos($pRange':'=== false{
  1186.                $rangeA $pRange;
  1187.                $rangeB $pRange;
  1188.            else {
  1189.                list($rangeA$rangeBexplode(':'$pRange);
  1190.            }
  1191.  
  1192.            // Calculate range outer borders
  1193.            $rangeStart PHPExcel_Cell::coordinateFromString($rangeA);
  1194.            $rangeEnd     PHPExcel_Cell::coordinateFromString($rangeB);
  1195.  
  1196.            // Translate column into index
  1197.            $rangeStart[0]    PHPExcel_Cell::columnIndexFromString($rangeStart[0]1;
  1198.            $rangeEnd[0]    PHPExcel_Cell::columnIndexFromString($rangeEnd[0]1;
  1199.  
  1200.            // Make sure we can loop upwards on rows and columns
  1201.            if ($rangeStart[0$rangeEnd[0&& $rangeStart[1$rangeEnd[1]{
  1202.                $tmp $rangeStart;
  1203.                $rangeStart $rangeEnd;
  1204.                $rangeEnd $tmp;
  1205.            }
  1206.  
  1207.            // Loop trough cells and apply styles
  1208.            for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  1209.                for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  1210.                    $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col$row);
  1211.                    $this->_stylesPHPExcel_Cell::stringFromColumnIndex($col$row clone $pCellStyle;
  1212.                }
  1213.            }
  1214.     }
  1215.  
  1216.     /**
  1217.      * Duplicate cell style array to a range of cells
  1218.      *
  1219.      * Please note that this will overwrite existing cell styles for cells in range,
  1220.      * if they are in the styles array. For example, if you decide to set a range of
  1221.      * cells to font bold, only include font bold in the styles array.
  1222.      *
  1223.      * @param    array            $pStyles    Array containing style information
  1224.      * @param     string            $pRange        Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1225.      * @throws    Exception
  1226.      */
  1227.     public function duplicateStyleArray($pStyles null$pRange '')
  1228.     {
  1229.         if (is_array($pStyles)) {
  1230.             // Uppercase coordinate
  1231.             $pRange strtoupper($pRange);
  1232.  
  1233.                // Is it a cell range or a single cell?
  1234.                $rangeA     '';
  1235.                $rangeB     '';
  1236.                if (strpos($pRange':'=== false{
  1237.                    $rangeA $pRange;
  1238.                    $rangeB $pRange;
  1239.                else {
  1240.                    list($rangeA$rangeBexplode(':'$pRange);
  1241.                }
  1242.  
  1243.                // Calculate range outer borders
  1244.                $rangeStart PHPExcel_Cell::coordinateFromString($rangeA);
  1245.                $rangeEnd     PHPExcel_Cell::coordinateFromString($rangeB);
  1246.  
  1247.                // Translate column into index
  1248.                $rangeStart[0]    PHPExcel_Cell::columnIndexFromString($rangeStart[0]1;
  1249.                $rangeEnd[0]    PHPExcel_Cell::columnIndexFromString($rangeEnd[0]1;
  1250.  
  1251.                // Make sure we can loop upwards on rows and columns
  1252.                if ($rangeStart[0$rangeEnd[0&& $rangeStart[1$rangeEnd[1]{
  1253.                    $tmp $rangeStart;
  1254.                    $rangeStart $rangeEnd;
  1255.                    $rangeEnd $tmp;
  1256.                }
  1257.  
  1258.                // Loop trough cells and apply styles array
  1259.                for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  1260.                    for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  1261.                        $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($col$row)->applyFromArray($pStyles);
  1262.                    }
  1263.                }
  1264.         else {
  1265.             throw new Exception("Invalid style array passed.");
  1266.         }
  1267.     }
  1268.  
  1269.     /**
  1270.      * Set break on a cell
  1271.      *
  1272.      * @param     string            $pCell        Cell coordinate (e.g. A1)
  1273.      * @param     int                $pBreak        Break type (type of PHPExcel_Worksheet::BREAK_*)
  1274.      * @throws    Exception
  1275.      */
  1276.     public function setBreak($pCell 'A1'$pBreak PHPExcel_Worksheet::BREAK_NONE)
  1277.     {
  1278.         // Uppercase coordinate
  1279.         $pCell strtoupper($pCell);
  1280.  
  1281.         if ($pCell != ''{
  1282.             $this->_breaks[$pCell$pBreak;
  1283.         else {
  1284.             throw new Exception('No cell coordinate specified.');
  1285.         }
  1286.     }
  1287.  
  1288.     /**
  1289.      * Set break on a cell by using numeric cell coordinates
  1290.      *
  1291.      * @param     int     $pColumn    Numeric column coordinate of the cell
  1292.      * @param     int     $pRow        Numeric row coordinate of the cell
  1293.      * @param     int        $pBreak        Break type (type of PHPExcel_Worksheet::BREAK_*)
  1294.      * @throws    Exception
  1295.      */
  1296.     public function setBreakByColumnAndRow($pColumn 0$pRow 0$pBreak PHPExcel_Worksheet::BREAK_NONE)
  1297.     {
  1298.         $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow$pBreak);
  1299.     }
  1300.  
  1301.     /**
  1302.      * Get breaks
  1303.      *
  1304.      * @return array[] 
  1305.      */
  1306.     public function getBreaks()
  1307.     {
  1308.         return $this->_breaks;
  1309.     }
  1310.  
  1311.     /**
  1312.      * Set merge on a cell range
  1313.      *
  1314.      * @param     string            $pRange        Cell range (e.g. A1:E1)
  1315.      * @throws    Exception
  1316.      */
  1317.     public function mergeCells($pRange 'A1:A1')
  1318.     {
  1319.         // Uppercase coordinate
  1320.         $pRange strtoupper($pRange);
  1321.  
  1322.         if (strpos($pRange,':'!== false{
  1323.             $this->_mergeCells[$pRange$pRange;
  1324.         else {
  1325.             throw new Exception('Merge must be set on a range of cells.');
  1326.         }
  1327.     }
  1328.  
  1329.     /**
  1330.      * Set merge on a cell range by using numeric cell coordinates
  1331.      *
  1332.      * @param     int $pColumn1    Numeric column coordinate of the first cell
  1333.      * @param     int $pRow1        Numeric row coordinate of the first cell
  1334.      * @param     int $pColumn2    Numeric column coordinate of the last cell
  1335.      * @param     int $pRow2        Numeric row coordinate of the last cell
  1336.      * @throws    Exception
  1337.      */
  1338.     public function mergeCellsByColumnAndRow($pColumn1 0$pRow1 0$pColumn2 0$pRow2 0)
  1339.     {
  1340.         $cellRange PHPExcel_Cell::stringFromColumnIndex($pColumn1$pRow1 ':' PHPExcel_Cell::stringFromColumnIndex($pColumn2$pRow2;
  1341.         $this->mergeCells($cellRange);
  1342.     }
  1343.  
  1344.     /**
  1345.      * Remove merge on a cell range
  1346.      *
  1347.      * @param     string            $pRange        Cell range (e.g. A1:E1)
  1348.      * @throws    Exception
  1349.      */
  1350.     public function unmergeCells($pRange 'A1:A1')
  1351.     {
  1352.         // Uppercase coordinate
  1353.         $pRange strtoupper($pRange);
  1354.  
  1355.         if (strpos($pRange,':'!== false{
  1356.             if (isset($this->_mergeCells[$pRange])) {
  1357.                 unset($this->_mergeCells[$pRange]);
  1358.             else {
  1359.                 throw new Exception('Cell range ' $pRange ' not known as merged.');
  1360.             }
  1361.         else {
  1362.             throw new Exception('Merge can only be removed from a range of cells.');
  1363.         }
  1364.     }
  1365.  
  1366.     /**
  1367.      * Remove merge on a cell range by using numeric cell coordinates
  1368.      *
  1369.      * @param     int $pColumn1    Numeric column coordinate of the first cell
  1370.      * @param     int $pRow1        Numeric row coordinate of the first cell
  1371.      * @param     int $pColumn2    Numeric column coordinate of the last cell
  1372.      * @param     int $pRow2        Numeric row coordinate of the last cell
  1373.      * @throws    Exception
  1374.      */
  1375.     public function unmergeCellsByColumnAndRow($pColumn1 0$pRow1 0$pColumn2 0$pRow2 0)
  1376.     {
  1377.         $cellRange PHPExcel_Cell::stringFromColumnIndex($pColumn1$pRow1 ':' PHPExcel_Cell::stringFromColumnIndex($pColumn2$pRow2;
  1378.         $this->unmergeCells($cellRange);
  1379.     }
  1380.  
  1381.     /**
  1382.      * Get merge cells
  1383.      *
  1384.      * @return array[] 
  1385.      */
  1386.     public function getMergeCells()
  1387.     {
  1388.         return $this->_mergeCells;
  1389.     }
  1390.  
  1391.     /**
  1392.      * Set protection on a cell range
  1393.      *
  1394.      * @param     string            $pRange                Cell (e.g. A1) or cell range (e.g. A1:E1)
  1395.      * @param     string            $pPassword            Password to unlock the protection
  1396.      * @param     boolean         $pAlreadyHashed     If the password has already been hashed, set this to true
  1397.      * @throws    Exception
  1398.      */
  1399.     public function protectCells($pRange 'A1'$pPassword ''$pAlreadyHashed false)
  1400.     {
  1401.         // Uppercase coordinate
  1402.         $pRange strtoupper($pRange);
  1403.  
  1404.         if (!$pAlreadyHashed{
  1405.             $pPassword PHPExcel_Shared_PasswordHasher::hashPassword($pPassword);
  1406.         }
  1407.         $this->_protectedCells[$pRange$pPassword;
  1408.     }
  1409.  
  1410.     /**
  1411.      * Set protection on a cell range by using numeric cell coordinates
  1412.      *
  1413.      * @param     int     $pColumn1            Numeric column coordinate of the first cell
  1414.      * @param     int     $pRow1                Numeric row coordinate of the first cell
  1415.      * @param     int     $pColumn2            Numeric column coordinate of the last cell
  1416.      * @param     int     $pRow2                Numeric row coordinate of the last cell
  1417.      * @param     string    $pPassword            Password to unlock the protection
  1418.      * @param     boolean $pAlreadyHashed     If the password has already been hashed, set this to true
  1419.      * @throws    Exception
  1420.      */
  1421.     public function protectCellsByColumnAndRow($pColumn1 0$pRow1 0$pColumn2 0$pRow2 0$pPassword ''$pAlreadyHashed false)
  1422.     {
  1423.         $cellRange PHPExcel_Cell::stringFromColumnIndex($pColumn1$pRow1 ':' PHPExcel_Cell::stringFromColumnIndex($pColumn2$pRow2;
  1424.         $this->protectCells($cellRange$pPassword$pAlreadyHashed);
  1425.     }
  1426.  
  1427.     /**
  1428.      * Remove protection on a cell range
  1429.      *
  1430.      * @param     string            $pRange        Cell (e.g. A1) or cell range (e.g. A1:E1)
  1431.      * @throws    Exception
  1432.      */
  1433.     public function unprotectCells($pRange 'A1')
  1434.     {
  1435.         // Uppercase coordinate
  1436.         $pRange strtoupper($pRange);
  1437.  
  1438.         if (isset($this->_protectedCells[$pRange])) {
  1439.             unset($this->_protectedCells[$pRange]);
  1440.         else {
  1441.             throw new Exception('Cell range ' $pRange ' not known as protected.');
  1442.         }
  1443.     }
  1444.  
  1445.     /**
  1446.      * Remove protection on a cell range by using numeric cell coordinates
  1447.      *
  1448.      * @param     int     $pColumn1            Numeric column coordinate of the first cell
  1449.      * @param     int     $pRow1                Numeric row coordinate of the first cell
  1450.      * @param     int     $pColumn2            Numeric column coordinate of the last cell
  1451.      * @param     int     $pRow2                Numeric row coordinate of the last cell
  1452.      * @param     string    $pPassword            Password to unlock the protection
  1453.      * @param     boolean $pAlreadyHashed     If the password has already been hashed, set this to true
  1454.      * @throws    Exception
  1455.      */
  1456.     public function unprotectCellsByColumnAndRow($pColumn1 0$pRow1 0$pColumn2 0$pRow2 0$pPassword ''$pAlreadyHashed false)
  1457.     {
  1458.         $cellRange PHPExcel_Cell::stringFromColumnIndex($pColumn1$pRow1 ':' PHPExcel_Cell::stringFromColumnIndex($pColumn2$pRow2;
  1459.         $this->unprotectCells($cellRange$pPassword$pAlreadyHashed);
  1460.     }
  1461.  
  1462.     /**
  1463.      * Get protected cells
  1464.      *
  1465.      * @return array[] 
  1466.      */
  1467.     public function getProtectedCells()
  1468.     {
  1469.         return $this->_protectedCells;
  1470.     }
  1471.  
  1472.     /**
  1473.      * Get Autofilter Range
  1474.      *
  1475.      * @return string 
  1476.      */
  1477.     public function getAutoFilter()
  1478.     {
  1479.         return $this->_autoFilter;
  1480.     }
  1481.  
  1482.     /**
  1483.      * Set Autofilter Range
  1484.      *
  1485.      * @param     string        $pRange        Cell range (i.e. A1:E10)
  1486.      * @throws     Exception
  1487.      */
  1488.     public function setAutoFilter($pRange '')
  1489.     {
  1490.         // Uppercase coordinate
  1491.         $pRange strtoupper($pRange);
  1492.  
  1493.         if (strpos($pRange,':'!== false{
  1494.             $this->_autoFilter = $pRange;
  1495.         else {
  1496.             throw new Exception('Autofilter must be set on a range of cells.');
  1497.         }
  1498.     }
  1499.  
  1500.     /**
  1501.      * Set Autofilter Range by using numeric cell coordinates
  1502.      *
  1503.      * @param     int     $pColumn1    Numeric column coordinate of the first cell
  1504.      * @param     int     $pRow1        Numeric row coordinate of the first cell
  1505.      * @param     int     $pColumn2    Numeric column coordinate of the second cell
  1506.      * @param     int     $pRow2        Numeric row coordinate of the second cell
  1507.      * @throws     Exception
  1508.      */
  1509.     public function setAutoFilterByColumnAndRow($pColumn1 0$pRow1 0$pColumn2 0$pRow2 0)
  1510.     {
  1511.         $this->setAutoFilter(
  1512.             PHPExcel_Cell::stringFromColumnIndex($pColumn1$pRow1
  1513.             . ':' .
  1514.             PHPExcel_Cell::stringFromColumnIndex($pColumn2$pRow2
  1515.         );
  1516.     }
  1517.  
  1518.     /**
  1519.      * Get Freeze Pane
  1520.      *
  1521.      * @return string 
  1522.      */
  1523.     public function getFreezePane()
  1524.     {
  1525.         return $this->_freezePane;
  1526.     }
  1527.  
  1528.     /**
  1529.      * Freeze Pane
  1530.      *
  1531.      * @param     string        $pCell        Cell (i.e. A1)
  1532.      * @throws     Exception
  1533.      */
  1534.     public function freezePane($pCell '')
  1535.     {
  1536.         // Uppercase coordinate
  1537.         $pCell strtoupper($pCell);
  1538.  
  1539.         if (strpos($pCell,':'=== false && strpos($pCell,','=== false{
  1540.             $this->_freezePane = $pCell;
  1541.         else {
  1542.             throw new Exception('Freeze pane can not be set on a range of cells.');
  1543.         }
  1544.     }
  1545.  
  1546.     /**
  1547.      * Freeze Pane by using numeric cell coordinates
  1548.      *
  1549.      * @param     int     $pColumn    Numeric column coordinate of the cell
  1550.      * @param     int     $pRow        Numeric row coordinate of the cell
  1551.      * @throws     Exception
  1552.      */
  1553.     public function freezePaneByColumnAndRow($pColumn 0$pRow 0)
  1554.     {
  1555.         $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow);
  1556.     }
  1557.  
  1558.     /**
  1559.      * Unfreeze Pane
  1560.      *
  1561.      * @return string 
  1562.      */
  1563.     public function unfreezePane()
  1564.     {
  1565.         $this->freezePane('');
  1566.     }
  1567.  
  1568.     /**
  1569.      * Insert a new row, updating all possible related data
  1570.      *
  1571.      * @param     int    $pBefore    Insert before this one
  1572.      * @param     int    $pNumRows    Number of rows to insert
  1573.      * @throws     Exception
  1574.      */
  1575.     public function insertNewRowBefore($pBefore 1$pNumRows 1{
  1576.         if ($pBefore >= 1{
  1577.             $objReferenceHelper PHPExcel_ReferenceHelper::getInstance();
  1578.             $objReferenceHelper->insertNewBefore('A' $pBefore0$pNumRows$this);
  1579.         else {
  1580.             throw new Exception("Rows can only be inserted before at least row 1.");
  1581.         }
  1582.  
  1583.         // Garbage collect...
  1584.         $this->garbageCollect();
  1585.     }
  1586.  
  1587.     /**
  1588.      * Insert a new column, updating all possible related data
  1589.      *
  1590.      * @param     int    $pBefore    Insert before this one
  1591.      * @param     int    $pNumCols    Number of columns to insert
  1592.      * @throws     Exception
  1593.      */
  1594.     public function insertNewColumnBefore($pBefore 'A'$pNumCols 1{
  1595.         if (!is_numeric($pBefore)) {
  1596.             $objReferenceHelper PHPExcel_ReferenceHelper::getInstance();
  1597.             $objReferenceHelper->insertNewBefore($pBefore '1'$pNumCols0$this);
  1598.         else {
  1599.             throw new Exception("Column references should not be numeric.");
  1600.         }
  1601.  
  1602.         // Garbage collect...
  1603.         $this->garbageCollect();
  1604.     }
  1605.  
  1606.     /**
  1607.      * Insert a new column, updating all possible related data
  1608.      *
  1609.      * @param     int    $pBefore    Insert before this one (numeric column coordinate of the cell)
  1610.      * @param     int    $pNumCols    Number of columns to insert
  1611.      * @throws     Exception
  1612.      */
  1613.     public function insertNewColumnBeforeByIndex($pBefore 0$pNumCols 1{
  1614.         if ($pBefore >= 0{
  1615.             $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore)$pNumCols);
  1616.         else {
  1617.             throw new Exception("Columns can only be inserted before at least column A (0).");
  1618.         }
  1619.  
  1620.         // Garbage collect...
  1621.         $this->garbageCollect();
  1622.     }
  1623.  
  1624.     /**
  1625.      * Delete a row, updating all possible related data
  1626.      *
  1627.      * @param     int    $pRow        Remove starting with this one
  1628.      * @param     int    $pNumRows    Number of rows to remove
  1629.      * @throws     Exception
  1630.      */
  1631.     public function removeRow($pRow 1$pNumRows 1{
  1632.         if ($pRow >= 1{
  1633.             $objReferenceHelper PHPExcel_ReferenceHelper::getInstance();
  1634.             $objReferenceHelper->insertNewBefore('A' ($pRow $pNumRows)0-$pNumRows$this);
  1635.         else {
  1636.             throw new Exception("Rows to be deleted should at least start from row 1.");
  1637.         }
  1638.  
  1639.         // Garbage collect...
  1640.         $this->garbageCollect();
  1641.     }
  1642.  
  1643.     /**
  1644.      * Remove a column, updating all possible related data
  1645.      *
  1646.      * @param     int    $pColumn    Remove starting with this one
  1647.      * @param     int    $pNumCols    Number of columns to remove
  1648.      * @throws     Exception
  1649.      */
  1650.     public function removeColumn($pColumn 'A'$pNumCols 1{
  1651.         if (!is_numeric($pColumn)) {
  1652.             $pColumn PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn$pNumCols);
  1653.             $objReferenceHelper PHPExcel_ReferenceHelper::getInstance();
  1654.             $objReferenceHelper->insertNewBefore($pColumn '1'-$pNumCols0$this);
  1655.         else {
  1656.             throw new Exception("Column references should not be numeric.");
  1657.         }
  1658.  
  1659.         // Garbage collect...
  1660.         $this->garbageCollect();
  1661.     }
  1662.  
  1663.     /**
  1664.      * Remove a column, updating all possible related data
  1665.      *
  1666.      * @param     int    $pColumn    Remove starting with this one (numeric column coordinate of the cell)
  1667.      * @param     int    $pNumCols    Number of columns to remove
  1668.      * @throws     Exception
  1669.      */
  1670.     public function removeColumnByIndex($pColumn 0$pNumCols 1{
  1671.         if ($pColumn >= 0{
  1672.             $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn)$pNumCols);
  1673.         else {
  1674.             throw new Exception("Columns can only be inserted before at least column A (0).");
  1675.         }
  1676.  
  1677.         // Garbage collect...
  1678.         $this->garbageCollect();
  1679.     }
  1680.  
  1681.     /**
  1682.      * Show gridlines?
  1683.      *
  1684.      * @return boolean 
  1685.      */
  1686.     public function getShowGridlines({
  1687.         return $this->_showGridlines;
  1688.     }
  1689.  
  1690.     /**
  1691.      * Set show gridlines
  1692.      *
  1693.      * @param boolean $pValue    Show gridlines (true/false)
  1694.      */
  1695.     public function setShowGridlines($pValue false{
  1696.         $this->_showGridlines = $pValue;
  1697.     }
  1698.  
  1699.     /**
  1700.     * Print gridlines?
  1701.     *
  1702.     * @return boolean 
  1703.     */
  1704.     public function getPrintGridlines({
  1705.         return $this->_printGridlines;
  1706.     }
  1707.  
  1708.     /**
  1709.     * Set print gridlines
  1710.     *
  1711.     * @param boolean $pValue Print gridlines (true/false)
  1712.     */
  1713.     public function setPrintGridlines($pValue false{
  1714.         $this->_printGridlines = $pValue;
  1715.     }
  1716.  
  1717.     /**
  1718.      * Show summary below? (Row/Column outlining)
  1719.      *
  1720.      * @return boolean 
  1721.      */
  1722.     public function getShowSummaryBelow({
  1723.         return $this->_showSummaryBelow;
  1724.     }
  1725.  
  1726.     /**
  1727.      * Set show summary below
  1728.      *
  1729.      * @param boolean $pValue    Show summary below (true/false)
  1730.      */
  1731.     public function setShowSummaryBelow($pValue true{
  1732.         $this->_showSummaryBelow = $pValue;
  1733.     }
  1734.  
  1735.     /**
  1736.      * Show summary right? (Row/Column outlining)
  1737.      *
  1738.      * @return boolean 
  1739.      */
  1740.     public function getShowSummaryRight({
  1741.         return $this->_showSummaryRight;
  1742.     }
  1743.  
  1744.     /**
  1745.      * Set show summary right
  1746.      *
  1747.      * @param boolean $pValue    Show summary right (true/false)
  1748.      */
  1749.     public function setShowSummaryRight($pValue true{
  1750.         $this->_showSummaryRight = $pValue;
  1751.     }
  1752.  
  1753.     /**
  1754.      * Get comments
  1755.      *
  1756.      * @return PHPExcel_Comment[] 
  1757.      */
  1758.     public function getComments()
  1759.     {
  1760.         return $this->_comments;
  1761.     }
  1762.  
  1763.     /**
  1764.      * Get comment for cell
  1765.      *
  1766.      * @param     string     $pCellCoordinate    Cell coordinate to get comment for
  1767.      * @return     PHPExcel_Comment 
  1768.      * @throws     Exception
  1769.      */
  1770.     public function getComment($pCellCoordinate 'A1')
  1771.     {
  1772.         // Uppercase coordinate
  1773.         $pCellCoordinate strtoupper($pCellCoordinate);
  1774.  
  1775.         if (strpos($pCellCoordinate,':'!== false || strpos($pCellCoordinate,','!== false{
  1776.             throw new Exception('Cell coordinate string can not be a range of cells.');
  1777.         else if (strpos($pCellCoordinate,'$'!== false{
  1778.             throw new Exception('Cell coordinate string must not be absolute.');
  1779.         else if ($pCellCoordinate == ''{
  1780.             throw new Exception('Cell coordinate can not be zero-length string.');
  1781.         else {
  1782.             // Check if we already have a comment for this cell.
  1783.             // If not, create a new comment.
  1784.             if (isset($this->_comments[$pCellCoordinate])) {
  1785.                 return $this->_comments[$pCellCoordinate];
  1786.             else {
  1787.                 $newComment new PHPExcel_Comment();
  1788.                 $this->_comments[$pCellCoordinate$newComment;
  1789.                 return $newComment;
  1790.             }
  1791.         }
  1792.     }
  1793.  
  1794.     /**
  1795.      * Get comment for cell by using numeric cell coordinates
  1796.      *
  1797.      * @param     int $pColumn    Numeric column coordinate of the cell
  1798.      * @param     int $pRow        Numeric row coordinate of the cell
  1799.      * @return     PHPExcel_Comment 
  1800.      */
  1801.     public function getCommentByColumnAndRow($pColumn 0$pRow 0)
  1802.     {
  1803.         return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow);
  1804.     }
  1805.  
  1806.     /**
  1807.      * Get selected cell
  1808.      *
  1809.      * @return string 
  1810.      */
  1811.     public function getSelectedCell()
  1812.     {
  1813.         return $this->_selectedCell;
  1814.     }
  1815.  
  1816.     /**
  1817.      * Selected cell
  1818.      *
  1819.      * @param     string        $pCell        Cell (i.e. A1)
  1820.      * @throws     Exception
  1821.      */
  1822.     public function setSelectedCell($pCell '')
  1823.     {
  1824.         // Uppercase coordinate
  1825.         $pCell strtoupper($pCell);
  1826.  
  1827.         if (strpos($pCoordinate,':'!== false || strpos($pCoordinate,','!== false{
  1828.             $this->_selectedCell = $pCell;
  1829.         else {
  1830.             throw new Exception('Selected cell can not be set on a range of cells.');
  1831.         }
  1832.     }
  1833.  
  1834.     /**
  1835.      * Selected cell by using numeric cell coordinates
  1836.      *
  1837.      * @param     int     $pColumn    Numeric column coordinate of the cell
  1838.      * @param     int     $pRow        Numeric row coordinate of the cell
  1839.      * @throws     Exception
  1840.      */
  1841.     public function setSelectedCellByColumnAndRow($pColumn 0$pRow 0)
  1842.     {
  1843.         $this->setSelectedCell(PHPExcel_Cell::stringFromColumnIndex($pColumn$pRow);
  1844.     }
  1845.  
  1846.     /**
  1847.      * Fill worksheet from values in array
  1848.      *
  1849.      * @param array $source    Source array
  1850.      * @param mixed $nullValue Value treated as "null"
  1851.      * @throws Exception
  1852.      */
  1853.     public function fromArray($source null$nullValue null{
  1854.         if (is_array($source)) {
  1855.             // Loop trough $source
  1856.             $currentRow 0;
  1857.             $rowData null;
  1858.             foreach ($source as $rowData{
  1859.                 ++$currentRow;
  1860.  
  1861.                 $rowCount count($rowData);
  1862.                 for ($i 0$i $rowCount++$i{
  1863.                     if ($rowData[$i!= $nullValue{
  1864.                         // Set cell value
  1865.                         $this->setCellValue(
  1866.                             PHPExcel_Cell::stringFromColumnIndex($i$currentRow$rowData[$i]
  1867.                         );
  1868.                     }
  1869.                 }
  1870.             }
  1871.         else {
  1872.             throw new Exception("Parameter \$source should be an array.");
  1873.         }
  1874.     }
  1875.  
  1876.     /**
  1877.      * Create array from worksheet
  1878.      *
  1879.      * @param mixed $nullValue Value treated as "null"
  1880.      * @param boolean $calculateFormulas Should formulas be calculated?
  1881.      * @return array 
  1882.      */
  1883.     public function toArray($nullValue null$calculateFormulas true{
  1884.         // Returnvalue
  1885.         $returnValue array();
  1886.  
  1887.         // Garbage collect...
  1888.         $this->garbageCollect();
  1889.  
  1890.         // Get worksheet dimension
  1891.         $dimension explode(':'$this->calculateWorksheetDimension());
  1892.         $dimension[0PHPExcel_Cell::coordinateFromString($dimension[0]);
  1893.         $dimension[0][0PHPExcel_Cell::columnIndexFromString($dimension[0][0]1;
  1894.         $dimension[1PHPExcel_Cell::coordinateFromString($dimension[1]);
  1895.         $dimension[1][0PHPExcel_Cell::columnIndexFromString($dimension[1][0]1;
  1896.  
  1897.         // Loop trough cells
  1898.         for ($row $dimension[0][1]$row <= $dimension[1][1]++$row{
  1899.             for ($column $dimension[0][0]$column <= $dimension[1][0]++$column{
  1900.                 // Cell exists?
  1901.                 if ($this->cellExistsByColumnAndRow($column$row)) {
  1902.                     $cell $this->getCellByColumnAndRow($column$row);
  1903.  
  1904.                     if ($cell->getValue(instanceof PHPExcel_RichText{
  1905.                         $returnValue[$row][$column$cell->getValue()->getPlainText();
  1906.                     else {
  1907.                         if ($calculateFormulas{
  1908.                             $returnValue[$row][$column$cell->getCalculatedValue();
  1909.                         else {
  1910.                             $returnValue[$row][$column$cell->getValue();
  1911.                         }
  1912.                     }
  1913.  
  1914.                     $style $this->getDefaultStyle();
  1915.                     if (isset($this->_styles[$cell->getCoordinate()])) {
  1916.                         $style $this->getStyleByColumnAndRow($column$row);
  1917.                     }
  1918.  
  1919.                     $returnValue[$row][$columnPHPExcel_Style_NumberFormat::toFormattedString($returnValue[$row][$column]$style->getNumberFormat()->getFormatCode());
  1920.                 else {
  1921.                     $returnValue[$row][$column$nullValue;
  1922.                 }
  1923.             }
  1924.         }
  1925.  
  1926.         // Return
  1927.         return $returnValue;
  1928.     }
  1929.     
  1930.     /**
  1931.      * Get row iterator
  1932.      *
  1933.      * @return PHPExcel_Worksheet_RowIterator 
  1934.      */
  1935.     public function getRowIterator({
  1936.         return new PHPExcel_Worksheet_RowIterator($this);
  1937.     }
  1938.  
  1939.     /**
  1940.      * Run PHPExcel garabage collector.
  1941.      */
  1942.     public function garbageCollect({
  1943.         // Build a reference table from images
  1944.         $imageCoordinates array();
  1945.           $iterator $this->getDrawingCollection()->getIterator();
  1946.            while ($iterator->valid()) {
  1947.                $imageCoordinates[$iterator->current()->getCoordinates()true;
  1948.  
  1949.                $iterator->next();
  1950.            }
  1951.  
  1952.            // Default style hash code
  1953.            $defaultStyleHashCode $this->_styles['default']->getHashCode();
  1954.            
  1955.         // Find cells that can be cleaned
  1956.         foreach ($this->_cellCollection as $coordinate => $cell{
  1957.             // Can be cleaned?
  1958.             $canBeCleaned false;
  1959.             
  1960.             // Current style hash code
  1961.             $currentStyleHashCode '';
  1962.             if (isset($this->_styles[$coordinate])) {
  1963.                 $currentStyleHashCode $this->_styles[$coordinate]->getHashCode();
  1964.             }
  1965.             
  1966.             // Empty value?
  1967.             if (is_null($cell->getValue()) || (!is_object($cell->getValue()) && $cell->getValue(=== '' && !$cell->hasHyperlink())) {
  1968.                 // Style set? Default style?
  1969.                 if ($currentStyleHashCode === $defaultStyleHashCode{
  1970.                     // It can be cleaned!
  1971.                     $canBeCleaned true;
  1972.                 }
  1973.             }
  1974.  
  1975.             // Referenced in image?
  1976.             if (isset($imageCoordinates[$coordinate]&& $imageCoordinates[$coordinate=== true{
  1977.                 $canBeCleaned false;
  1978.             }
  1979.  
  1980.             // Clean?
  1981.             if ($canBeCleaned{
  1982.                 unset($this->_cellCollection[$coordinate]);
  1983.  
  1984.                 // Does it resemble the default style?
  1985.                 if ($currentStyleHashCode === $defaultStyleHashCode{
  1986.                     unset($this->_styles[$coordinate]);
  1987.                 }
  1988.             }
  1989.         }
  1990.     }
  1991.  
  1992.     /**
  1993.      * Get hash code
  1994.      *
  1995.      * @return string    Hash code
  1996.      */
  1997.     public function getHashCode({
  1998.         return md5(
  1999.               $this->_title
  2000.             . $this->_autoFilter
  2001.             . ($this->_protection->isProtectionEnabled('t' 'f')
  2002.             //. $this->calculateWorksheetDimension()
  2003.             . __CLASS__
  2004.         );
  2005.     }
  2006.     
  2007.     /**
  2008.      * Hash index
  2009.      *
  2010.      * @var string 
  2011.      */
  2012.     private $_hashIndex;
  2013.     
  2014.     /**
  2015.      * Get hash index
  2016.      * 
  2017.      * Note that this index may vary during script execution! Only reliable moment is
  2018.      * while doing a write of a workbook and when changes are not allowed.
  2019.      *
  2020.      * @return string    Hash index
  2021.      */
  2022.     public function getHashIndex({
  2023.         return $this->_hashIndex;
  2024.     }
  2025.     
  2026.     /**
  2027.      * Set hash index
  2028.      * 
  2029.      * Note that this index may vary during script execution! Only reliable moment is
  2030.      * while doing a write of a workbook and when changes are not allowed.
  2031.      *
  2032.      * @param string    $value    Hash index
  2033.      */
  2034.     public function setHashIndex($value{
  2035.         $this->_hashIndex = $value;
  2036.     }
  2037.  
  2038.     /**
  2039.      * Extract worksheet title from range.
  2040.      *
  2041.      * Example: extractSheetTitle('test!A1') ==> 'test'
  2042.      * Example: extractSheetTitle('test!A1', true) ==> array('test', 'A1');
  2043.      *
  2044.      * @param string $pRange    Range to extract title from
  2045.      * @param bool $returnRange    Return range? (see example)
  2046.      * @return mixed 
  2047.      */
  2048.     public static function extractSheetTitle($pRange$returnRange false{
  2049.         // Sheet title included?
  2050.         if (strpos($pRange'!'=== false{
  2051.             return '';
  2052.         }
  2053.  
  2054.         // Extract sheet title
  2055.         $reference explode('!'$pRange);
  2056.         if (strpos($reference[0]'\''=== 0{
  2057.             $reference[0substr($reference[0]1);
  2058.         }
  2059.         if (strrpos($reference[0]'\''=== strlen($reference[0]1{
  2060.             $reference[0substr($reference[0]0strlen($reference[0]1);
  2061.         }
  2062.  
  2063.         if ($returnRange{
  2064.             return $reference;
  2065.         else {
  2066.             return $reference[1];
  2067.         }
  2068.     }
  2069.  
  2070.     /**
  2071.      * Copy worksheet (!= clone!)
  2072.      *
  2073.      * @return PHPExcel_Worksheet 
  2074.      */
  2075.     public function copy({
  2076.         $copied clone $this;
  2077.  
  2078.         return $copied;
  2079.     }
  2080.  
  2081.     /**
  2082.      * Implement PHP __clone to create a deep clone, not just a shallow copy.
  2083.      */
  2084.     public function __clone({
  2085.         foreach ($this as $key => $val{
  2086.             if (is_object($val|| (is_array($val))) {
  2087.                 $this->{$keyunserialize(serialize($val));
  2088.             }
  2089.         }
  2090.     }
  2091. }

Documentation generated on Wed, 22 Apr 2009 09:06:57 +0200 by phpDocumentor 1.4.1