[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * PHPExcel_Style_NumberFormat 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_Style 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 class PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable 29 { 30 /* Pre-defined formats */ 31 const FORMAT_GENERAL = 'General'; 32 33 const FORMAT_TEXT = '@'; 34 35 const FORMAT_NUMBER = '0'; 36 const FORMAT_NUMBER_00 = '0.00'; 37 const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00'; 38 const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-'; 39 40 const FORMAT_PERCENTAGE = '0%'; 41 const FORMAT_PERCENTAGE_00 = '0.00%'; 42 43 const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd'; 44 const FORMAT_DATE_YYYYMMDD = 'yy-mm-dd'; 45 const FORMAT_DATE_DDMMYYYY = 'dd/mm/yy'; 46 const FORMAT_DATE_DMYSLASH = 'd/m/y'; 47 const FORMAT_DATE_DMYMINUS = 'd-m-y'; 48 const FORMAT_DATE_DMMINUS = 'd-m'; 49 const FORMAT_DATE_MYMINUS = 'm-y'; 50 const FORMAT_DATE_XLSX14 = 'mm-dd-yy'; 51 const FORMAT_DATE_XLSX15 = 'd-mmm-yy'; 52 const FORMAT_DATE_XLSX16 = 'd-mmm'; 53 const FORMAT_DATE_XLSX17 = 'mmm-yy'; 54 const FORMAT_DATE_XLSX22 = 'm/d/yy h:mm'; 55 const FORMAT_DATE_DATETIME = 'd/m/y h:mm'; 56 const FORMAT_DATE_TIME1 = 'h:mm AM/PM'; 57 const FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM'; 58 const FORMAT_DATE_TIME3 = 'h:mm'; 59 const FORMAT_DATE_TIME4 = 'h:mm:ss'; 60 const FORMAT_DATE_TIME5 = 'mm:ss'; 61 const FORMAT_DATE_TIME6 = 'h:mm:ss'; 62 const FORMAT_DATE_TIME7 = 'i:s.S'; 63 const FORMAT_DATE_TIME8 = 'h:mm:ss;@'; 64 const FORMAT_DATE_YYYYMMDDSLASH = 'yy/mm/dd;@'; 65 66 const FORMAT_CURRENCY_USD_SIMPLE = '"$"#,##0.00_-'; 67 const FORMAT_CURRENCY_USD = '$#,##0_-'; 68 const FORMAT_CURRENCY_EUR_SIMPLE = '[$EUR ]#,##0.00_-'; 69 70 /** 71 * Excel built-in number formats 72 * 73 * @var array 74 */ 75 protected static $builtInFormats; 76 77 /** 78 * Excel built-in number formats (flipped, for faster lookups) 79 * 80 * @var array 81 */ 82 protected static $flippedBuiltInFormats; 83 84 /** 85 * Format Code 86 * 87 * @var string 88 */ 89 protected $formatCode = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; 90 91 /** 92 * Built-in format Code 93 * 94 * @var string 95 */ 96 protected $builtInFormatCode = 0; 97 98 /** 99 * Create a new PHPExcel_Style_NumberFormat 100 * 101 * @param boolean $isSupervisor Flag indicating if this is a supervisor or not 102 * Leave this value at default unless you understand exactly what 103 * its ramifications are 104 * @param boolean $isConditional Flag indicating if this is a conditional style or not 105 * Leave this value at default unless you understand exactly what 106 * its ramifications are 107 */ 108 public function __construct($isSupervisor = false, $isConditional = false) 109 { 110 // Supervisor? 111 parent::__construct($isSupervisor); 112 113 if ($isConditional) { 114 $this->formatCode = null; 115 $this->builtInFormatCode = false; 116 } 117 } 118 119 /** 120 * Get the shared style component for the currently active cell in currently active sheet. 121 * Only used for style supervisor 122 * 123 * @return PHPExcel_Style_NumberFormat 124 */ 125 public function getSharedComponent() 126 { 127 return $this->parent->getSharedComponent()->getNumberFormat(); 128 } 129 130 /** 131 * Build style array from subcomponents 132 * 133 * @param array $array 134 * @return array 135 */ 136 public function getStyleArray($array) 137 { 138 return array('numberformat' => $array); 139 } 140 141 /** 142 * Apply styles from array 143 * 144 * <code> 145 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray( 146 * array( 147 * 'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE 148 * ) 149 * ); 150 * </code> 151 * 152 * @param array $pStyles Array containing style information 153 * @throws PHPExcel_Exception 154 * @return PHPExcel_Style_NumberFormat 155 */ 156 public function applyFromArray($pStyles = null) 157 { 158 if (is_array($pStyles)) { 159 if ($this->isSupervisor) { 160 $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); 161 } else { 162 if (array_key_exists('code', $pStyles)) { 163 $this->setFormatCode($pStyles['code']); 164 } 165 } 166 } else { 167 throw new PHPExcel_Exception("Invalid style array passed."); 168 } 169 return $this; 170 } 171 172 /** 173 * Get Format Code 174 * 175 * @return string 176 */ 177 public function getFormatCode() 178 { 179 if ($this->isSupervisor) { 180 return $this->getSharedComponent()->getFormatCode(); 181 } 182 if ($this->builtInFormatCode !== false) { 183 return self::builtInFormatCode($this->builtInFormatCode); 184 } 185 return $this->formatCode; 186 } 187 188 /** 189 * Set Format Code 190 * 191 * @param string $pValue 192 * @return PHPExcel_Style_NumberFormat 193 */ 194 public function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL) 195 { 196 if ($pValue == '') { 197 $pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; 198 } 199 if ($this->isSupervisor) { 200 $styleArray = $this->getStyleArray(array('code' => $pValue)); 201 $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); 202 } else { 203 $this->formatCode = $pValue; 204 $this->builtInFormatCode = self::builtInFormatCodeIndex($pValue); 205 } 206 return $this; 207 } 208 209 /** 210 * Get Built-In Format Code 211 * 212 * @return int 213 */ 214 public function getBuiltInFormatCode() 215 { 216 if ($this->isSupervisor) { 217 return $this->getSharedComponent()->getBuiltInFormatCode(); 218 } 219 return $this->builtInFormatCode; 220 } 221 222 /** 223 * Set Built-In Format Code 224 * 225 * @param int $pValue 226 * @return PHPExcel_Style_NumberFormat 227 */ 228 public function setBuiltInFormatCode($pValue = 0) 229 { 230 231 if ($this->isSupervisor) { 232 $styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue))); 233 $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); 234 } else { 235 $this->builtInFormatCode = $pValue; 236 $this->formatCode = self::builtInFormatCode($pValue); 237 } 238 return $this; 239 } 240 241 /** 242 * Fill built-in format codes 243 */ 244 private static function fillBuiltInFormatCodes() 245 { 246 // [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance] 247 // 18.8.30. numFmt (Number Format) 248 // 249 // The ECMA standard defines built-in format IDs 250 // 14: "mm-dd-yy" 251 // 22: "m/d/yy h:mm" 252 // 37: "#,##0 ;(#,##0)" 253 // 38: "#,##0 ;[Red](#,##0)" 254 // 39: "#,##0.00;(#,##0.00)" 255 // 40: "#,##0.00;[Red](#,##0.00)" 256 // 47: "mmss.0" 257 // KOR fmt 55: "yyyy-mm-dd" 258 // Excel defines built-in format IDs 259 // 14: "m/d/yyyy" 260 // 22: "m/d/yyyy h:mm" 261 // 37: "#,##0_);(#,##0)" 262 // 38: "#,##0_);[Red](#,##0)" 263 // 39: "#,##0.00_);(#,##0.00)" 264 // 40: "#,##0.00_);[Red](#,##0.00)" 265 // 47: "mm:ss.0" 266 // KOR fmt 55: "yyyy/mm/dd" 267 268 // Built-in format codes 269 if (is_null(self::$builtInFormats)) { 270 self::$builtInFormats = array(); 271 272 // General 273 self::$builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; 274 self::$builtInFormats[1] = '0'; 275 self::$builtInFormats[2] = '0.00'; 276 self::$builtInFormats[3] = '#,##0'; 277 self::$builtInFormats[4] = '#,##0.00'; 278 279 self::$builtInFormats[9] = '0%'; 280 self::$builtInFormats[10] = '0.00%'; 281 self::$builtInFormats[11] = '0.00E+00'; 282 self::$builtInFormats[12] = '# ?/?'; 283 self::$builtInFormats[13] = '# ??/??'; 284 self::$builtInFormats[14] = 'm/d/yyyy'; // Despite ECMA 'mm-dd-yy'; 285 self::$builtInFormats[15] = 'd-mmm-yy'; 286 self::$builtInFormats[16] = 'd-mmm'; 287 self::$builtInFormats[17] = 'mmm-yy'; 288 self::$builtInFormats[18] = 'h:mm AM/PM'; 289 self::$builtInFormats[19] = 'h:mm:ss AM/PM'; 290 self::$builtInFormats[20] = 'h:mm'; 291 self::$builtInFormats[21] = 'h:mm:ss'; 292 self::$builtInFormats[22] = 'm/d/yyyy h:mm'; // Despite ECMA 'm/d/yy h:mm'; 293 294 self::$builtInFormats[37] = '#,##0_);(#,##0)'; // Despite ECMA '#,##0 ;(#,##0)'; 295 self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; // Despite ECMA '#,##0 ;[Red](#,##0)'; 296 self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; // Despite ECMA '#,##0.00;(#,##0.00)'; 297 self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; // Despite ECMA '#,##0.00;[Red](#,##0.00)'; 298 299 self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; 300 self::$builtInFormats[45] = 'mm:ss'; 301 self::$builtInFormats[46] = '[h]:mm:ss'; 302 self::$builtInFormats[47] = 'mm:ss.0'; // Despite ECMA 'mmss.0'; 303 self::$builtInFormats[48] = '##0.0E+0'; 304 self::$builtInFormats[49] = '@'; 305 306 // CHT 307 self::$builtInFormats[27] = '[$-404]e/m/d'; 308 self::$builtInFormats[30] = 'm/d/yy'; 309 self::$builtInFormats[36] = '[$-404]e/m/d'; 310 self::$builtInFormats[50] = '[$-404]e/m/d'; 311 self::$builtInFormats[57] = '[$-404]e/m/d'; 312 313 // THA 314 self::$builtInFormats[59] = 't0'; 315 self::$builtInFormats[60] = 't0.00'; 316 self::$builtInFormats[61] = 't#,##0'; 317 self::$builtInFormats[62] = 't#,##0.00'; 318 self::$builtInFormats[67] = 't0%'; 319 self::$builtInFormats[68] = 't0.00%'; 320 self::$builtInFormats[69] = 't# ?/?'; 321 self::$builtInFormats[70] = 't# ??/??'; 322 323 // Flip array (for faster lookups) 324 self::$flippedBuiltInFormats = array_flip(self::$builtInFormats); 325 } 326 } 327 328 /** 329 * Get built-in format code 330 * 331 * @param int $pIndex 332 * @return string 333 */ 334 public static function builtInFormatCode($pIndex) 335 { 336 // Clean parameter 337 $pIndex = intval($pIndex); 338 339 // Ensure built-in format codes are available 340 self::fillBuiltInFormatCodes(); 341 342 // Lookup format code 343 if (isset(self::$builtInFormats[$pIndex])) { 344 return self::$builtInFormats[$pIndex]; 345 } 346 347 return ''; 348 } 349 350 /** 351 * Get built-in format code index 352 * 353 * @param string $formatCode 354 * @return int|boolean 355 */ 356 public static function builtInFormatCodeIndex($formatCode) 357 { 358 // Ensure built-in format codes are available 359 self::fillBuiltInFormatCodes(); 360 361 // Lookup format code 362 if (isset(self::$flippedBuiltInFormats[$formatCode])) { 363 return self::$flippedBuiltInFormats[$formatCode]; 364 } 365 366 return false; 367 } 368 369 /** 370 * Get hash code 371 * 372 * @return string Hash code 373 */ 374 public function getHashCode() 375 { 376 if ($this->isSupervisor) { 377 return $this->getSharedComponent()->getHashCode(); 378 } 379 return md5( 380 $this->formatCode . 381 $this->builtInFormatCode . 382 __CLASS__ 383 ); 384 } 385 386 /** 387 * Search/replace values to convert Excel date/time format masks to PHP format masks 388 * 389 * @var array 390 */ 391 private static $dateFormatReplacements = array( 392 // first remove escapes related to non-format characters 393 '\\' => '', 394 // 12-hour suffix 395 'am/pm' => 'A', 396 // 4-digit year 397 'e' => 'Y', 398 'yyyy' => 'Y', 399 // 2-digit year 400 'yy' => 'y', 401 // first letter of month - no php equivalent 402 'mmmmm' => 'M', 403 // full month name 404 'mmmm' => 'F', 405 // short month name 406 'mmm' => 'M', 407 // mm is minutes if time, but can also be month w/leading zero 408 // so we try to identify times be the inclusion of a : separator in the mask 409 // It isn't perfect, but the best way I know how 410 ':mm' => ':i', 411 'mm:' => 'i:', 412 // month leading zero 413 'mm' => 'm', 414 // month no leading zero 415 'm' => 'n', 416 // full day of week name 417 'dddd' => 'l', 418 // short day of week name 419 'ddd' => 'D', 420 // days leading zero 421 'dd' => 'd', 422 // days no leading zero 423 'd' => 'j', 424 // seconds 425 'ss' => 's', 426 // fractional seconds - no php equivalent 427 '.s' => '' 428 ); 429 /** 430 * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock) 431 * 432 * @var array 433 */ 434 private static $dateFormatReplacements24 = array( 435 'hh' => 'H', 436 'h' => 'G' 437 ); 438 /** 439 * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock) 440 * 441 * @var array 442 */ 443 private static $dateFormatReplacements12 = array( 444 'hh' => 'h', 445 'h' => 'g' 446 ); 447 448 private static function setLowercaseCallback($matches) { 449 return mb_strtolower($matches[0]); 450 } 451 452 private static function escapeQuotesCallback($matches) { 453 return '\\' . implode('\\', str_split($matches[1])); 454 } 455 456 private static function formatAsDate(&$value, &$format) 457 { 458 // strip off first part containing e.g. [$-F800] or [$USD-409] 459 // general syntax: [$<Currency string>-<language info>] 460 // language info is in hexadecimal 461 $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format); 462 463 // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case; 464 // but we don't want to change any quoted strings 465 $format = preg_replace_callback('/(?:^|")([^"]*)(?:$|")/', array('self', 'setLowercaseCallback'), $format); 466 467 // Only process the non-quoted blocks for date format characters 468 $blocks = explode('"', $format); 469 foreach($blocks as $key => &$block) { 470 if ($key % 2 == 0) { 471 $block = strtr($block, self::$dateFormatReplacements); 472 if (!strpos($block, 'A')) { 473 // 24-hour time format 474 $block = strtr($block, self::$dateFormatReplacements24); 475 } else { 476 // 12-hour time format 477 $block = strtr($block, self::$dateFormatReplacements12); 478 } 479 } 480 } 481 $format = implode('"', $blocks); 482 483 // escape any quoted characters so that DateTime format() will render them correctly 484 $format = preg_replace_callback('/"(.*)"/U', array('self', 'escapeQuotesCallback'), $format); 485 486 $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value); 487 $value = $dateObj->format($format); 488 } 489 490 private static function formatAsPercentage(&$value, &$format) 491 { 492 if ($format === self::FORMAT_PERCENTAGE) { 493 $value = round((100 * $value), 0) . '%'; 494 } else { 495 if (preg_match('/\.[#0]+/i', $format, $m)) { 496 $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1); 497 $format = str_replace($m[0], $s, $format); 498 } 499 if (preg_match('/^[#0]+/', $format, $m)) { 500 $format = str_replace($m[0], strlen($m[0]), $format); 501 } 502 $format = '%' . str_replace('%', 'f%%', $format); 503 504 $value = sprintf($format, 100 * $value); 505 } 506 } 507 508 private static function formatAsFraction(&$value, &$format) 509 { 510 $sign = ($value < 0) ? '-' : ''; 511 512 $integerPart = floor(abs($value)); 513 $decimalPart = trim(fmod(abs($value), 1), '0.'); 514 $decimalLength = strlen($decimalPart); 515 $decimalDivisor = pow(10, $decimalLength); 516 517 $GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart, $decimalDivisor); 518 519 $adjustedDecimalPart = $decimalPart/$GCD; 520 $adjustedDecimalDivisor = $decimalDivisor/$GCD; 521 522 if ((strpos($format, '0') !== false) || (strpos($format, '#') !== false) || (substr($format, 0, 3) == '? ?')) { 523 if ($integerPart == 0) { 524 $integerPart = ''; 525 } 526 $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor"; 527 } else { 528 $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor; 529 $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor"; 530 } 531 } 532 533 private static function complexNumberFormatMask($number, $mask, $level = 0) 534 { 535 $sign = ($number < 0.0); 536 $number = abs($number); 537 if (strpos($mask, '.') !== false) { 538 $numbers = explode('.', $number . '.0'); 539 $masks = explode('.', $mask . '.0'); 540 $result1 = self::complexNumberFormatMask($numbers[0], $masks[0], 1); 541 $result2 = strrev(self::complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), 1)); 542 return (($sign) ? '-' : '') . $result1 . '.' . $result2; 543 } 544 545 $r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE); 546 if ($r > 1) { 547 $result = array_reverse($result[0]); 548 549 foreach ($result as $block) { 550 $divisor = 1 . $block[0]; 551 $size = strlen($block[0]); 552 $offset = $block[1]; 553 554 $blockValue = sprintf( 555 '%0' . $size . 'd', 556 fmod($number, $divisor) 557 ); 558 $number = floor($number / $divisor); 559 $mask = substr_replace($mask, $blockValue, $offset, $size); 560 } 561 if ($number > 0) { 562 $mask = substr_replace($mask, $number, $offset, 0); 563 } 564 $result = $mask; 565 } else { 566 $result = $number; 567 } 568 569 return (($sign) ? '-' : '') . $result; 570 } 571 572 /** 573 * Convert a value in a pre-defined format to a PHP string 574 * 575 * @param mixed $value Value to format 576 * @param string $format Format code 577 * @param array $callBack Callback function for additional formatting of string 578 * @return string Formatted string 579 */ 580 public static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null) 581 { 582 // For now we do not treat strings although section 4 of a format code affects strings 583 if (!is_numeric($value)) { 584 return $value; 585 } 586 587 // For 'General' format code, we just pass the value although this is not entirely the way Excel does it, 588 // it seems to round numbers to a total of 10 digits. 589 if (($format === PHPExcel_Style_NumberFormat::FORMAT_GENERAL) || ($format === PHPExcel_Style_NumberFormat::FORMAT_TEXT)) { 590 return $value; 591 } 592 593 // Convert any other escaped characters to quoted strings, e.g. (\T to "T") 594 $format = preg_replace('/(\\\(.))(?=(?:[^"]|"[^"]*")*$)/u', '"$2}"', $format); 595 596 // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal) 597 $sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format); 598 599 // Extract the relevant section depending on whether number is positive, negative, or zero? 600 // Text not supported yet. 601 // Here is how the sections apply to various values in Excel: 602 // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT] 603 // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE] 604 // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO] 605 // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT] 606 switch (count($sections)) { 607 case 1: 608 $format = $sections[0]; 609 break; 610 case 2: 611 $format = ($value >= 0) ? $sections[0] : $sections[1]; 612 $value = abs($value); // Use the absolute value 613 break; 614 case 3: 615 $format = ($value > 0) ? 616 $sections[0] : ( ($value < 0) ? 617 $sections[1] : $sections[2]); 618 $value = abs($value); // Use the absolute value 619 break; 620 case 4: 621 $format = ($value > 0) ? 622 $sections[0] : ( ($value < 0) ? 623 $sections[1] : $sections[2]); 624 $value = abs($value); // Use the absolute value 625 break; 626 default: 627 // something is wrong, just use first section 628 $format = $sections[0]; 629 break; 630 } 631 632 // In Excel formats, "_" is used to add spacing, 633 // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space 634 $format = preg_replace('/_./', ' ', $format); 635 636 // Save format with color information for later use below 637 $formatColor = $format; 638 639 // Strip color information 640 $color_regex = '/^\\[[a-zA-Z]+\\]/'; 641 $format = preg_replace($color_regex, '', $format); 642 643 // Let's begin inspecting the format and converting the value to a formatted string 644 645 // Check for date/time characters (not inside quotes) 646 if (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format, $matches)) { 647 // datetime format 648 self::formatAsDate($value, $format); 649 } elseif (preg_match('/%$/', $format)) { 650 // % number format 651 self::formatAsPercentage($value, $format); 652 } else { 653 if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) { 654 $value = 'EUR ' . sprintf('%1.2f', $value); 655 } else { 656 // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols 657 $format = str_replace(array('"', '*'), '', $format); 658 659 // Find out if we need thousands separator 660 // This is indicated by a comma enclosed by a digit placeholder: 661 // #,# or 0,0 662 $useThousands = preg_match('/(#,#|0,0)/', $format); 663 if ($useThousands) { 664 $format = preg_replace('/0,0/', '00', $format); 665 $format = preg_replace('/#,#/', '##', $format); 666 } 667 668 // Scale thousands, millions,... 669 // This is indicated by a number of commas after a digit placeholder: 670 // #, or 0.0,, 671 $scale = 1; // same as no scale 672 $matches = array(); 673 if (preg_match('/(#|0)(,+)/', $format, $matches)) { 674 $scale = pow(1000, strlen($matches[2])); 675 676 // strip the commas 677 $format = preg_replace('/0,+/', '0', $format); 678 $format = preg_replace('/#,+/', '#', $format); 679 } 680 681 if (preg_match('/#?.*\?\/\?/', $format, $m)) { 682 //echo 'Format mask is fractional '.$format.' <br />'; 683 if ($value != (int)$value) { 684 self::formatAsFraction($value, $format); 685 } 686 687 } else { 688 // Handle the number itself 689 690 // scale number 691 $value = $value / $scale; 692 693 // Strip # 694 $format = preg_replace('/\\#/', '0', $format); 695 696 $n = "/\[[^\]]+\]/"; 697 $m = preg_replace($n, '', $format); 698 $number_regex = "/(0+)(\.?)(0*)/"; 699 if (preg_match($number_regex, $m, $matches)) { 700 $left = $matches[1]; 701 $dec = $matches[2]; 702 $right = $matches[3]; 703 704 // minimun width of formatted number (including dot) 705 $minWidth = strlen($left) + strlen($dec) + strlen($right); 706 if ($useThousands) { 707 $value = number_format( 708 $value, 709 strlen($right), 710 PHPExcel_Shared_String::getDecimalSeparator(), 711 PHPExcel_Shared_String::getThousandsSeparator() 712 ); 713 $value = preg_replace($number_regex, $value, $format); 714 } else { 715 if (preg_match('/[0#]E[+-]0/i', $format)) { 716 // Scientific format 717 $value = sprintf('%5.2E', $value); 718 } elseif (preg_match('/0([^\d\.]+)0/', $format)) { 719 $value = self::complexNumberFormatMask($value, $format); 720 } else { 721 $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; 722 $value = sprintf($sprintf_pattern, $value); 723 $value = preg_replace($number_regex, $value, $format); 724 } 725 } 726 } 727 } 728 if (preg_match('/\[\$(.*)\]/u', $format, $m)) { 729 // Currency or Accounting 730 $currencyFormat = $m[0]; 731 $currencyCode = $m[1]; 732 list($currencyCode) = explode('-', $currencyCode); 733 if ($currencyCode == '') { 734 $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); 735 } 736 $value = preg_replace('/\[\$([^\]]*)\]/u', $currencyCode, $value); 737 } 738 } 739 } 740 741 // Escape any escaped slashes to a single slash 742 $format = preg_replace("/\\\\/u", '\\', $format); 743 744 // Additional formatting provided by callback function 745 if ($callBack !== null) { 746 list($writerInstance, $function) = $callBack; 747 $value = $writerInstance->$function($value, $formatColor); 748 } 749 750 return $value; 751 } 752 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |