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