5 * Copyright (c) 2006 - 2014 PHPExcel
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.
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.
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
22 * @package PHPExcel_Calculation
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##
29 /** PHPExcel root directory */
30 if (!defined('PHPEXCEL_ROOT')) {
34 define('PHPEXCEL_ROOT', dirname(__FILE__
) . '/../../');
35 require(PHPEXCEL_ROOT
. 'PHPExcel/Autoloader.php');
40 * PHPExcel_Calculation_TextData
43 * @package PHPExcel_Calculation
44 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
46 class PHPExcel_Calculation_TextData
{
48 private static $_invalidChars = Null;
50 private static function _uniord($c) {
51 if (ord($c{0}) >=0 && ord($c{0}) <= 127)
53 if (ord($c{0}) >= 192 && ord($c{0}) <= 223)
54 return (ord($c{0})-192)*64 +
(ord($c{1})-128);
55 if (ord($c{0}) >= 224 && ord($c{0}) <= 239)
56 return (ord($c{0})-224)*4096 +
(ord($c{1})-128)*64 +
(ord($c{2})-128);
57 if (ord($c{0}) >= 240 && ord($c{0}) <= 247)
58 return (ord($c{0})-240)*262144 +
(ord($c{1})-128)*4096 +
(ord($c{2})-128)*64 +
(ord($c{3})-128);
59 if (ord($c{0}) >= 248 && ord($c{0}) <= 251)
60 return (ord($c{0})-248)*16777216 +
(ord($c{1})-128)*262144 +
(ord($c{2})-128)*4096 +
(ord($c{3})-128)*64 +
(ord($c{4})-128);
61 if (ord($c{0}) >= 252 && ord($c{0}) <= 253)
62 return (ord($c{0})-252)*1073741824 +
(ord($c{1})-128)*16777216 +
(ord($c{2})-128)*262144 +
(ord($c{3})-128)*4096 +
(ord($c{4})-128)*64 +
(ord($c{5})-128);
63 if (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error
64 return PHPExcel_Calculation_Functions
::VALUE();
66 } // function _uniord()
71 * @param string $character Value
74 public static function CHARACTER($character) {
75 $character = PHPExcel_Calculation_Functions
::flattenSingleValue($character);
77 if ((!is_numeric($character)) ||
($character < 0)) {
78 return PHPExcel_Calculation_Functions
::VALUE();
81 if (function_exists('mb_convert_encoding')) {
82 return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES');
84 return chr(intval($character));
92 * @param mixed $stringValue Value to check
95 public static function TRIMNONPRINTABLE($stringValue = '') {
96 $stringValue = PHPExcel_Calculation_Functions
::flattenSingleValue($stringValue);
98 if (is_bool($stringValue)) {
99 return ($stringValue) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
102 if (self
::$_invalidChars == Null) {
103 self
::$_invalidChars = range(chr(0),chr(31));
106 if (is_string($stringValue) ||
is_numeric($stringValue)) {
107 return str_replace(self
::$_invalidChars, '', trim($stringValue, "\x00..\x1F"));
110 } // function TRIMNONPRINTABLE()
116 * @param mixed $stringValue Value to check
119 public static function TRIMSPACES($stringValue = '') {
120 $stringValue = PHPExcel_Calculation_Functions
::flattenSingleValue($stringValue);
121 if (is_bool($stringValue)) {
122 return ($stringValue) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
125 if (is_string($stringValue) ||
is_numeric($stringValue)) {
126 return trim(preg_replace('/ +/',' ',trim($stringValue, ' ')), ' ');
129 } // function TRIMSPACES()
135 * @param string $characters Value
138 public static function ASCIICODE($characters) {
139 if (($characters === NULL) ||
($characters === ''))
140 return PHPExcel_Calculation_Functions
::VALUE();
141 $characters = PHPExcel_Calculation_Functions
::flattenSingleValue($characters);
142 if (is_bool($characters)) {
143 if (PHPExcel_Calculation_Functions
::getCompatibilityMode() == PHPExcel_Calculation_Functions
::COMPATIBILITY_OPENOFFICE
) {
144 $characters = (int) $characters;
146 $characters = ($characters) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
150 $character = $characters;
151 if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) {
152 if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); }
153 return self
::_uniord($character);
155 if (strlen($characters) > 0) { $character = substr($characters, 0, 1); }
156 return ord($character);
158 } // function ASCIICODE()
166 public static function CONCATENATE() {
170 // Loop through arguments
171 $aArgs = PHPExcel_Calculation_Functions
::flattenArray(func_get_args());
172 foreach ($aArgs as $arg) {
174 if (PHPExcel_Calculation_Functions
::getCompatibilityMode() == PHPExcel_Calculation_Functions
::COMPATIBILITY_OPENOFFICE
) {
177 $arg = ($arg) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
180 $returnValue .= $arg;
185 } // function CONCATENATE()
191 * This function converts a number to text using currency format, with the decimals rounded to the specified place.
192 * The format used is $#,##0.00_);($#,##0.00)..
194 * @param float $value The value to format
195 * @param int $decimals The number of digits to display to the right of the decimal point.
196 * If decimals is negative, number is rounded to the left of the decimal point.
197 * If you omit decimals, it is assumed to be 2
200 public static function DOLLAR($value = 0, $decimals = 2) {
201 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
202 $decimals = is_null($decimals) ?
0 : PHPExcel_Calculation_Functions
::flattenSingleValue($decimals);
204 // Validate parameters
205 if (!is_numeric($value) ||
!is_numeric($decimals)) {
206 return PHPExcel_Calculation_Functions
::NaN();
208 $decimals = floor($decimals);
212 $mask .= '.' . str_repeat('0',$decimals);
214 $round = pow(10,abs($decimals));
215 if ($value < 0) { $round = 0-$round; }
216 $value = PHPExcel_Calculation_MathTrig
::MROUND($value, $round);
219 return PHPExcel_Style_NumberFormat
::toFormattedString($value, $mask);
221 } // function DOLLAR()
227 * @param string $needle The string to look for
228 * @param string $haystack The string in which to look
229 * @param int $offset Offset within $haystack
232 public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) {
233 $needle = PHPExcel_Calculation_Functions
::flattenSingleValue($needle);
234 $haystack = PHPExcel_Calculation_Functions
::flattenSingleValue($haystack);
235 $offset = PHPExcel_Calculation_Functions
::flattenSingleValue($offset);
237 if (!is_bool($needle)) {
238 if (is_bool($haystack)) {
239 $haystack = ($haystack) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
242 if (($offset > 0) && (PHPExcel_Shared_String
::CountCharacters($haystack) > $offset)) {
243 if (PHPExcel_Shared_String
::CountCharacters($needle) == 0) {
246 if (function_exists('mb_strpos')) {
247 $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
249 $pos = strpos($haystack, $needle, --$offset);
251 if ($pos !== false) {
256 return PHPExcel_Calculation_Functions
::VALUE();
257 } // function SEARCHSENSITIVE()
263 * @param string $needle The string to look for
264 * @param string $haystack The string in which to look
265 * @param int $offset Offset within $haystack
268 public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) {
269 $needle = PHPExcel_Calculation_Functions
::flattenSingleValue($needle);
270 $haystack = PHPExcel_Calculation_Functions
::flattenSingleValue($haystack);
271 $offset = PHPExcel_Calculation_Functions
::flattenSingleValue($offset);
273 if (!is_bool($needle)) {
274 if (is_bool($haystack)) {
275 $haystack = ($haystack) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
278 if (($offset > 0) && (PHPExcel_Shared_String
::CountCharacters($haystack) > $offset)) {
279 if (PHPExcel_Shared_String
::CountCharacters($needle) == 0) {
282 if (function_exists('mb_stripos')) {
283 $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8');
285 $pos = stripos($haystack, $needle, --$offset);
287 if ($pos !== false) {
292 return PHPExcel_Calculation_Functions
::VALUE();
293 } // function SEARCHINSENSITIVE()
299 * @param mixed $value Value to check
300 * @param integer $decimals
301 * @param boolean $no_commas
304 public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) {
305 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
306 $decimals = PHPExcel_Calculation_Functions
::flattenSingleValue($decimals);
307 $no_commas = PHPExcel_Calculation_Functions
::flattenSingleValue($no_commas);
309 // Validate parameters
310 if (!is_numeric($value) ||
!is_numeric($decimals)) {
311 return PHPExcel_Calculation_Functions
::NaN();
313 $decimals = floor($decimals);
315 $valueResult = round($value,$decimals);
316 if ($decimals < 0) { $decimals = 0; }
318 $valueResult = number_format($valueResult,$decimals);
321 return (string) $valueResult;
322 } // function FIXEDFORMAT()
328 * @param string $value Value
329 * @param int $chars Number of characters
332 public static function LEFT($value = '', $chars = 1) {
333 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
334 $chars = PHPExcel_Calculation_Functions
::flattenSingleValue($chars);
337 return PHPExcel_Calculation_Functions
::VALUE();
340 if (is_bool($value)) {
341 $value = ($value) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
344 if (function_exists('mb_substr')) {
345 return mb_substr($value, 0, $chars, 'UTF-8');
347 return substr($value, 0, $chars);
355 * @param string $value Value
356 * @param int $start Start character
357 * @param int $chars Number of characters
360 public static function MID($value = '', $start = 1, $chars = null) {
361 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
362 $start = PHPExcel_Calculation_Functions
::flattenSingleValue($start);
363 $chars = PHPExcel_Calculation_Functions
::flattenSingleValue($chars);
365 if (($start < 1) ||
($chars < 0)) {
366 return PHPExcel_Calculation_Functions
::VALUE();
369 if (is_bool($value)) {
370 $value = ($value) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
373 if (function_exists('mb_substr')) {
374 return mb_substr($value, --$start, $chars, 'UTF-8');
376 return substr($value, --$start, $chars);
384 * @param string $value Value
385 * @param int $chars Number of characters
388 public static function RIGHT($value = '', $chars = 1) {
389 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
390 $chars = PHPExcel_Calculation_Functions
::flattenSingleValue($chars);
393 return PHPExcel_Calculation_Functions
::VALUE();
396 if (is_bool($value)) {
397 $value = ($value) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
400 if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) {
401 return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');
403 return substr($value, strlen($value) - $chars);
405 } // function RIGHT()
411 * @param string $value Value
414 public static function STRINGLENGTH($value = '') {
415 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
417 if (is_bool($value)) {
418 $value = ($value) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
421 if (function_exists('mb_strlen')) {
422 return mb_strlen($value, 'UTF-8');
424 return strlen($value);
426 } // function STRINGLENGTH()
432 * Converts a string value to upper case.
434 * @param string $mixedCaseString
437 public static function LOWERCASE($mixedCaseString) {
438 $mixedCaseString = PHPExcel_Calculation_Functions
::flattenSingleValue($mixedCaseString);
440 if (is_bool($mixedCaseString)) {
441 $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
444 return PHPExcel_Shared_String
::StrToLower($mixedCaseString);
445 } // function LOWERCASE()
451 * Converts a string value to upper case.
453 * @param string $mixedCaseString
456 public static function UPPERCASE($mixedCaseString) {
457 $mixedCaseString = PHPExcel_Calculation_Functions
::flattenSingleValue($mixedCaseString);
459 if (is_bool($mixedCaseString)) {
460 $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
463 return PHPExcel_Shared_String
::StrToUpper($mixedCaseString);
464 } // function UPPERCASE()
470 * Converts a string value to upper case.
472 * @param string $mixedCaseString
475 public static function PROPERCASE($mixedCaseString) {
476 $mixedCaseString = PHPExcel_Calculation_Functions
::flattenSingleValue($mixedCaseString);
478 if (is_bool($mixedCaseString)) {
479 $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation
::getTRUE() : PHPExcel_Calculation
::getFALSE();
482 return PHPExcel_Shared_String
::StrToTitle($mixedCaseString);
483 } // function PROPERCASE()
489 * @param string $oldText String to modify
490 * @param int $start Start character
491 * @param int $chars Number of characters
492 * @param string $newText String to replace in defined position
495 public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) {
496 $oldText = PHPExcel_Calculation_Functions
::flattenSingleValue($oldText);
497 $start = PHPExcel_Calculation_Functions
::flattenSingleValue($start);
498 $chars = PHPExcel_Calculation_Functions
::flattenSingleValue($chars);
499 $newText = PHPExcel_Calculation_Functions
::flattenSingleValue($newText);
501 $left = self
::LEFT($oldText,$start-1);
502 $right = self
::RIGHT($oldText,self
::STRINGLENGTH($oldText)-($start+
$chars)+
1);
504 return $left.$newText.$right;
505 } // function REPLACE()
511 * @param string $text Value
512 * @param string $fromText From Value
513 * @param string $toText To Value
514 * @param integer $instance Instance Number
517 public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) {
518 $text = PHPExcel_Calculation_Functions
::flattenSingleValue($text);
519 $fromText = PHPExcel_Calculation_Functions
::flattenSingleValue($fromText);
520 $toText = PHPExcel_Calculation_Functions
::flattenSingleValue($toText);
521 $instance = floor(PHPExcel_Calculation_Functions
::flattenSingleValue($instance));
523 if ($instance == 0) {
524 if(function_exists('mb_str_replace')) {
525 return mb_str_replace($fromText,$toText,$text);
527 return str_replace($fromText,$toText,$text);
531 while($instance > 0) {
532 if (function_exists('mb_strpos')) {
533 $pos = mb_strpos($text, $fromText, $pos+
1, 'UTF-8');
535 $pos = strpos($text, $fromText, $pos+
1);
537 if ($pos === false) {
542 if ($pos !== false) {
543 if (function_exists('mb_strlen')) {
544 return self
::REPLACE($text,++
$pos,mb_strlen($fromText, 'UTF-8'),$toText);
546 return self
::REPLACE($text,++
$pos,strlen($fromText),$toText);
552 } // function SUBSTITUTE()
558 * @param mixed $testValue Value to check
561 public static function RETURNSTRING($testValue = '') {
562 $testValue = PHPExcel_Calculation_Functions
::flattenSingleValue($testValue);
564 if (is_string($testValue)) {
568 } // function RETURNSTRING()
574 * @param mixed $value Value to check
575 * @param string $format Format mask to use
578 public static function TEXTFORMAT($value,$format) {
579 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
580 $format = PHPExcel_Calculation_Functions
::flattenSingleValue($format);
582 if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date
::isDateTimeFormatCode($format)) {
583 $value = PHPExcel_Calculation_DateTime
::DATEVALUE($value);
586 return (string) PHPExcel_Style_NumberFormat
::toFormattedString($value,$format);
587 } // function TEXTFORMAT()
592 * @param mixed $value Value to check
595 public static function VALUE($value = '') {
596 $value = PHPExcel_Calculation_Functions
::flattenSingleValue($value);
598 if (!is_numeric($value)) {
599 $numberValue = str_replace(
600 PHPExcel_Shared_String
::getThousandsSeparator(),
602 trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String
::getCurrencyCode())
604 if (is_numeric($numberValue)) {
605 return (float) $numberValue;
608 $dateSetting = PHPExcel_Calculation_Functions
::getReturnDateType();
609 PHPExcel_Calculation_Functions
::setReturnDateType(PHPExcel_Calculation_Functions
::RETURNDATE_EXCEL
);
611 if (strpos($value, ':') !== false) {
612 $timeValue = PHPExcel_Calculation_DateTime
::TIMEVALUE($value);
613 if ($timeValue !== PHPExcel_Calculation_Functions
::VALUE()) {
614 PHPExcel_Calculation_Functions
::setReturnDateType($dateSetting);
618 $dateValue = PHPExcel_Calculation_DateTime
::DATEVALUE($value);
619 if ($dateValue !== PHPExcel_Calculation_Functions
::VALUE()) {
620 PHPExcel_Calculation_Functions
::setReturnDateType($dateSetting);
623 PHPExcel_Calculation_Functions
::setReturnDateType($dateSetting);
625 return PHPExcel_Calculation_Functions
::VALUE();
627 return (float) $value;