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

Source for file Worksheet.php

Documentation is available at Worksheet.php

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

Documentation generated on Mon, 27 Oct 2008 08:41:55 +0100 by phpDocumentor 1.4.1