PHPExcel_Style
[ class tree: PHPExcel_Style ] [ index: PHPExcel_Style ] [ all elements ]

Source for file NumberFormat.php

Documentation is available at NumberFormat.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2010 PHPExcel
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  20.  *
  21.  * @category   PHPExcel
  22.  * @package    PHPExcel_Style
  23.  * @copyright  Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.7.3c, 2010-06-01
  26.  */
  27.  
  28.  
  29. /**
  30.  * PHPExcel_Style_NumberFormat
  31.  *
  32.  * @category   PHPExcel
  33.  * @package    PHPExcel_Style
  34.  * @copyright  Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  35.  */
  36. class PHPExcel_Style_NumberFormat implements PHPExcel_IComparable
  37. {
  38.     /* Pre-defined formats */
  39.     const FORMAT_GENERAL                    'General';
  40.  
  41.     const FORMAT_TEXT                        '@';
  42.  
  43.     const FORMAT_NUMBER                        '0';
  44.     const FORMAT_NUMBER_00                    '0.00';
  45.     const FORMAT_NUMBER_COMMA_SEPARATED1    '#,##0.00';
  46.     const FORMAT_NUMBER_COMMA_SEPARATED2    '#,##0.00_-';
  47.  
  48.     const FORMAT_PERCENTAGE                    '0%';
  49.     const FORMAT_PERCENTAGE_00                '0.00%';
  50.  
  51.     const FORMAT_DATE_YYYYMMDD2                'yyyy-mm-dd';
  52.     const FORMAT_DATE_YYYYMMDD                'yy-mm-dd';
  53.     const FORMAT_DATE_DDMMYYYY                'dd/mm/yy';
  54.     const FORMAT_DATE_DMYSLASH                'd/m/y';
  55.     const FORMAT_DATE_DMYMINUS                'd-m-y';
  56.     const FORMAT_DATE_DMMINUS                'd-m';
  57.     const FORMAT_DATE_MYMINUS                'm-y';
  58.     const FORMAT_DATE_XLSX14                'mm-dd-yy';
  59.     const FORMAT_DATE_XLSX15                'd-mmm-yy';
  60.     const FORMAT_DATE_XLSX16                'd-mmm';
  61.     const FORMAT_DATE_XLSX17                'mmm-yy';
  62.     const FORMAT_DATE_XLSX22                'm/d/yy h:mm';
  63.     const FORMAT_DATE_DATETIME                'd/m/y h:mm';
  64.     const FORMAT_DATE_TIME1                    'h:mm AM/PM';
  65.     const FORMAT_DATE_TIME2                    'h:mm:ss AM/PM';
  66.     const FORMAT_DATE_TIME3                    'h:mm';
  67.     const FORMAT_DATE_TIME4                    'h:mm:ss';
  68.     const FORMAT_DATE_TIME5                    'mm:ss';
  69.     const FORMAT_DATE_TIME6                    'h:mm:ss';
  70.     const FORMAT_DATE_TIME7                    'i:s.S';
  71.     const FORMAT_DATE_TIME8                    'h:mm:ss;@';
  72.     const FORMAT_DATE_YYYYMMDDSLASH            'yy/mm/dd;@';
  73.  
  74.     const FORMAT_CURRENCY_USD_SIMPLE        '"$"#,##0.00_-';
  75.     const FORMAT_CURRENCY_USD                '$#,##0_-';
  76.     const FORMAT_CURRENCY_EUR_SIMPLE        '[$EUR ]#,##0.00_-';
  77.  
  78.     /**
  79.      * Excel built-in number formats
  80.      *
  81.      * @var array 
  82.      */
  83.     private static $_builtInFormats;
  84.  
  85.     /**
  86.      * Excel built-in number formats (flipped, for faster lookups)
  87.      *
  88.      * @var array 
  89.      */
  90.     private static $_flippedBuiltInFormats;
  91.  
  92.     /**
  93.      * Format Code
  94.      *
  95.      * @var string 
  96.      */
  97.     private $_formatCode;
  98.  
  99.     /**
  100.      * Built-in format Code
  101.      *
  102.      * @var string 
  103.      */
  104.     private $_builtInFormatCode;
  105.  
  106.     /**
  107.      * Parent Borders
  108.      *
  109.      * @var _parentPropertyName string
  110.      */
  111.     private $_parentPropertyName;
  112.  
  113.     /**
  114.      * Supervisor?
  115.      *
  116.      * @var boolean 
  117.      */
  118.     private $_isSupervisor;
  119.  
  120.     /**
  121.      * Parent. Only used for supervisor
  122.      *
  123.      * @var PHPExcel_Style 
  124.      */
  125.     private $_parent;
  126.  
  127.     /**
  128.      * Create a new PHPExcel_Style_NumberFormat
  129.      */
  130.     public function __construct($isSupervisor false)
  131.     {
  132.         // Supervisor?
  133.         $this->_isSupervisor $isSupervisor;
  134.  
  135.         // Initialise values
  136.         $this->_formatCode            PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
  137.         $this->_builtInFormatCode    0;
  138.     }
  139.  
  140.     /**
  141.      * Bind parent. Only used for supervisor
  142.      *
  143.      * @param PHPExcel_Style $parent 
  144.      * @return PHPExcel_Style_NumberFormat 
  145.      */
  146.     public function bindParent($parent)
  147.     {
  148.         $this->_parent $parent;
  149.     }
  150.  
  151.     /**
  152.      * Is this a supervisor or a real style component?
  153.      *
  154.      * @return boolean 
  155.      */
  156.     public function getIsSupervisor()
  157.     {
  158.         return $this->_isSupervisor;
  159.     }
  160.  
  161.     /**
  162.      * Get the shared style component for the currently active cell in currently active sheet.
  163.      * Only used for style supervisor
  164.      *
  165.      * @return PHPExcel_Style_NumberFormat 
  166.      */
  167.     public function getSharedComponent()
  168.     {
  169.         return $this->_parent->getSharedComponent()->getNumberFormat();
  170.     }
  171.  
  172.     /**
  173.      * Get the currently active sheet. Only used for supervisor
  174.      *
  175.      * @return PHPExcel_Worksheet 
  176.      */
  177.     public function getActiveSheet()
  178.     {
  179.         return $this->_parent->getActiveSheet();
  180.     }
  181.  
  182.     /**
  183.      * Get the currently active cell coordinate in currently active sheet.
  184.      * Only used for supervisor
  185.      *
  186.      * @return string E.g. 'A1'
  187.      */
  188.     public function getSelectedCells()
  189.     {
  190.         return $this->getActiveSheet()->getSelectedCells();
  191.     }
  192.  
  193.     /**
  194.      * Get the currently active cell coordinate in currently active sheet.
  195.      * Only used for supervisor
  196.      *
  197.      * @return string E.g. 'A1'
  198.      */
  199.     public function getActiveCell()
  200.     {
  201.         return $this->getActiveSheet()->getActiveCell();
  202.     }
  203.  
  204.     /**
  205.      * Build style array from subcomponents
  206.      *
  207.      * @param array $array 
  208.      * @return array 
  209.      */
  210.     public function getStyleArray($array)
  211.     {
  212.         return array('numberformat' => $array);
  213.     }
  214.  
  215.     /**
  216.      * Apply styles from array
  217.      *
  218.      * <code>
  219.      * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(
  220.      *         array(
  221.      *             'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE
  222.      *         )
  223.      * );
  224.      * </code>
  225.      *
  226.      * @param    array    $pStyles    Array containing style information
  227.      * @throws    Exception
  228.      * @return PHPExcel_Style_NumberFormat 
  229.      */
  230.     public function applyFromArray($pStyles null)
  231.     {
  232.         if (is_array($pStyles)) {
  233.             if ($this->_isSupervisor{
  234.                 $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
  235.             else {
  236.                 if (array_key_exists('code'$pStyles)) {
  237.                     $this->setFormatCode($pStyles['code']);
  238.                 }
  239.             }
  240.         else {
  241.             throw new Exception("Invalid style array passed.");
  242.         }
  243.         return $this;
  244.     }
  245.  
  246.     /**
  247.      * Get Format Code
  248.      *
  249.      * @return string 
  250.      */
  251.     public function getFormatCode()
  252.     {
  253.         if ($this->_isSupervisor{
  254.             return $this->getSharedComponent()->getFormatCode();
  255.         }
  256.         if ($this->_builtInFormatCode !== false)
  257.         {
  258.             return self::builtInFormatCode($this->_builtInFormatCode);
  259.         }
  260.         return $this->_formatCode;
  261.     }
  262.  
  263.     /**
  264.      * Set Format Code
  265.      *
  266.      * @param string $pValue 
  267.      * @return PHPExcel_Style_NumberFormat 
  268.      */
  269.     public function setFormatCode($pValue PHPExcel_Style_NumberFormat::FORMAT_GENERAL)
  270.     {
  271.         if ($pValue == ''{
  272.             $pValue PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
  273.         }
  274.         if ($this->_isSupervisor{
  275.             $styleArray $this->getStyleArray(array('code' => $pValue));
  276.             $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
  277.         else {
  278.             $this->_formatCode $pValue;
  279.             $this->_builtInFormatCode self::builtInFormatCodeIndex($pValue);
  280.         }
  281.         return $this;
  282.     }
  283.  
  284.     /**
  285.      * Get Built-In Format Code
  286.      *
  287.      * @return int 
  288.      */
  289.     public function getBuiltInFormatCode()
  290.     {
  291.         if ($this->_isSupervisor{
  292.             return $this->getSharedComponent()->getBuiltInFormatCode();
  293.         }
  294.         return $this->_builtInFormatCode;
  295.     }
  296.  
  297.     /**
  298.      * Set Built-In Format Code
  299.      *
  300.      * @param int $pValue 
  301.      * @return PHPExcel_Style_NumberFormat 
  302.      */
  303.     public function setBuiltInFormatCode($pValue 0)
  304.     {
  305.  
  306.         if ($this->_isSupervisor{
  307.             $styleArray $this->getStyleArray(array('code' => self::builtInFormatCode($pValue)));
  308.             $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
  309.         else {
  310.             $this->_builtInFormatCode $pValue;
  311.             $this->_formatCode self::builtInFormatCode($pValue);
  312.         }
  313.         return $this;
  314.     }
  315.  
  316.     /**
  317.      * Fill built-in format codes
  318.      */
  319.     private static function fillBuiltInFormatCodes()
  320.     {
  321.         // Built-in format codes
  322.         if (is_null(self::$_builtInFormats)) {
  323.             self::$_builtInFormats array();
  324.  
  325.             // General
  326.             self::$_builtInFormats[0'General';
  327.             self::$_builtInFormats[1'0';
  328.             self::$_builtInFormats[2'0.00';
  329.             self::$_builtInFormats[3'#,##0';
  330.             self::$_builtInFormats[4'#,##0.00';
  331.  
  332.             self::$_builtInFormats[9'0%';
  333.             self::$_builtInFormats[10'0.00%';
  334.             self::$_builtInFormats[11'0.00E+00';
  335.             self::$_builtInFormats[12'# ?/?';
  336.             self::$_builtInFormats[13'# ??/??';
  337.             self::$_builtInFormats[14'mm-dd-yy';
  338.             self::$_builtInFormats[15'd-mmm-yy';
  339.             self::$_builtInFormats[16'd-mmm';
  340.             self::$_builtInFormats[17'mmm-yy';
  341.             self::$_builtInFormats[18'h:mm AM/PM';
  342.             self::$_builtInFormats[19'h:mm:ss AM/PM';
  343.             self::$_builtInFormats[20'h:mm';
  344.             self::$_builtInFormats[21'h:mm:ss';
  345.             self::$_builtInFormats[22'm/d/yy h:mm';
  346.  
  347.             self::$_builtInFormats[37'#,##0 ;(#,##0)';
  348.             self::$_builtInFormats[38'#,##0 ;[Red](#,##0)';
  349.             self::$_builtInFormats[39'#,##0.00;(#,##0.00)';
  350.             self::$_builtInFormats[40'#,##0.00;[Red](#,##0.00)';
  351.  
  352.             self::$_builtInFormats[44'_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
  353.             self::$_builtInFormats[45'mm:ss';
  354.             self::$_builtInFormats[46'[h]:mm:ss';
  355.             self::$_builtInFormats[47'mmss.0';
  356.             self::$_builtInFormats[48'##0.0E+0';
  357.             self::$_builtInFormats[49'@';
  358.  
  359.             // CHT
  360.             self::$_builtInFormats[27'[$-404]e/m/d';
  361.             self::$_builtInFormats[30'm/d/yy';
  362.             self::$_builtInFormats[36'[$-404]e/m/d';
  363.             self::$_builtInFormats[50'[$-404]e/m/d';
  364.             self::$_builtInFormats[57'[$-404]e/m/d';
  365.  
  366.             // THA
  367.             self::$_builtInFormats[59't0';
  368.             self::$_builtInFormats[60't0.00';
  369.             self::$_builtInFormats[61't#,##0';
  370.             self::$_builtInFormats[62't#,##0.00';
  371.             self::$_builtInFormats[67't0%';
  372.             self::$_builtInFormats[68't0.00%';
  373.             self::$_builtInFormats[69't# ?/?';
  374.             self::$_builtInFormats[70't# ??/??';
  375.  
  376.             // Flip array (for faster lookups)
  377.             self::$_flippedBuiltInFormats array_flip(self::$_builtInFormats);
  378.         }
  379.     }
  380.  
  381.     /**
  382.      * Get built-in format code
  383.      *
  384.      * @param    int        $pIndex 
  385.      * @return    string 
  386.      */
  387.     public static function builtInFormatCode($pIndex)
  388.     {
  389.         // Clean parameter
  390.         $pIndex intval($pIndex);
  391.  
  392.         // Ensure built-in format codes are available
  393.         self::fillBuiltInFormatCodes();
  394.  
  395.         // Lookup format code
  396.         if (array_key_exists($pIndexself::$_builtInFormats)) {
  397.             return self::$_builtInFormats[$pIndex];
  398.         }
  399.  
  400.         return '';
  401.     }
  402.  
  403.     /**
  404.      * Get built-in format code index
  405.      *
  406.      * @param    string        $formatCode 
  407.      * @return    int|boolean
  408.      */
  409.     public static function builtInFormatCodeIndex($formatCode)
  410.     {
  411.         // Ensure built-in format codes are available
  412.         self::fillBuiltInFormatCodes();
  413.  
  414.         // Lookup format code
  415.         if (array_key_exists($formatCodeself::$_flippedBuiltInFormats)) {
  416.             return self::$_flippedBuiltInFormats[$formatCode];
  417.         }
  418.  
  419.         return false;
  420.     }
  421.  
  422.     /**
  423.      * Get hash code
  424.      *
  425.      * @return string    Hash code
  426.      */
  427.     public function getHashCode()
  428.     {
  429.         if ($this->_isSupervisor{
  430.             return $this->getSharedComponent()->getHashCode();
  431.         }
  432.         return md5(
  433.               $this->_formatCode
  434.             . $this->_builtInFormatCode
  435.             . __CLASS__
  436.         );
  437.     }
  438.  
  439.     /**
  440.      * Implement PHP __clone to create a deep clone, not just a shallow copy.
  441.      */
  442.     public function __clone()
  443.     {
  444.         $vars get_object_vars($this);
  445.         foreach ($vars as $key => $value{
  446.             if (is_object($value)) {
  447.                 $this->$key clone $value;
  448.             else {
  449.                 $this->$key $value;
  450.             }
  451.         }
  452.     }
  453.  
  454.     private static $_dateFormatReplacements array(
  455.             // first remove escapes related to non-format characters
  456.             '\\'    => '',
  457.             //    12-hour suffix
  458.             'am/pm'    => 'A',
  459.             //    4-digit year
  460.             'yyyy'    => 'Y',
  461.             //    2-digit year
  462.             'yy'    => 'y',
  463.             //    first letter of month - no php equivalent
  464.             'mmmmm'    => 'M',
  465.             //    full month name
  466.             'mmmm'    => 'F',
  467.             //    short month name
  468.             'mmm'    => 'M',
  469.             //    mm is minutes if time or month w/leading zero
  470.             ':mm'    => ':i',
  471.             //    month leading zero
  472.             'mm'    => 'm',
  473.             //    month no leading zero
  474.             'm'        => 'n',
  475.             //    full day of week name
  476.             'dddd'    => 'l',
  477.             //    short day of week name
  478.             'ddd'    => 'D',
  479.             //    days leading zero
  480.             'dd'    => 'd',
  481.             //    days no leading zero
  482.             'd'        => 'j',
  483.             //    seconds
  484.             'ss'    => 's',
  485.             //    fractional seconds - no php equivalent
  486.             '.s'    => ''
  487.         );
  488.     private static $_dateFormatReplacements24 array(
  489.             'hh'    => 'H',
  490.             'h'        => 'G'
  491.         );
  492.     private static $_dateFormatReplacements12 array(
  493.             'hh'    => 'h',
  494.             'h'        => 'g'
  495.         );
  496.  
  497.     /**
  498.      * Convert a value in a pre-defined format to a PHP string
  499.      *
  500.      * @param mixed     $value        Value to format
  501.      * @param string     $format        Format code
  502.      * @param array        $callBack    Callback function for additional formatting of string
  503.      * @return string    Formatted string
  504.      */
  505.     public static function toFormattedString($value ''$format ''$callBack null)
  506.     {
  507.         // For now we do not treat strings although section 4 of a format code affects strings
  508.         if (!is_numeric($value)) return $value;
  509.  
  510.         // For 'General' format code, we just pass the value although this is not entirely the way Excel does it,
  511.         // it seems to round numbers to a total of 10 digits.
  512.         if ($format === 'General'{
  513.             return $value;
  514.         }
  515.  
  516.         // Get the sections, there can be up to four sections
  517.         $sections explode(';'$format);
  518.  
  519.         // Fetch the relevant section depending on whether number is positive, negative, or zero?
  520.         // Text not supported yet.
  521.         // Here is how the sections apply to various values in Excel:
  522.         //   1 section:   [POSITIVE/NEGATIVE/ZERO/TEXT]
  523.         //   2 sections:  [POSITIVE/ZERO/TEXT] [NEGATIVE]
  524.         //   3 sections:  [POSITIVE/TEXT] [NEGATIVE] [ZERO]
  525.         //   4 sections:  [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
  526.         switch (count($sections)) {
  527.             case 1:
  528.                 $format $sections[0];
  529.                 break;
  530.  
  531.             case 2:
  532.                 $format ($value >= 0$sections[0$sections[1];
  533.                 $value abs($value)// Use the absolute value
  534.                 break;
  535.  
  536.             case 3:
  537.                 $format ($value 0?
  538.                     $sections[0( ($value 0?
  539.                         $sections[1$sections[2]);
  540.                 $value abs($value)// Use the absolute value
  541.                 break;
  542.  
  543.             case 4:
  544.                 $format ($value 0?
  545.                     $sections[0( ($value 0?
  546.                         $sections[1$sections[2]);
  547.                 $value abs($value)// Use the absolute value
  548.                 break;
  549.  
  550.             default:
  551.                 // something is wrong, just use first section
  552.                 $format $sections[0];
  553.                 break;
  554.         }
  555.  
  556.         // Save format with color information for later use below
  557.         $formatColor $format;
  558.  
  559.         // Strip color information
  560.         $color_regex '/^\\[[a-zA-Z]+\\]/';
  561.         $format preg_replace($color_regex''$format);
  562.  
  563.         // Let's begin inspecting the format and converting the value to a formatted string
  564.         if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i'$format)) // datetime format
  565.             // dvc: convert Excel formats to PHP date formats
  566.  
  567.             // strip off first part containing e.g. [$-F800] or [$USD-409]
  568.             // general syntax: [$<Currency string>-<language info>]
  569.             // language info is in hexadecimal
  570.             $format preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i'''$format);
  571.  
  572.             // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case
  573.             $format strtolower($format);
  574.  
  575.             $format strtr($format,self::$_dateFormatReplacements);
  576.             if (!strpos($format,'A')) {    // 24-hour time format
  577.                 $format strtr($format,self::$_dateFormatReplacements24);
  578.             else {                    // 12-hour time format
  579.                 $format strtr($format,self::$_dateFormatReplacements12);
  580.             }
  581.  
  582.             $dateObj PHPExcel_Shared_Date::ExcelToPHPObject($value);
  583.             $value $dateObj->format($format);
  584.  
  585.         else if (preg_match('/%$/'$format)) // % number format
  586.             if ($format === self::FORMAT_PERCENTAGE{
  587.                 $value round( (100 $value)0'%';
  588.             else {
  589.                 if (preg_match('/\.[#0]+/i'$format$m)) {
  590.                     $s substr($m[0]01(strlen($m[0]1);
  591.                     $format str_replace($m[0]$s$format);
  592.                 }
  593.                 if (preg_match('/^[#0]+/'$format$m)) {
  594.                     $format str_replace($m[0]strlen($m[0])$format);
  595.                 }
  596.                 $format '%' str_replace('%''f%%'$format);
  597.  
  598.                 $value sprintf($format100 $value);
  599.             }
  600.  
  601.         else {
  602.             if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE{
  603.                 $value 'EUR ' sprintf('%1.2f'$value);
  604.  
  605.             else {
  606.                 // In Excel formats, "_" is used to add spacing, which we can't do in HTML
  607.                 $format preg_replace('/_./'''$format);
  608.  
  609.                 // Some non-number characters are escaped with \, which we don't need
  610.                 $format preg_replace("/\\\\/"''$format);
  611.  
  612.                 // Some non-number strings are quoted, so we'll get rid of the quotes
  613.                 $format preg_replace('/"/'''$format);
  614.  
  615.                 // Find out if we need thousands separator
  616.                 // This is indicated by a comma enclosed by a digit placeholder:
  617.                 //        #,#   or   0,0
  618.                 $useThousands preg_match('/(#,#|0,0)/'$format);
  619.                 if ($useThousands{
  620.                     $format preg_replace('/0,0/''00'$format);
  621.                     $format preg_replace('/#,#/''##'$format);
  622.                 }
  623.  
  624.                 // Scale thousands, millions,...
  625.                 // This is indicated by a number of commas after a digit placeholder:
  626.                 //        #,   or    0.0,,
  627.                 $scale 1// same as no scale
  628.                 $matches array();
  629.                 if (preg_match('/(#|0)(,+)/'$format$matches)) {
  630.                     $scale pow(1000strlen($matches[2]));
  631.  
  632.                     // strip the commas
  633.                     $format preg_replace('/0,+/''0'$format);
  634.                     $format preg_replace('/#,+/''#'$format);
  635.                 }
  636.  
  637.                 if (preg_match('/#?.*\?\/\?/'$format$m)) {
  638.                     //echo 'Format mask is fractional '.$format.' <br />';
  639.                     if ($value != (int)$value{
  640.                         $sign ($value 0'-' '';
  641.  
  642.                         $integerPart floor(abs($value));
  643.                         $decimalPart trim(fmod(abs($value),1),'0.');
  644.                         $decimalLength strlen($decimalPart);
  645.                         $decimalDivisor pow(10,$decimalLength);
  646.  
  647.                         $GCD PHPExcel_Calculation_Functions::GCD($decimalPart,$decimalDivisor);
  648.  
  649.                         $adjustedDecimalPart $decimalPart/$GCD;
  650.                         $adjustedDecimalDivisor $decimalDivisor/$GCD;
  651.  
  652.                         if ((strpos($format,'0'!== false|| (substr($format,0,3== '? ?')) {
  653.                             if ($integerPart == 0$integerPart ''}
  654.                             $value "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
  655.                         else {
  656.                             $adjustedDecimalPart += $integerPart $adjustedDecimalDivisor;
  657.                             $value "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
  658.                         }
  659.                     }
  660.  
  661.                 else {
  662.                     // Handle the number itself
  663.  
  664.                     // scale number
  665.                     $value $value $scale;
  666.  
  667.                     // Strip #
  668.                     $format preg_replace('/\\#/'''$format);
  669.  
  670.                     $number_regex "/(0+)(\.?)(0*)/";
  671.                     $matches array();
  672.                     if (preg_match($number_regex$format$matches)) {
  673.                         $left $matches[1];
  674.                         $dec $matches[2];
  675.                         $right $matches[3];
  676.  
  677.                         // minimun width of formatted number (including dot)
  678.                         $minWidth strlen($leftstrlen($decstrlen($right);
  679.  
  680.                         if ($useThousands{
  681.                             $value number_format(
  682.                                 $value
  683.                                 strlen($right)
  684.                                 PHPExcel_Shared_String::getDecimalSeparator()
  685.                                 PHPExcel_Shared_String::getThousandsSeparator()
  686.                             );
  687.  
  688.                         else {
  689.                             $sprintf_pattern "%0$minWidth.strlen($right"f";
  690.                             $value sprintf($sprintf_pattern$value);
  691.                         }
  692.  
  693.                         $value preg_replace($number_regex$value$format);
  694.                     }
  695.                 }
  696.             }
  697.         }
  698.  
  699.         // Additional formatting provided by callback function
  700.         if ($callBack !== null{
  701.             list($writerInstance$function$callBack;
  702.             $value $writerInstance->$function($value$formatColor);
  703.         }
  704.  
  705.         return $value;
  706.     }
  707.  
  708. }

Documentation generated on Tue, 01 Jun 2010 17:05:19 +0200 by phpDocumentor 1.4.3