For God so loved the world, that He gave His only begotten Son, that all who believe in Him should not perish but have everlasting life
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

651 lines
22 KiB

  1. <?php
  2. /** PHPExcel root directory */
  3. if (!defined('PHPEXCEL_ROOT')) {
  4. /**
  5. * @ignore
  6. */
  7. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  8. require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
  9. }
  10. /**
  11. * PHPExcel_Calculation_TextData
  12. *
  13. * Copyright (c) 2006 - 2015 PHPExcel
  14. *
  15. * This library is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU Lesser General Public
  17. * License as published by the Free Software Foundation; either
  18. * version 2.1 of the License, or (at your option) any later version.
  19. *
  20. * This library is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. * Lesser General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Lesser General Public
  26. * License along with this library; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. *
  29. * @category PHPExcel
  30. * @package PHPExcel_Calculation
  31. * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  32. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  33. * @version ##VERSION##, ##DATE##
  34. */
  35. class PHPExcel_Calculation_TextData
  36. {
  37. private static $invalidChars;
  38. private static function unicodeToOrd($c)
  39. {
  40. if (ord($c{0}) >=0 && ord($c{0}) <= 127) {
  41. return ord($c{0});
  42. } elseif (ord($c{0}) >= 192 && ord($c{0}) <= 223) {
  43. return (ord($c{0})-192)*64 + (ord($c{1})-128);
  44. } elseif (ord($c{0}) >= 224 && ord($c{0}) <= 239) {
  45. return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128);
  46. } elseif (ord($c{0}) >= 240 && ord($c{0}) <= 247) {
  47. return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128);
  48. } elseif (ord($c{0}) >= 248 && ord($c{0}) <= 251) {
  49. 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);
  50. } elseif (ord($c{0}) >= 252 && ord($c{0}) <= 253) {
  51. 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);
  52. } elseif (ord($c{0}) >= 254 && ord($c{0}) <= 255) {
  53. // error
  54. return PHPExcel_Calculation_Functions::VALUE();
  55. }
  56. return 0;
  57. }
  58. /**
  59. * CHARACTER
  60. *
  61. * @param string $character Value
  62. * @return int
  63. */
  64. public static function CHARACTER($character)
  65. {
  66. $character = PHPExcel_Calculation_Functions::flattenSingleValue($character);
  67. if ((!is_numeric($character)) || ($character < 0)) {
  68. return PHPExcel_Calculation_Functions::VALUE();
  69. }
  70. if (function_exists('mb_convert_encoding')) {
  71. return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES');
  72. } else {
  73. return chr(intval($character));
  74. }
  75. }
  76. /**
  77. * TRIMNONPRINTABLE
  78. *
  79. * @param mixed $stringValue Value to check
  80. * @return string
  81. */
  82. public static function TRIMNONPRINTABLE($stringValue = '')
  83. {
  84. $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue);
  85. if (is_bool($stringValue)) {
  86. return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  87. }
  88. if (self::$invalidChars == null) {
  89. self::$invalidChars = range(chr(0), chr(31));
  90. }
  91. if (is_string($stringValue) || is_numeric($stringValue)) {
  92. return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F"));
  93. }
  94. return null;
  95. }
  96. /**
  97. * TRIMSPACES
  98. *
  99. * @param mixed $stringValue Value to check
  100. * @return string
  101. */
  102. public static function TRIMSPACES($stringValue = '')
  103. {
  104. $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue);
  105. if (is_bool($stringValue)) {
  106. return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  107. }
  108. if (is_string($stringValue) || is_numeric($stringValue)) {
  109. return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' ');
  110. }
  111. return null;
  112. }
  113. /**
  114. * ASCIICODE
  115. *
  116. * @param string $characters Value
  117. * @return int
  118. */
  119. public static function ASCIICODE($characters)
  120. {
  121. if (($characters === null) || ($characters === '')) {
  122. return PHPExcel_Calculation_Functions::VALUE();
  123. }
  124. $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters);
  125. if (is_bool($characters)) {
  126. if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
  127. $characters = (int) $characters;
  128. } else {
  129. $characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  130. }
  131. }
  132. $character = $characters;
  133. if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) {
  134. if (mb_strlen($characters, 'UTF-8') > 1) {
  135. $character = mb_substr($characters, 0, 1, 'UTF-8');
  136. }
  137. return self::unicodeToOrd($character);
  138. } else {
  139. if (strlen($characters) > 0) {
  140. $character = substr($characters, 0, 1);
  141. }
  142. return ord($character);
  143. }
  144. }
  145. /**
  146. * CONCATENATE
  147. *
  148. * @return string
  149. */
  150. public static function CONCATENATE()
  151. {
  152. $returnValue = '';
  153. // Loop through arguments
  154. $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());
  155. foreach ($aArgs as $arg) {
  156. if (is_bool($arg)) {
  157. if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
  158. $arg = (int) $arg;
  159. } else {
  160. $arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  161. }
  162. }
  163. $returnValue .= $arg;
  164. }
  165. return $returnValue;
  166. }
  167. /**
  168. * DOLLAR
  169. *
  170. * This function converts a number to text using currency format, with the decimals rounded to the specified place.
  171. * The format used is $#,##0.00_);($#,##0.00)..
  172. *
  173. * @param float $value The value to format
  174. * @param int $decimals The number of digits to display to the right of the decimal point.
  175. * If decimals is negative, number is rounded to the left of the decimal point.
  176. * If you omit decimals, it is assumed to be 2
  177. * @return string
  178. */
  179. public static function DOLLAR($value = 0, $decimals = 2)
  180. {
  181. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  182. $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals);
  183. // Validate parameters
  184. if (!is_numeric($value) || !is_numeric($decimals)) {
  185. return PHPExcel_Calculation_Functions::NaN();
  186. }
  187. $decimals = floor($decimals);
  188. $mask = '$#,##0';
  189. if ($decimals > 0) {
  190. $mask .= '.' . str_repeat('0', $decimals);
  191. } else {
  192. $round = pow(10, abs($decimals));
  193. if ($value < 0) {
  194. $round = 0-$round;
  195. }
  196. $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round);
  197. }
  198. return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask);
  199. }
  200. /**
  201. * SEARCHSENSITIVE
  202. *
  203. * @param string $needle The string to look for
  204. * @param string $haystack The string in which to look
  205. * @param int $offset Offset within $haystack
  206. * @return string
  207. */
  208. public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1)
  209. {
  210. $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle);
  211. $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack);
  212. $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset);
  213. if (!is_bool($needle)) {
  214. if (is_bool($haystack)) {
  215. $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  216. }
  217. if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) {
  218. if (PHPExcel_Shared_String::CountCharacters($needle) == 0) {
  219. return $offset;
  220. }
  221. if (function_exists('mb_strpos')) {
  222. $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
  223. } else {
  224. $pos = strpos($haystack, $needle, --$offset);
  225. }
  226. if ($pos !== false) {
  227. return ++$pos;
  228. }
  229. }
  230. }
  231. return PHPExcel_Calculation_Functions::VALUE();
  232. }
  233. /**
  234. * SEARCHINSENSITIVE
  235. *
  236. * @param string $needle The string to look for
  237. * @param string $haystack The string in which to look
  238. * @param int $offset Offset within $haystack
  239. * @return string
  240. */
  241. public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1)
  242. {
  243. $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle);
  244. $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack);
  245. $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset);
  246. if (!is_bool($needle)) {
  247. if (is_bool($haystack)) {
  248. $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  249. }
  250. if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) {
  251. if (PHPExcel_Shared_String::CountCharacters($needle) == 0) {
  252. return $offset;
  253. }
  254. if (function_exists('mb_stripos')) {
  255. $pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8');
  256. } else {
  257. $pos = stripos($haystack, $needle, --$offset);
  258. }
  259. if ($pos !== false) {
  260. return ++$pos;
  261. }
  262. }
  263. }
  264. return PHPExcel_Calculation_Functions::VALUE();
  265. }
  266. /**
  267. * FIXEDFORMAT
  268. *
  269. * @param mixed $value Value to check
  270. * @param integer $decimals
  271. * @param boolean $no_commas
  272. * @return boolean
  273. */
  274. public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false)
  275. {
  276. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  277. $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals);
  278. $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas);
  279. // Validate parameters
  280. if (!is_numeric($value) || !is_numeric($decimals)) {
  281. return PHPExcel_Calculation_Functions::NaN();
  282. }
  283. $decimals = floor($decimals);
  284. $valueResult = round($value, $decimals);
  285. if ($decimals < 0) {
  286. $decimals = 0;
  287. }
  288. if (!$no_commas) {
  289. $valueResult = number_format($valueResult, $decimals);
  290. }
  291. return (string) $valueResult;
  292. }
  293. /**
  294. * LEFT
  295. *
  296. * @param string $value Value
  297. * @param int $chars Number of characters
  298. * @return string
  299. */
  300. public static function LEFT($value = '', $chars = 1)
  301. {
  302. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  303. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  304. if ($chars < 0) {
  305. return PHPExcel_Calculation_Functions::VALUE();
  306. }
  307. if (is_bool($value)) {
  308. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  309. }
  310. if (function_exists('mb_substr')) {
  311. return mb_substr($value, 0, $chars, 'UTF-8');
  312. } else {
  313. return substr($value, 0, $chars);
  314. }
  315. }
  316. /**
  317. * MID
  318. *
  319. * @param string $value Value
  320. * @param int $start Start character
  321. * @param int $chars Number of characters
  322. * @return string
  323. */
  324. public static function MID($value = '', $start = 1, $chars = null)
  325. {
  326. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  327. $start = PHPExcel_Calculation_Functions::flattenSingleValue($start);
  328. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  329. if (($start < 1) || ($chars < 0)) {
  330. return PHPExcel_Calculation_Functions::VALUE();
  331. }
  332. if (is_bool($value)) {
  333. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  334. }
  335. if (function_exists('mb_substr')) {
  336. return mb_substr($value, --$start, $chars, 'UTF-8');
  337. } else {
  338. return substr($value, --$start, $chars);
  339. }
  340. }
  341. /**
  342. * RIGHT
  343. *
  344. * @param string $value Value
  345. * @param int $chars Number of characters
  346. * @return string
  347. */
  348. public static function RIGHT($value = '', $chars = 1)
  349. {
  350. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  351. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  352. if ($chars < 0) {
  353. return PHPExcel_Calculation_Functions::VALUE();
  354. }
  355. if (is_bool($value)) {
  356. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  357. }
  358. if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) {
  359. return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');
  360. } else {
  361. return substr($value, strlen($value) - $chars);
  362. }
  363. }
  364. /**
  365. * STRINGLENGTH
  366. *
  367. * @param string $value Value
  368. * @return string
  369. */
  370. public static function STRINGLENGTH($value = '')
  371. {
  372. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  373. if (is_bool($value)) {
  374. $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  375. }
  376. if (function_exists('mb_strlen')) {
  377. return mb_strlen($value, 'UTF-8');
  378. } else {
  379. return strlen($value);
  380. }
  381. }
  382. /**
  383. * LOWERCASE
  384. *
  385. * Converts a string value to upper case.
  386. *
  387. * @param string $mixedCaseString
  388. * @return string
  389. */
  390. public static function LOWERCASE($mixedCaseString)
  391. {
  392. $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);
  393. if (is_bool($mixedCaseString)) {
  394. $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  395. }
  396. return PHPExcel_Shared_String::StrToLower($mixedCaseString);
  397. }
  398. /**
  399. * UPPERCASE
  400. *
  401. * Converts a string value to upper case.
  402. *
  403. * @param string $mixedCaseString
  404. * @return string
  405. */
  406. public static function UPPERCASE($mixedCaseString)
  407. {
  408. $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);
  409. if (is_bool($mixedCaseString)) {
  410. $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  411. }
  412. return PHPExcel_Shared_String::StrToUpper($mixedCaseString);
  413. }
  414. /**
  415. * PROPERCASE
  416. *
  417. * Converts a string value to upper case.
  418. *
  419. * @param string $mixedCaseString
  420. * @return string
  421. */
  422. public static function PROPERCASE($mixedCaseString)
  423. {
  424. $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);
  425. if (is_bool($mixedCaseString)) {
  426. $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();
  427. }
  428. return PHPExcel_Shared_String::StrToTitle($mixedCaseString);
  429. }
  430. /**
  431. * REPLACE
  432. *
  433. * @param string $oldText String to modify
  434. * @param int $start Start character
  435. * @param int $chars Number of characters
  436. * @param string $newText String to replace in defined position
  437. * @return string
  438. */
  439. public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText)
  440. {
  441. $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText);
  442. $start = PHPExcel_Calculation_Functions::flattenSingleValue($start);
  443. $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars);
  444. $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText);
  445. $left = self::LEFT($oldText, $start-1);
  446. $right = self::RIGHT($oldText, self::STRINGLENGTH($oldText)-($start+$chars)+1);
  447. return $left.$newText.$right;
  448. }
  449. /**
  450. * SUBSTITUTE
  451. *
  452. * @param string $text Value
  453. * @param string $fromText From Value
  454. * @param string $toText To Value
  455. * @param integer $instance Instance Number
  456. * @return string
  457. */
  458. public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0)
  459. {
  460. $text = PHPExcel_Calculation_Functions::flattenSingleValue($text);
  461. $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText);
  462. $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText);
  463. $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance));
  464. if ($instance == 0) {
  465. if (function_exists('mb_str_replace')) {
  466. return mb_str_replace($fromText, $toText, $text);
  467. } else {
  468. return str_replace($fromText, $toText, $text);
  469. }
  470. } else {
  471. $pos = -1;
  472. while ($instance > 0) {
  473. if (function_exists('mb_strpos')) {
  474. $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8');
  475. } else {
  476. $pos = strpos($text, $fromText, $pos+1);
  477. }
  478. if ($pos === false) {
  479. break;
  480. }
  481. --$instance;
  482. }
  483. if ($pos !== false) {
  484. if (function_exists('mb_strlen')) {
  485. return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText);
  486. } else {
  487. return self::REPLACE($text, ++$pos, strlen($fromText), $toText);
  488. }
  489. }
  490. }
  491. return $text;
  492. }
  493. /**
  494. * RETURNSTRING
  495. *
  496. * @param mixed $testValue Value to check
  497. * @return boolean
  498. */
  499. public static function RETURNSTRING($testValue = '')
  500. {
  501. $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue);
  502. if (is_string($testValue)) {
  503. return $testValue;
  504. }
  505. return null;
  506. }
  507. /**
  508. * TEXTFORMAT
  509. *
  510. * @param mixed $value Value to check
  511. * @param string $format Format mask to use
  512. * @return boolean
  513. */
  514. public static function TEXTFORMAT($value, $format)
  515. {
  516. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  517. $format = PHPExcel_Calculation_Functions::flattenSingleValue($format);
  518. if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) {
  519. $value = PHPExcel_Calculation_DateTime::DATEVALUE($value);
  520. }
  521. return (string) PHPExcel_Style_NumberFormat::toFormattedString($value, $format);
  522. }
  523. /**
  524. * VALUE
  525. *
  526. * @param mixed $value Value to check
  527. * @return boolean
  528. */
  529. public static function VALUE($value = '')
  530. {
  531. $value = PHPExcel_Calculation_Functions::flattenSingleValue($value);
  532. if (!is_numeric($value)) {
  533. $numberValue = str_replace(
  534. PHPExcel_Shared_String::getThousandsSeparator(),
  535. '',
  536. trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode())
  537. );
  538. if (is_numeric($numberValue)) {
  539. return (float) $numberValue;
  540. }
  541. $dateSetting = PHPExcel_Calculation_Functions::getReturnDateType();
  542. PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
  543. if (strpos($value, ':') !== false) {
  544. $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value);
  545. if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) {
  546. PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);
  547. return $timeValue;
  548. }
  549. }
  550. $dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value);
  551. if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) {
  552. PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);
  553. return $dateValue;
  554. }
  555. PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);
  556. return PHPExcel_Calculation_Functions::VALUE();
  557. }
  558. return (float) $value;
  559. }
  560. }