1<?php 2 3/** 4 * PHPExcel_Writer_Excel5_Xf 5 * 6 * Copyright (c) 2006 - 2015 PHPExcel 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 * @category PHPExcel 23 * @package PHPExcel_Writer_Excel5 24 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 25 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 26 * @version ##VERSION##, ##DATE## 27 */ 28 29// Original file header of PEAR::Spreadsheet_Excel_Writer_Format (used as the base for this class): 30// ----------------------------------------------------------------------------------------- 31// /* 32// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> 33// * 34// * The majority of this is _NOT_ my code. I simply ported it from the 35// * PERL Spreadsheet::WriteExcel module. 36// * 37// * The author of the Spreadsheet::WriteExcel module is John McNamara 38// * <jmcnamara@cpan.org> 39// * 40// * I _DO_ maintain this code, and John McNamara has nothing to do with the 41// * porting of this code to PHP. Any questions directly related to this 42// * class library should be directed to me. 43// * 44// * License Information: 45// * 46// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets 47// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com 48// * 49// * This library is free software; you can redistribute it and/or 50// * modify it under the terms of the GNU Lesser General Public 51// * License as published by the Free Software Foundation; either 52// * version 2.1 of the License, or (at your option) any later version. 53// * 54// * This library is distributed in the hope that it will be useful, 55// * but WITHOUT ANY WARRANTY; without even the implied warranty of 56// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 57// * Lesser General Public License for more details. 58// * 59// * You should have received a copy of the GNU Lesser General Public 60// * License along with this library; if not, write to the Free Software 61// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 62// */ 63class PHPExcel_Writer_Excel5_Xf 64{ 65 /** 66 * Style XF or a cell XF ? 67 * 68 * @var boolean 69 */ 70 private $isStyleXf; 71 72 /** 73 * Index to the FONT record. Index 4 does not exist 74 * @var integer 75 */ 76 private $fontIndex; 77 78 /** 79 * An index (2 bytes) to a FORMAT record (number format). 80 * @var integer 81 */ 82 private $numberFormatIndex; 83 84 /** 85 * 1 bit, apparently not used. 86 * @var integer 87 */ 88 private $textJustLast; 89 90 /** 91 * The cell's foreground color. 92 * @var integer 93 */ 94 private $foregroundColor; 95 96 /** 97 * The cell's background color. 98 * @var integer 99 */ 100 private $backgroundColor; 101 102 /** 103 * Color of the bottom border of the cell. 104 * @var integer 105 */ 106 private $bottomBorderColor; 107 108 /** 109 * Color of the top border of the cell. 110 * @var integer 111 */ 112 private $topBorderColor; 113 114 /** 115 * Color of the left border of the cell. 116 * @var integer 117 */ 118 private $leftBorderColor; 119 120 /** 121 * Color of the right border of the cell. 122 * @var integer 123 */ 124 private $rightBorderColor; 125 126 /** 127 * Constructor 128 * 129 * @access public 130 * @param PHPExcel_Style The XF format 131 */ 132 public function __construct(PHPExcel_Style $style = null) 133 { 134 $this->isStyleXf = false; 135 $this->fontIndex = 0; 136 137 $this->numberFormatIndex = 0; 138 139 $this->textJustLast = 0; 140 141 $this->foregroundColor = 0x40; 142 $this->backgroundColor = 0x41; 143 144 $this->_diag = 0; 145 146 $this->bottomBorderColor = 0x40; 147 $this->topBorderColor = 0x40; 148 $this->leftBorderColor = 0x40; 149 $this->rightBorderColor = 0x40; 150 $this->_diag_color = 0x40; 151 $this->_style = $style; 152 153 } 154 155 156 /** 157 * Generate an Excel BIFF XF record (style or cell). 158 * 159 * @return string The XF record 160 */ 161 public function writeXf() 162 { 163 // Set the type of the XF record and some of the attributes. 164 if ($this->isStyleXf) { 165 $style = 0xFFF5; 166 } else { 167 $style = self::mapLocked($this->_style->getProtection()->getLocked()); 168 $style |= self::mapHidden($this->_style->getProtection()->getHidden()) << 1; 169 } 170 171 // Flags to indicate if attributes have been set. 172 $atr_num = ($this->numberFormatIndex != 0)?1:0; 173 $atr_fnt = ($this->fontIndex != 0)?1:0; 174 $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; 175 $atr_bdr = (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || 176 self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || 177 self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || 178 self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; 179 $atr_pat = (($this->foregroundColor != 0x40) || 180 ($this->backgroundColor != 0x41) || 181 self::mapFillType($this->_style->getFill()->getFillType()))?1:0; 182 $atr_prot = self::mapLocked($this->_style->getProtection()->getLocked()) 183 | self::mapHidden($this->_style->getProtection()->getHidden()); 184 185 // Zero the default border colour if the border has not been set. 186 if (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { 187 $this->bottomBorderColor = 0; 188 } 189 if (self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { 190 $this->topBorderColor = 0; 191 } 192 if (self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { 193 $this->rightBorderColor = 0; 194 } 195 if (self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { 196 $this->leftBorderColor = 0; 197 } 198 if (self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { 199 $this->_diag_color = 0; 200 } 201 202 $record = 0x00E0; // Record identifier 203 $length = 0x0014; // Number of bytes to follow 204 205 $ifnt = $this->fontIndex; // Index to FONT record 206 $ifmt = $this->numberFormatIndex; // Index to FORMAT record 207 208 $align = $this->mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment 209 $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; 210 $align |= self::mapVAlign($this->_style->getAlignment()->getVertical()) << 4; 211 $align |= $this->textJustLast << 7; 212 213 $used_attrib = $atr_num << 2; 214 $used_attrib |= $atr_fnt << 3; 215 $used_attrib |= $atr_alc << 4; 216 $used_attrib |= $atr_bdr << 5; 217 $used_attrib |= $atr_pat << 6; 218 $used_attrib |= $atr_prot << 7; 219 220 $icv = $this->foregroundColor; // fg and bg pattern colors 221 $icv |= $this->backgroundColor << 7; 222 223 $border1 = self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color 224 $border1 |= self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; 225 $border1 |= self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; 226 $border1 |= self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; 227 $border1 |= $this->leftBorderColor << 16; 228 $border1 |= $this->rightBorderColor << 23; 229 230 $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); 231 $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH 232 || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; 233 $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH 234 || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; 235 $border1 |= $diag_tl_to_rb << 30; 236 $border1 |= $diag_tr_to_lb << 31; 237 238 $border2 = $this->topBorderColor; // Border color 239 $border2 |= $this->bottomBorderColor << 7; 240 $border2 |= $this->_diag_color << 14; 241 $border2 |= self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; 242 $border2 |= self::mapFillType($this->_style->getFill()->getFillType()) << 26; 243 244 $header = pack("vv", $record, $length); 245 246 //BIFF8 options: identation, shrinkToFit and text direction 247 $biff8_options = $this->_style->getAlignment()->getIndent(); 248 $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; 249 250 $data = pack("vvvC", $ifnt, $ifmt, $style, $align); 251 $data .= pack("CCC", self::mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib); 252 $data .= pack("VVv", $border1, $border2, $icv); 253 254 return($header . $data); 255 } 256 257 /** 258 * Is this a style XF ? 259 * 260 * @param boolean $value 261 */ 262 public function setIsStyleXf($value) 263 { 264 $this->isStyleXf = $value; 265 } 266 267 /** 268 * Sets the cell's bottom border color 269 * 270 * @access public 271 * @param int $colorIndex Color index 272 */ 273 public function setBottomColor($colorIndex) 274 { 275 $this->bottomBorderColor = $colorIndex; 276 } 277 278 /** 279 * Sets the cell's top border color 280 * 281 * @access public 282 * @param int $colorIndex Color index 283 */ 284 public function setTopColor($colorIndex) 285 { 286 $this->topBorderColor = $colorIndex; 287 } 288 289 /** 290 * Sets the cell's left border color 291 * 292 * @access public 293 * @param int $colorIndex Color index 294 */ 295 public function setLeftColor($colorIndex) 296 { 297 $this->leftBorderColor = $colorIndex; 298 } 299 300 /** 301 * Sets the cell's right border color 302 * 303 * @access public 304 * @param int $colorIndex Color index 305 */ 306 public function setRightColor($colorIndex) 307 { 308 $this->rightBorderColor = $colorIndex; 309 } 310 311 /** 312 * Sets the cell's diagonal border color 313 * 314 * @access public 315 * @param int $colorIndex Color index 316 */ 317 public function setDiagColor($colorIndex) 318 { 319 $this->_diag_color = $colorIndex; 320 } 321 322 323 /** 324 * Sets the cell's foreground color 325 * 326 * @access public 327 * @param int $colorIndex Color index 328 */ 329 public function setFgColor($colorIndex) 330 { 331 $this->foregroundColor = $colorIndex; 332 } 333 334 /** 335 * Sets the cell's background color 336 * 337 * @access public 338 * @param int $colorIndex Color index 339 */ 340 public function setBgColor($colorIndex) 341 { 342 $this->backgroundColor = $colorIndex; 343 } 344 345 /** 346 * Sets the index to the number format record 347 * It can be date, time, currency, etc... 348 * 349 * @access public 350 * @param integer $numberFormatIndex Index to format record 351 */ 352 public function setNumberFormatIndex($numberFormatIndex) 353 { 354 $this->numberFormatIndex = $numberFormatIndex; 355 } 356 357 /** 358 * Set the font index. 359 * 360 * @param int $value Font index, note that value 4 does not exist 361 */ 362 public function setFontIndex($value) 363 { 364 $this->fontIndex = $value; 365 } 366 367 /** 368 * Map of BIFF2-BIFF8 codes for border styles 369 * @static array of int 370 * 371 */ 372 private static $mapBorderStyles = array( 373 PHPExcel_Style_Border::BORDER_NONE => 0x00, 374 PHPExcel_Style_Border::BORDER_THIN => 0x01, 375 PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, 376 PHPExcel_Style_Border::BORDER_DASHED => 0x03, 377 PHPExcel_Style_Border::BORDER_DOTTED => 0x04, 378 PHPExcel_Style_Border::BORDER_THICK => 0x05, 379 PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, 380 PHPExcel_Style_Border::BORDER_HAIR => 0x07, 381 PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, 382 PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, 383 PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, 384 PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, 385 PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, 386 PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, 387 ); 388 389 /** 390 * Map border style 391 * 392 * @param string $borderStyle 393 * @return int 394 */ 395 private static function mapBorderStyle($borderStyle) 396 { 397 if (isset(self::$mapBorderStyles[$borderStyle])) { 398 return self::$mapBorderStyles[$borderStyle]; 399 } 400 return 0x00; 401 } 402 403 /** 404 * Map of BIFF2-BIFF8 codes for fill types 405 * @static array of int 406 * 407 */ 408 private static $mapFillTypes = array( 409 PHPExcel_Style_Fill::FILL_NONE => 0x00, 410 PHPExcel_Style_Fill::FILL_SOLID => 0x01, 411 PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, 412 PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, 413 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, 414 PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, 415 PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, 416 PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, 417 PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, 418 PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, 419 PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, 420 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, 421 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, 422 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, 423 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, 424 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, 425 PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, 426 PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, 427 PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, 428 PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 429 PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 430 ); 431 432 /** 433 * Map fill type 434 * 435 * @param string $fillType 436 * @return int 437 */ 438 private static function mapFillType($fillType) 439 { 440 if (isset(self::$mapFillTypes[$fillType])) { 441 return self::$mapFillTypes[$fillType]; 442 } 443 return 0x00; 444 } 445 446 /** 447 * Map of BIFF2-BIFF8 codes for horizontal alignment 448 * @static array of int 449 * 450 */ 451 private static $mapHAlignments = array( 452 PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, 453 PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, 454 PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, 455 PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, 456 PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, 457 PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, 458 PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, 459 ); 460 461 /** 462 * Map to BIFF2-BIFF8 codes for horizontal alignment 463 * 464 * @param string $hAlign 465 * @return int 466 */ 467 private function mapHAlign($hAlign) 468 { 469 if (isset(self::$mapHAlignments[$hAlign])) { 470 return self::$mapHAlignments[$hAlign]; 471 } 472 return 0; 473 } 474 475 /** 476 * Map of BIFF2-BIFF8 codes for vertical alignment 477 * @static array of int 478 * 479 */ 480 private static $mapVAlignments = array( 481 PHPExcel_Style_Alignment::VERTICAL_TOP => 0, 482 PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, 483 PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, 484 PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, 485 ); 486 487 /** 488 * Map to BIFF2-BIFF8 codes for vertical alignment 489 * 490 * @param string $vAlign 491 * @return int 492 */ 493 private static function mapVAlign($vAlign) 494 { 495 if (isset(self::$mapVAlignments[$vAlign])) { 496 return self::$mapVAlignments[$vAlign]; 497 } 498 return 2; 499 } 500 501 /** 502 * Map to BIFF8 codes for text rotation angle 503 * 504 * @param int $textRotation 505 * @return int 506 */ 507 private static function mapTextRotation($textRotation) 508 { 509 if ($textRotation >= 0) { 510 return $textRotation; 511 } elseif ($textRotation == -165) { 512 return 255; 513 } elseif ($textRotation < 0) { 514 return 90 - $textRotation; 515 } 516 } 517 518 /** 519 * Map locked 520 * 521 * @param string 522 * @return int 523 */ 524 private static function mapLocked($locked) 525 { 526 switch ($locked) { 527 case PHPExcel_Style_Protection::PROTECTION_INHERIT: 528 return 1; 529 case PHPExcel_Style_Protection::PROTECTION_PROTECTED: 530 return 1; 531 case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: 532 return 0; 533 default: 534 return 1; 535 } 536 } 537 538 /** 539 * Map hidden 540 * 541 * @param string 542 * @return int 543 */ 544 private static function mapHidden($hidden) 545 { 546 switch ($hidden) { 547 case PHPExcel_Style_Protection::PROTECTION_INHERIT: 548 return 0; 549 case PHPExcel_Style_Protection::PROTECTION_PROTECTED: 550 return 1; 551 case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: 552 return 0; 553 default: 554 return 0; 555 } 556 } 557} 558