| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679 | <?php/** * PHPExcel * * 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 * * @category   PHPExcel * @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 *//** * PHPExcel_Style * * @category   PHPExcel * @package    PHPExcel_Style * @copyright  Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) */class PHPExcel_Style implements PHPExcel_IComparable{	/**	 * Font	 *	 * @var PHPExcel_Style_Font	 */	private $_font;	/**	 * Fill	 *	 * @var PHPExcel_Style_Fill	 */	private $_fill;	/**	 * Borders	 *	 * @var PHPExcel_Style_Borders	 */	private $_borders;	/**	 * Alignment	 *	 * @var PHPExcel_Style_Alignment	 */	private $_alignment;	/**	 * Number Format	 *	 * @var PHPExcel_Style_NumberFormat	 */	private $_numberFormat;	/**	 * Conditional styles	 *	 * @var PHPExcel_Style_Conditional[]	 */	private $_conditionalStyles;	/**	 * Protection	 *	 * @var PHPExcel_Style_Protection	 */	private $_protection;	/**	 * Style supervisor?	 *	 * @var boolean	 */	private $_isSupervisor;	/**	 * Parent. Only used for style supervisor	 *	 * @var PHPExcel	 */	private $_parent;	/**	 * Index of style in collection. Only used for real style.	 *	 * @var int	 */	private $_index;    /**     * Create a new PHPExcel_Style	 *	 * @param boolean $isSupervisor     */    public function __construct($isSupervisor = false)    {    	// Supervisor?		$this->_isSupervisor = $isSupervisor;		// Initialise values    	$this->_conditionalStyles 	= array();		$this->_font				= new PHPExcel_Style_Font($isSupervisor);		$this->_fill				= new PHPExcel_Style_Fill($isSupervisor);		$this->_borders				= new PHPExcel_Style_Borders($isSupervisor);		$this->_alignment			= new PHPExcel_Style_Alignment($isSupervisor);		$this->_numberFormat		= new PHPExcel_Style_NumberFormat($isSupervisor);		$this->_protection			= new PHPExcel_Style_Protection($isSupervisor);		// bind parent if we are a supervisor		if ($isSupervisor) {			$this->_font->bindParent($this);			$this->_fill->bindParent($this);			$this->_borders->bindParent($this);			$this->_alignment->bindParent($this);			$this->_numberFormat->bindParent($this);			$this->_protection->bindParent($this);		}    }	/**	 * Bind parent. Only used for supervisor	 *	 * @param PHPExcel $parent	 * @return PHPExcel_Style	 */	public function bindParent($parent)	{		$this->_parent = $parent;		return $this;	}	/**	 * Is this a supervisor or a real style component?	 *	 * @return boolean	 */	public function getIsSupervisor()	{		return $this->_isSupervisor;	}	/**	 * Get the shared style component for the currently active cell in currently active sheet.	 * Only used for style supervisor	 *	 * @return PHPExcel_Style	 */	public function getSharedComponent()	{		$activeSheet = $this->getActiveSheet();		$selectedCell = $this->getActiveCell(); // e.g. 'A1'		if ($activeSheet->cellExists($selectedCell)) {			$xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();		} else {			$xfIndex = 0;		}		return $this->_parent->getCellXfByIndex($xfIndex);	}	/**	 * Get the currently active sheet. Only used for supervisor	 *	 * @return PHPExcel_Worksheet	 */	public function getActiveSheet()	{		return $this->_parent->getActiveSheet();	}	/**	 * Get the currently active cell coordinate in currently active sheet.	 * Only used for supervisor	 *	 * @return string E.g. 'A1'	 */	public function getSelectedCells()	{		return $this->_parent->getActiveSheet()->getSelectedCells();	}	/**	 * Get the currently active cell coordinate in currently active sheet.	 * Only used for supervisor	 *	 * @return string E.g. 'A1'	 */	public function getActiveCell()	{		return $this->_parent->getActiveSheet()->getActiveCell();	}	/**	 * Get parent. Only used for style supervisor	 *	 * @return PHPExcel	 */	public function getParent()	{		return $this->_parent;	}    /**     * Apply styles from array     *     * <code>     * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray(     * 		array(     * 			'font'    => array(     * 				'name'      => 'Arial',     * 				'bold'      => true,     * 				'italic'    => false,     * 				'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,     * 				'strike'    => false,     * 				'color'     => array(     * 					'rgb' => '808080'     * 				)     * 			),     * 			'borders' => array(     * 				'bottom'     => array(     * 					'style' => PHPExcel_Style_Border::BORDER_DASHDOT,     * 					'color' => array(     * 						'rgb' => '808080'     * 					)     * 				),     * 				'top'     => array(     * 					'style' => PHPExcel_Style_Border::BORDER_DASHDOT,     * 					'color' => array(     * 						'rgb' => '808080'     * 					)     * 				)     * 			)     * 		)     * );     * </code>     *     * @param	array	$pStyles	Array containing style information     * @param 	boolean		$pAdvanced	Advanced mode for setting borders.     * @throws	Exception     * @return PHPExcel_Style     */	public function applyFromArray($pStyles = null, $pAdvanced = true) {		if (is_array($pStyles)) {			if ($this->_isSupervisor) {				$pRange = $this->getSelectedCells();				// Uppercase coordinate				$pRange = strtoupper($pRange);				// Is it a cell range or a single cell?				if (strpos($pRange, ':') === false) {					$rangeA = $pRange;					$rangeB = $pRange;				} else {					list($rangeA, $rangeB) = explode(':', $pRange);				}				// Calculate range outer borders				$rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);				$rangeEnd 	= PHPExcel_Cell::coordinateFromString($rangeB);				// Translate column into index				$rangeStart[0]	= PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;				$rangeEnd[0]	= PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;				// Make sure we can loop upwards on rows and columns				if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {					$tmp = $rangeStart;					$rangeStart = $rangeEnd;					$rangeEnd = $tmp;				}				// ADVANCED MODE:				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						$colStart = ($x == 3) ?							PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0])								: PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);						// end column index for region						$colEnd = ($x == 1) ?							PHPExcel_Cell::stringFromColumnIndex($rangeStart[0])								: PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);						for ($y = 1; $y <= $yMax; ++$y) {							// which edges are touching the region							$edges = array();							// are we at left edge							if ($x == 1) {								$edges[] = 'left';							}							// are we at right edge							if ($x == $xMax) {								$edges[] = 'right';							}							// are we at top edge?							if ($y == 1) {								$edges[] = 'top';							}							// are we at bottom edge?							if ($y == $yMax) {								$edges[] = 'bottom';							}							// start row index for region							$rowStart = ($y == 3) ?								$rangeEnd[1] : $rangeStart[1] + $y - 1;							// end row index for region							$rowEnd = ($y == 1) ?								$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) {								switch ($innerEdge) {									case 'top':									case 'bottom':										// should pick up 'horizontal' border property if set										if (isset($pStyles['borders']['horizontal'])) {											$regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];										} else {											unset($regionStyles['borders'][$innerEdge]);										}										break;									case 'left':									case 'right':										// should pick up 'vertical' border property if set										if (isset($pStyles['borders']['vertical'])) {											$regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];										} else {											unset($regionStyles['borders'][$innerEdge]);										}										break;								}							}							// apply region style to region by calling applyFromArray() in simple mode							$this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);						}					}					return;				}				// SIMPLE MODE:				// 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)) {					$selectionType = 'ROW';				} else {					$selectionType = 'CELL';				}				// First loop through columns, rows, or cells to find out which styles are affected by this operation				switch ($selectionType) {					case 'COLUMN':						$oldXfIndexes = array();						for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {							$oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;						}						break;					case 'ROW':						$oldXfIndexes = array();						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							} else {								$oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;							}						}						break;					case 'CELL':						$oldXfIndexes = array();						for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {							for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {								$oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;							}						}						break;				}				// clone each of the affected styles, apply the style arrray, and add the new styles to the workbook				$workbook = $this->getActiveSheet()->getParent();				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();					} else {						// 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) {					case 'COLUMN':						for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {							$columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);							$oldXfIndex = $columnDimension->getXfIndex();							$columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);						}						break;					case 'ROW':						for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {							$rowDimension = $this->getActiveSheet()->getRowDimension($row);							$oldXfIndex = $rowDimension->getXfIndex() === null ?								0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style							$rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);						}						break;					case 'CELL':						for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {							for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {								$cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);								$oldXfIndex = $cell->getXfIndex();								$cell->setXfIndex($newXfIndexes[$oldXfIndex]);							}						}						break;				}			} else {				// not a supervisor, just apply the style array directly on style object				if (array_key_exists('fill', $pStyles)) {					$this->getFill()->applyFromArray($pStyles['fill']);				}				if (array_key_exists('font', $pStyles)) {					$this->getFont()->applyFromArray($pStyles['font']);				}				if (array_key_exists('borders', $pStyles)) {					$this->getBorders()->applyFromArray($pStyles['borders']);				}				if (array_key_exists('alignment', $pStyles)) {					$this->getAlignment()->applyFromArray($pStyles['alignment']);				}				if (array_key_exists('numberformat', $pStyles)) {					$this->getNumberFormat()->applyFromArray($pStyles['numberformat']);				}				if (array_key_exists('protection', $pStyles)) {					$this->getProtection()->applyFromArray($pStyles['protection']);				}			}		} else {			throw new Exception("Invalid style array passed.");		}		return $this;	}    /**     * Get Fill     *     * @return PHPExcel_Style_Fill     */    public function getFill() {		return $this->_fill;    }    /**     * Get Font     *     * @return PHPExcel_Style_Font     */    public function getFont() {		return $this->_font;    }	/**	 * Set font	 *	 * @param PHPExcel_Style_Font $font	 * @return PHPExcel_Style	 */	public function setFont(PHPExcel_Style_Font $font)	{		$this->_font = $font;		return $this;	}    /**     * Get Borders     *     * @return PHPExcel_Style_Borders     */    public function getBorders() {		return $this->_borders;    }    /**     * Get Alignment     *     * @return PHPExcel_Style_Alignment     */    public function getAlignment() {		return $this->_alignment;    }    /**     * Get Number Format     *     * @return PHPExcel_Style_NumberFormat     */    public function getNumberFormat() {		return $this->_numberFormat;    }    /**     * Get Conditional Styles. Only used on supervisor.     *     * @return PHPExcel_Style_Conditional[]     */    public function getConditionalStyles() {		return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());    }    /**     * Set Conditional Styles. Only used on supervisor.     *     * @param PHPExcel_Style_Conditional[]	$pValue	Array of condtional styles     * @return PHPExcel_Style     */    public function setConditionalStyles($pValue = null) {		if (is_array($pValue)) {			$this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);		}		return $this;    }    /**     * Get Protection     *     * @return PHPExcel_Style_Protection     */    public function getProtection() {		return $this->_protection;    }	/**	 * Get hash code	 *	 * @return string	Hash code	 */	public function getHashCode() {		$hashConditionals = '';		foreach ($this->_conditionalStyles as $conditional) {			$hashConditionals .= $conditional->getHashCode();		}    	return md5(    		  $this->_fill->getHashCode()    		. $this->_font->getHashCode()    		. $this->_borders->getHashCode()    		. $this->_alignment->getHashCode()    		. $this->_numberFormat->getHashCode()    		. $hashConditionals    		. $this->_protection->getHashCode()    		. __CLASS__    	);    }	/**	 * Get own index in style collection	 *	 * @return int	 */	public function getIndex()	{		return $this->_index;	}	/**	 * Set own index in style collection	 *	 * @param int $pValue	 */	public function setIndex($pValue)	{		$this->_index = $pValue;	}	/**	 * Implement PHP __clone to create a deep clone, not just a shallow copy.	 */	public function __clone() {		$vars = get_object_vars($this);		foreach ($vars as $key => $value) {			if ((is_object($value)) && ($key != '_parent')) {				$this->$key = clone $value;			} else {				$this->$key = $value;			}		}	}}
 |