Source for file Style.php
Documentation is available at Style.php
* Copyright (c) 2006 - 2011 PHPExcel
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* @package PHPExcel_Style
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version 1.7.6, 2011-02-27
* @package PHPExcel_Style
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
* @var PHPExcel_Style_Font
* @var PHPExcel_Style_Fill
* @var PHPExcel_Style_Borders
* @var PHPExcel_Style_Alignment
* @var PHPExcel_Style_NumberFormat
* @var PHPExcel_Style_Conditional[]
private $_conditionalStyles;
* @var PHPExcel_Style_Protection
* Parent. Only used for style supervisor
* Index of style in collection. Only used for real style.
* Create a new PHPExcel_Style
* @param boolean $isSupervisor
$this->_isSupervisor = $isSupervisor;
$this->_conditionalStyles = array();
// bind parent if we are a supervisor
* Bind parent. Only used for supervisor
* @param PHPExcel $parent
$this->_parent = $parent;
* Is this a supervisor or a real style component?
return $this->_isSupervisor;
* Get the shared style component for the currently active cell in currently active sheet.
* Only used for style supervisor
if ($activeSheet->cellExists($selectedCell)) {
$xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();
return $this->_parent->getCellXfByIndex($xfIndex);
* Get the currently active sheet. Only used for supervisor
* @return PHPExcel_Worksheet
return $this->_parent->getActiveSheet();
* Get the currently active cell coordinate in currently active sheet.
* Only used for supervisor
* @return string E.g. 'A1'
return $this->_parent->getActiveSheet()->getSelectedCells();
* Get the currently active cell coordinate in currently active sheet.
* Only used for supervisor
* @return string E.g. 'A1'
return $this->_parent->getActiveSheet()->getActiveCell();
* Get parent. Only used for style supervisor
* Apply styles from array
* $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray(
* 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
* 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
* 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
* @param array $pStyles Array containing style information
* @param boolean $pAdvanced Advanced mode for setting borders.
if ($this->_isSupervisor) {
// Is it a cell range or a single cell?
if (strpos($pRange, ':') === false) {
list ($rangeA, $rangeB) = explode(':', $pRange);
// Calculate range outer borders
// Translate column into index
// Make sure we can loop upwards on rows and columns
if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
if ($pAdvanced && isset ($pStyles['borders'])) {
// 'allborders' is a shorthand property for 'outline' and 'inside' and
// it applies to components that have not been set explicitly
if (isset ($pStyles['borders']['allborders'])) {
foreach (array('outline', 'inside') as $component) {
if (!isset ($pStyles['borders'][$component])) {
$pStyles['borders'][$component] = $pStyles['borders']['allborders'];
unset ($pStyles['borders']['allborders']); // not needed any more
// 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
// it applies to components that have not been set explicitly
if (isset ($pStyles['borders']['outline'])) {
foreach (array('top', 'right', 'bottom', 'left') as $component) {
if (!isset ($pStyles['borders'][$component])) {
$pStyles['borders'][$component] = $pStyles['borders']['outline'];
unset ($pStyles['borders']['outline']); // not needed any more
// 'inside' is a shorthand property for 'vertical' and 'horizontal'
// it applies to components that have not been set explicitly
if (isset ($pStyles['borders']['inside'])) {
foreach (array('vertical', 'horizontal') as $component) {
if (!isset ($pStyles['borders'][$component])) {
$pStyles['borders'][$component] = $pStyles['borders']['inside'];
unset ($pStyles['borders']['inside']); // not needed any more
// width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
$xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
$yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
// loop through up to 3 x 3 = 9 regions
for ($x = 1; $x <= $xMax; ++ $x) {
// start column index for region
// end column index for region
for ($y = 1; $y <= $yMax; ++ $y) {
// which edges are touching the region
// are we at bottom edge?
// start row index for region
$rangeEnd[1] : $rangeStart[1] + $y - 1;
// end row index for region
$rangeStart[1] : $rangeEnd[1] - $yMax + $y;
// build range for region
$range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
// retrieve relevant style array for region
$regionStyles = $pStyles;
unset ($regionStyles['borders']['inside']);
// what are the inner edges of the region when looking at the selection
$innerEdges = array_diff( array('top', 'right', 'bottom', 'left'), $edges );
// inner edges that are not touching the region should take the 'inside' border properties if they have been set
foreach ($innerEdges as $innerEdge) {
// should pick up 'horizontal' border property if set
if (isset ($pStyles['borders']['horizontal'])) {
$regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
unset ($regionStyles['borders'][$innerEdge]);
// should pick up 'vertical' border property if set
if (isset ($pStyles['borders']['vertical'])) {
$regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
unset ($regionStyles['borders'][$innerEdge]);
// apply region style to region by calling applyFromArray() in simple mode
$this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
// Selection type, inspect
if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
$selectionType = 'COLUMN';
} else if (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) {
// First loop through columns, rows, or cells to find out which styles are affected by this operation
switch ($selectionType) {
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++ $col) {
$oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++ $row) {
if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
$oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
$oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++ $col) {
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++ $row) {
$oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
// clone each of the affected styles, apply the style arrray, and add the new styles to the workbook
foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
$style = $workbook->getCellXfByIndex($oldXfIndex);
$newStyle = clone $style;
$newStyle->applyFromArray($pStyles);
if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
// there is already such cell Xf in our collection
$newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
// we don't have such a cell Xf, need to add
$workbook->addCellXf($newStyle);
$newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
// Loop through columns, rows, or cells again and update the XF index
switch ($selectionType) {
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++ $col) {
$columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
$oldXfIndex = $columnDimension->getXfIndex();
$columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++ $row) {
$oldXfIndex = $rowDimension->getXfIndex() === null ?
0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
$rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++ $col) {
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++ $row) {
$oldXfIndex = $cell->getXfIndex();
$cell->setXfIndex($newXfIndexes[$oldXfIndex]);
// not a supervisor, just apply the style array directly on style object
$this->getFill()->applyFromArray($pStyles['fill']);
$this->getFont()->applyFromArray($pStyles['font']);
$this->getBorders()->applyFromArray($pStyles['borders']);
$this->getAlignment()->applyFromArray($pStyles['alignment']);
throw new Exception("Invalid style array passed.");
* @return PHPExcel_Style_Fill
* @return PHPExcel_Style_Font
* @param PHPExcel_Style_Font $font
public function setFont(PHPExcel_Style_Font $font)
* @return PHPExcel_Style_Borders
* @return PHPExcel_Style_Alignment
return $this->_alignment;
* @return PHPExcel_Style_NumberFormat
return $this->_numberFormat;
* Get Conditional Styles. Only used on supervisor.
* @return PHPExcel_Style_Conditional[]
* Set Conditional Styles. Only used on supervisor.
* @param PHPExcel_Style_Conditional[] $pValue Array of condtional styles
* @return PHPExcel_Style_Protection
return $this->_protection;
* @return string Hash code
foreach ($this->_conditionalStyles as $conditional) {
$hashConditionals .= $conditional->getHashCode();
* Get own index in style collection
* Set own index in style collection
* Implement PHP __clone to create a deep clone, not just a shallow copy.
foreach ($vars as $key => $value) {
if ((is_object($value)) && ($key != '_parent')) {
$this->$key = clone $value;
|