Bugfix: Work item 14999 - PHPExcel Excel2007 Reader colour problems with solidfill

Bugfix:	Work item 13215 - Formatting get lost and edit a template XLSX file
Bugfix:	Work item 14029 - Excel 2007 Reader /writer lost fontcolor
Bugfix:	Work item 13374 - file that makes cells go black 


git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@66428 2327b42d-5241-43d6-9e2a-de5ac946f064
This commit is contained in:
Mark Baker 2011-01-04 23:14:59 +00:00
parent 59b831c4f1
commit 74f299e5e5
4 changed files with 261 additions and 9 deletions

View File

@ -68,6 +68,8 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
private $_referenceHelper = null;
private static $_theme = null;
/**
* Read data only?
*
@ -342,6 +344,44 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
$zip = new ZipArchive;
$zip->open($pFilename);
// Read the theme first, because we need the colour scheme when reading the styles
$wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
foreach ($wbRels->Relationship as $rel) {
switch ($rel["Type"]) {
case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme":
$themeOrderArray = array('lt1','dk1','lt2','dk2');
$themeOrderAdditional = count($themeOrderArray);
$xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}"));
if (is_object($xmlTheme)) {
$xmlThemeName = $xmlTheme->attributes();
$xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main");
$themeName = (string)$xmlThemeName['name'];
$colourScheme = $xmlTheme->themeElements->clrScheme->attributes();
$colourSchemeName = (string)$colourScheme['name'];
$colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main");
$themeColours = array();
foreach ($colourScheme as $k => $xmlColour) {
$themePos = array_search($k,$themeOrderArray);
if ($themePos === false) {
$themePos = $themeOrderAdditional++;
}
if (isset($xmlColour->sysClr)) {
$xmlColourData = $xmlColour->sysClr->attributes();
$themeColours[$themePos] = $xmlColourData['lastClr'];
} elseif (isset($xmlColour->srgbClr)) {
$xmlColourData = $xmlColour->srgbClr->attributes();
$themeColours[$themePos] = $xmlColourData['val'];
}
}
self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours);
}
break;
}
}
$rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
foreach ($rels->Relationship as $rel) {
switch ($rel["Type"]) {
@ -1464,12 +1504,26 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
return $excel;
}
private static function _readColor($color) {
private static function _readColor($color, $background=false) {
if (isset($color["rgb"])) {
return (string)$color["rgb"];
} else if (isset($color["indexed"])) {
return PHPExcel_Style_Color::indexedColor($color["indexed"])->getARGB();
return PHPExcel_Style_Color::indexedColor($color["indexed"],$background)->getARGB();
} else if (isset($color["theme"])) {
if (!is_null(self::$_theme)) {
$returnColour = self::$_theme->getColourByIndex((int)$color["theme"]);
if (isset($color["tint"])) {
$tintAdjust = (float) $color["tint"];
$returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust);
}
return 'FF'.$returnColour;
}
}
if ($background) {
return 'FFFFFFFF';
}
return 'FF000000';
}
private static function _readStyle($docStyle, $style) {
@ -1519,18 +1573,18 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
}
$docStyle->getFill()->setRotation(floatval($gradientFill["degree"]));
$gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
$docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) );
$docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) );
$docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"),true)->color) );
$docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"),true)->color) );
} elseif ($style->fill->patternFill) {
$patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid';
$docStyle->getFill()->setFillType($patternType);
if ($style->fill->patternFill->fgColor) {
$docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor));
$docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true));
} else {
$docStyle->getFill()->getStartColor()->setARGB('FF000000');
}
if ($style->fill->patternFill->bgColor) {
$docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor));
$docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true));
}
}
}

View File

@ -0,0 +1,124 @@
<?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_Reader_Excel2007
* @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 ##VERSION##, ##DATE##
*/
/**
* PHPExcel_Reader_Excel2007_Theme
*
* @category PHPExcel
* @package PHPExcel_Reader_Excel2007
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
*/
class PHPExcel_Reader_Excel2007_Theme
{
/**
* Theme Name
*
* @var string
*/
private $_themeName;
/**
* Colour Scheme Name
*
* @var string
*/
private $_colourSchemeName;
/**
* Colour Map indexed by position
*
* @var array of string
*/
private $_colourMapValues;
/**
* Colour Map
*
* @var array of string
*/
private $_colourMap;
/**
* Create a new PHPExcel_Theme
*
*/
public function __construct($themeName,$colourSchemeName,$colourMap)
{
// Initialise values
$this->_themeName = $themeName;
$this->_colourSchemeName = $colourSchemeName;
$this->_colourMap = $colourMap;
}
/**
* Get Theme Name
*
* @return string
*/
public function getThemeName()
{
return $this->_themeName;
}
/**
* Get colour Scheme Name
*
* @return string
*/
public function getColourSchemeName() {
return $this->_colourSchemeName;
}
/**
* Get colour Map Value by Position
*
* @return string
*/
public function getColourByIndex($index=0) {
if (isset($this->_colourMap[$index])) {
return $this->_colourMap[$index];
}
return null;
}
/**
* 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;
}
}
}
}

View File

@ -291,13 +291,78 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable
return $this;
}
private static function _getColourComponent($RGB,$offset,$hex=true) {
$colour = substr($RGB,$offset,2);
if (!$hex)
$colour = hexdec($colour);
return $colour;
}
public static function getRed($RGB,$hex=true) {
if (strlen($RGB) == 8) {
return self::_getColourComponent($RGB,2,$hex);
} elseif (strlen($RGB) == 6) {
return self::_getColourComponent($RGB,0,$hex);
}
}
public static function getGreen($RGB,$hex=true) {
if (strlen($RGB) == 8) {
return self::_getColourComponent($RGB,4,$hex);
} elseif (strlen($RGB) == 6) {
return self::_getColourComponent($RGB,2,$hex);
}
}
public static function getBlue($RGB,$hex=true) {
if (strlen($RGB) == 8) {
return self::_getColourComponent($RGB,6,$hex);
} elseif (strlen($RGB) == 6) {
return self::_getColourComponent($RGB,4,$hex);
}
}
/**
* Adjust the brightness of a color
*
* @param string $hex The colour as an RGB value (e.g. FF00CCCC or CCDDEE
* @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1
* @return string The adjusted colour as an RGB value (e.g. FF00CCCC or CCDDEE
*/
public static function changeBrightness($hex, $adjustPercentage) {
$red = self::getRed($hex,false);
$green = self::getGreen($hex,false);
$blue = self::getBlue($hex,false);
if ($adjustPercentage > 0) {
$red += (255 - $red) * $adjustPercentage;
$green += (255 - $green) * $adjustPercentage;
$blue += (255 - $blue) * $adjustPercentage;
} else {
$red += $red * $adjustPercentage;
$green += $green * $adjustPercentage;
$blue += $blue * $adjustPercentage;
}
if ($red < 0) $red = 0;
elseif ($red > 255) $red = 255;
if ($green < 0) $green = 0;
elseif ($green > 255) $green = 255;
if ($blue < 0) $blue = 0;
elseif ($blue > 255) $blue = 255;
return strtoupper( str_pad(dechex($red), 2, '0', 0) .
str_pad(dechex($green), 2, '0', 0) .
str_pad(dechex($blue), 2, '0', 0)
);
}
/**
* Get indexed color
*
* @param int $pIndex
* @return PHPExcel_Style_Color
*/
public static function indexedColor($pIndex) {
public static function indexedColor($pIndex, $background=false) {
// Clean parameter
$pIndex = intval($pIndex);
@ -374,7 +439,10 @@ class PHPExcel_Style_Color implements PHPExcel_IComparable
return new PHPExcel_Style_Color(self::$_indexedColors[$pIndex]);
}
return new PHPExcel_Style_Color();
if ($background) {
return new PHPExcel_Style_Color('FFFFFFFF');
}
return new PHPExcel_Style_Color('FF000000');
}
/**

View File

@ -35,6 +35,12 @@ Fixed in SVN:
- Bugfix: (MBaker) Treat CodePage of 0 as CP1251 (for .xls files written by applications that don't set the CodePage correctly, such as Apple Numbers)
- Bugfix: (MB) Work item 11583 - Need method for removing autoFilter
- Bugfix: (MBaker) Work item 15029 - coordinateFromString throws exception for rows greater than 99,999
- Bugfix: (MBaker) Work item 14999 - PHPExcel Excel2007 Reader colour problems with solidfill
- Bugfix: (MBaker) Work item 13215 - Formatting get lost and edit a template XLSX file
- Bugfix: (MBaker) Work item 14029 - Excel 2007 Reader /writer lost fontcolor
- Bugfix: (MBaker) Work item 13374 - file that makes cells go black
2010-12-10 (v1.7.5):