| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 | <?php/** * PHPExcel_Style * * Copyright (c) 2006 - 2015 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 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL * @version    ##VERSION##, ##DATE## */class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable{    /**     * Font     *     * @var PHPExcel_Style_Font     */    protected $font;    /**     * Fill     *     * @var PHPExcel_Style_Fill     */    protected $fill;    /**     * Borders     *     * @var PHPExcel_Style_Borders     */    protected $borders;    /**     * Alignment     *     * @var PHPExcel_Style_Alignment     */    protected $alignment;    /**     * Number Format     *     * @var PHPExcel_Style_NumberFormat     */    protected $numberFormat;    /**     * Conditional styles     *     * @var PHPExcel_Style_Conditional[]     */    protected $conditionalStyles;    /**     * Protection     *     * @var PHPExcel_Style_Protection     */    protected $protection;    /**     * Index of style in collection. Only used for real style.     *     * @var int     */    protected $index;    /**     * Use Quote Prefix when displaying in cell editor. Only used for real style.     *     * @var boolean     */    protected $quotePrefix = false;    /**     * Create a new PHPExcel_Style     *     * @param boolean $isSupervisor Flag indicating if this is a supervisor or not     *         Leave this value at default unless you understand exactly what     *    its ramifications are     * @param boolean $isConditional Flag indicating if this is a conditional style or not     *       Leave this value at default unless you understand exactly what     *    its ramifications are     */    public function __construct($isSupervisor = false, $isConditional = false)    {        // Supervisor?        $this->isSupervisor = $isSupervisor;        // Initialise values        $this->conditionalStyles = array();        $this->font         = new PHPExcel_Style_Font($isSupervisor, $isConditional);        $this->fill         = new PHPExcel_Style_Fill($isSupervisor, $isConditional);        $this->borders      = new PHPExcel_Style_Borders($isSupervisor, $isConditional);        $this->alignment    = new PHPExcel_Style_Alignment($isSupervisor, $isConditional);        $this->numberFormat = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional);        $this->protection   = new PHPExcel_Style_Protection($isSupervisor, $isConditional);        // 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);        }    }    /**     * 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 parent. Only used for style supervisor     *     * @return PHPExcel     */    public function getParent()    {        return $this->parent;    }    /**     * Build style array from subcomponents     *     * @param array $array     * @return array     */    public function getStyleArray($array)    {        return array('quotePrefix' => $array);    }    /**     * 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'     *                     )     *                 )     *             ),     *             'quotePrefix'    => true     *         )     * );     * </code>     *     * @param    array    $pStyles    Array containing style information     * @param     boolean        $pAdvanced    Advanced mode for setting borders.     * @throws    PHPExcel_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();                            if ($x == 1) {                                // are we at left edge                                $edges[] = 'left';                            }                            if ($x == $xMax) {                                // are we at right edge                                $edges[] = 'right';                            }                            if ($y == 1) {                                // are we at top edge?                                $edges[] = 'top';                            }                            if ($y == $yMax) {                                // are we at bottom edge?                                $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 $this;                }                // SIMPLE MODE:                // Selection type, inspect                if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {                    $selectionType = 'COLUMN';                } elseif (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 array, 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']);                }                if (array_key_exists('quotePrefix', $pStyles)) {                    $this->quotePrefix = $pStyles['quotePrefix'];                }            }        } else {            throw new PHPExcel_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 quote prefix     *     * @return boolean     */    public function getQuotePrefix()    {        if ($this->isSupervisor) {            return $this->getSharedComponent()->getQuotePrefix();        }        return $this->quotePrefix;    }    /**     * Set quote prefix     *     * @param boolean $pValue     */    public function setQuotePrefix($pValue)    {        if ($pValue == '') {            $pValue = false;        }        if ($this->isSupervisor) {            $styleArray = array('quotePrefix' => $pValue);            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);        } else {            $this->quotePrefix = (boolean) $pValue;        }        return $this;    }    /**     * 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() .            ($this->quotePrefix  ? 't' : 'f') .            __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;    }}
 |