PageRenderTime 35ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/v1.4.5/Classes/PHPExcel/Cell.php

#
PHP | 564 lines | 253 code | 70 blank | 241 comment | 44 complexity | 628d71a37db5cd24b714fa858648c148 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.0, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2007 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
  23. * @copyright Copyright (c) 2006 - 2007 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/lgpl.txt LGPL
  25. * @version ##VERSION##, ##DATE##
  26. */
  27. /** PHPExcel_Cell_DataType */
  28. require_once 'PHPExcel/Cell/DataType.php';
  29. /** PHPExcel_Cell_DataValidation */
  30. require_once 'PHPExcel/Cell/DataValidation.php';
  31. /** PHPExcel_Worksheet */
  32. require_once 'PHPExcel/Worksheet.php';
  33. /** PHPExcel_Calculation */
  34. require_once 'PHPExcel/Calculation.php';
  35. /**
  36. * PHPExcel_Cell
  37. *
  38. * @category PHPExcel
  39. * @package PHPExcel
  40. * @copyright Copyright (c) 2006 - 2007 PHPExcel (http://www.codeplex.com/PHPExcel)
  41. */
  42. class PHPExcel_Cell
  43. {
  44. /**
  45. * Column of the cell
  46. *
  47. * @var string
  48. */
  49. private $_column;
  50. /**
  51. * Row of the cell
  52. *
  53. * @var int
  54. */
  55. private $_row;
  56. /**
  57. * Value of the cell
  58. *
  59. * @var mixed
  60. */
  61. private $_value;
  62. /**
  63. * Type of the cell data
  64. *
  65. * @var string
  66. */
  67. private $_dataType;
  68. /**
  69. * Data validation
  70. *
  71. * @var PHPExcel_Cell_DataValidation
  72. */
  73. private $_dataValidation;
  74. /**
  75. * Parent worksheet
  76. *
  77. * @var PHPExcel_Worksheet
  78. */
  79. private $_parent;
  80. /**
  81. * Create a new Cell
  82. *
  83. * @param string $pColumn
  84. * @param int $pRow
  85. * @param mixed $pValue
  86. * @param string $pDataType
  87. * @param PHPExcel_Worksheet $pSheet
  88. * @throws Exception
  89. */
  90. public function __construct($pColumn = 'A', $pRow = 1, $pValue = null, $pDataType = null, PHPExcel_Worksheet $pSheet = null)
  91. {
  92. // Initialise cell coordinate
  93. $this->_column = strtoupper($pColumn);
  94. $this->_row = $pRow;
  95. // Initialise cell value
  96. $this->_value = $pValue;
  97. // Set datatype?
  98. if (!is_null($pDataType)) {
  99. $this->_dataType = $pDataType;
  100. }
  101. // Set worksheet
  102. $this->_parent = $pSheet;
  103. }
  104. /**
  105. * Get cell coordinate column
  106. *
  107. * @return string
  108. */
  109. public function getColumn()
  110. {
  111. return strtoupper($this->_column);
  112. }
  113. /**
  114. * Get cell coordinate row
  115. *
  116. * @return int
  117. */
  118. public function getRow()
  119. {
  120. return $this->_row;
  121. }
  122. /**
  123. * Get cell coordinate
  124. *
  125. * @return string
  126. */
  127. public function getCoordinate()
  128. {
  129. return $this->_column . $this->_row;
  130. }
  131. /**
  132. * Get cell value
  133. *
  134. * @return mixed
  135. */
  136. public function getValue()
  137. {
  138. return $this->_value;
  139. }
  140. /**
  141. * Set cell value
  142. *
  143. * This clears the cell formula.
  144. *
  145. * @param mixed $pValue Value
  146. * @param bool $pUpdateDataType Update the data type?
  147. */
  148. public function setValue($pValue = null, $pUpdateDataType = true)
  149. {
  150. $this->_value = $pValue;
  151. if ($pUpdateDataType) {
  152. $this->_dataType = PHPExcel_Cell_DataType::dataTypeForValue($pValue);
  153. }
  154. }
  155. /**
  156. * Set cell value (with explicit data type given)
  157. *
  158. * @param mixed $pValue Value
  159. * @param string $pDataType Explicit data type
  160. */
  161. public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
  162. {
  163. $this->_value = $pValue;
  164. $this->_dataType = $pDataType;
  165. }
  166. /**
  167. * Get caluclated cell value
  168. *
  169. * @return mixed
  170. */
  171. public function getCalculatedValue()
  172. {
  173. if ($this->_dataType != PHPExcel_Cell_DataType::TYPE_FORMULA) {
  174. return $this->_value;
  175. } else {
  176. return PHPExcel_Calculation::getInstance()->calculate($this);
  177. }
  178. }
  179. /**
  180. * Get cell data type
  181. *
  182. * @return string
  183. */
  184. public function getDataType()
  185. {
  186. return $this->_dataType;
  187. }
  188. /**
  189. * Set cell data type
  190. *
  191. * @param string $pDataType
  192. */
  193. public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
  194. {
  195. $this->_dataType = $pDataType;
  196. }
  197. /**
  198. * Has Data validation?
  199. *
  200. * @return boolean
  201. */
  202. public function hasDataValidation()
  203. {
  204. return !is_null($this->_dataValidation);
  205. }
  206. /**
  207. * Get Data validation
  208. *
  209. * @return PHPExcel_Cell_DataValidation
  210. */
  211. public function getDataValidation()
  212. {
  213. if (is_null($this->_dataValidation)) {
  214. $this->_dataValidation = new PHPExcel_Cell_DataValidation($this);
  215. }
  216. return $this->_dataValidation;
  217. }
  218. /**
  219. * Set Data validation
  220. *
  221. * @param PHPExcel_Cell_DataValidation $pDataValidation
  222. * @throws Exception
  223. */
  224. public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = null)
  225. {
  226. $this->_dataValidation = $pDataValidation;
  227. $this->_dataValidation->setParent($this);
  228. }
  229. /**
  230. * Get parent
  231. *
  232. * @return PHPExcel_Worksheet
  233. */
  234. public function getParent() {
  235. return $this->_parent;
  236. }
  237. /**
  238. * Is cell in a specific range?
  239. *
  240. * @param string $pRange Cell range (e.g. A1:A1)
  241. * @return boolean
  242. */
  243. public function isInRange($pRange = 'A1:A1')
  244. {
  245. // Uppercase coordinate
  246. $pRange = strtoupper($pRange);
  247. // Extract range
  248. $rangeA = '';
  249. $rangeB = '';
  250. if (strpos($pRange, ':') === false) {
  251. $rangeA = $pRange;
  252. $rangeB = $pRange;
  253. } else {
  254. list($rangeA, $rangeB) = explode(':', $pRange);
  255. }
  256. // Calculate range outer borders
  257. $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
  258. $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
  259. // Translate column into index
  260. $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
  261. $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
  262. // Translate properties
  263. $myColumn = PHPExcel_Cell::columnIndexFromString($this->getColumn()) - 1;
  264. $myRow = $this->getRow();
  265. // Verify if cell is in range
  266. return (
  267. ($rangeStart[0] <= $myColumn && $rangeEnd[0] >= $myColumn) &&
  268. ($rangeStart[1] <= $myRow && $rangeEnd[1] >= $myRow)
  269. );
  270. }
  271. /**
  272. * Coordinate from string
  273. *
  274. * @param string $pCoordinateString
  275. * @return array Array containing column and row (indexes 0 and 1)
  276. * @throws Exception
  277. */
  278. public static function coordinateFromString($pCoordinateString = 'A1')
  279. {
  280. if (eregi(':', $pCoordinateString)) {
  281. throw new Exception('Cell coordinate string can not be a range of cells.');
  282. } else if (eregi('\$', $pCoordinateString)) {
  283. throw new Exception('Cell coordinate string must not be absolute.');
  284. } else if ($pCoordinateString == '') {
  285. throw new Exception('Cell coordinate can not be zero-length string.');
  286. } else {
  287. // Column
  288. $column = '';
  289. // Row
  290. $row = '';
  291. // Calculate column
  292. for ($i = 0; $i < strlen($pCoordinateString); $i++) {
  293. if (!is_numeric(substr($pCoordinateString, $i, 1))) {
  294. $column .= strtoupper(substr($pCoordinateString, $i, 1));
  295. } else {
  296. $row = substr($pCoordinateString, $i);
  297. break;
  298. }
  299. }
  300. // Return array
  301. return array($column, $row);
  302. }
  303. }
  304. /**
  305. * Make string coordinate absolute
  306. *
  307. * @param string $pCoordinateString
  308. * @return string Absolute coordinate
  309. * @throws Exception
  310. */
  311. public static function absoluteCoordinate($pCoordinateString = 'A1')
  312. {
  313. if (!eregi(':', $pCoordinateString)) {
  314. // Return value
  315. $returnValue = '';
  316. // Create absolute coordinate
  317. list($column, $row) = PHPExcel_Cell::coordinateFromString($pCoordinateString);
  318. $returnValue = '$' . $column . '$' . $row;
  319. // Return
  320. return $returnValue;
  321. } else {
  322. throw new Exception("Coordinate string should not be a cell range.");
  323. }
  324. }
  325. /**
  326. * Split range into coordinate strings
  327. *
  328. * @param string $pRange
  329. * @return array Array containg two coordinate strings
  330. */
  331. public static function splitRange($pRange = 'A1:A1')
  332. {
  333. return explode(':', $pRange);
  334. }
  335. /**
  336. * Calculate range dimension
  337. *
  338. * @param string $pRange Cell range (e.g. A1:A1)
  339. * @return array Range dimension (width, height)
  340. */
  341. public static function rangeDimension($pRange = 'A1:A1')
  342. {
  343. // Uppercase coordinate
  344. $pRange = strtoupper($pRange);
  345. // Extract range
  346. $rangeA = '';
  347. $rangeB = '';
  348. if (strpos($pRange, ':') === false) {
  349. $rangeA = $pRange;
  350. $rangeB = $pRange;
  351. } else {
  352. list($rangeA, $rangeB) = explode(':', $pRange);
  353. }
  354. // Calculate range outer borders
  355. $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
  356. $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
  357. // Translate column into index
  358. $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]);
  359. $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]);
  360. return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) );
  361. }
  362. /**
  363. * Columnindex from string
  364. *
  365. * @param string $pString
  366. * @return int Column index (base 1 !!!)
  367. * @throws Exception
  368. */
  369. public static function columnIndexFromString($pString = 'A')
  370. {
  371. // Convert to uppercase
  372. $pString = strtoupper($pString);
  373. // Convert column to integer
  374. if (strlen($pString) == 1) {
  375. $result = 0;
  376. $result += (ord(substr($pString, 0, 1)) - 65);
  377. $result += 1;
  378. return $result;
  379. } else if (strlen($pString) == 2) {
  380. $result = 0;
  381. $result += ( (1 + (ord(substr($pString, 0, 1)) - 65) ) * 26);
  382. $result += (ord(substr($pString, 1, 2)) - 65);
  383. $result += 1;
  384. return $result;
  385. } else {
  386. throw new Exception("Column string index can not be " . (strlen($pString) != 0 ? "longer than 2 characters" : "empty") . ".");
  387. }
  388. }
  389. /**
  390. * String from columnindex
  391. *
  392. * @param int $pColumnIndex Column index (base 0 !!!)
  393. * @return string
  394. */
  395. public static function stringFromColumnIndex($pColumnIndex = 0)
  396. {
  397. // Convert column to string
  398. $returnValue = '';
  399. // Determine column string
  400. if ($pColumnIndex < 26) {
  401. $returnValue = chr(65 + $pColumnIndex);
  402. } else {
  403. $iRemainder = (int)($pColumnIndex / 26) -1;
  404. $returnValue = PHPExcel_Cell::stringFromColumnIndex( $iRemainder ).chr(65 + $pColumnIndex%26) ;
  405. }
  406. // Return
  407. return $returnValue;
  408. }
  409. /**
  410. * Extract all cell references in range
  411. *
  412. * @param string $pRange Range (e.g. A1 or A1:A10 or A1:A10 A100:A1000)
  413. * @return array Array containing single cell references
  414. */
  415. public static function extractAllCellReferencesInRange($pRange = 'A1') {
  416. // Returnvalue
  417. $returnValue = array();
  418. // Explode spaces
  419. $aExplodeSpaces = explode(' ', str_replace('$', '', strtoupper($pRange)));
  420. foreach ($aExplodeSpaces as $explodedSpaces) {
  421. // Single cell?
  422. if (strpos($explodedSpaces, ':') === false) {
  423. $col = 'A';
  424. $row = 1;
  425. list($col, $row) = PHPExcel_Cell::coordinateFromString($explodedSpaces);
  426. if (strlen($col) <= 2) {
  427. $returnValue[] = $explodedSpaces;
  428. }
  429. continue;
  430. }
  431. // Range...
  432. $rangeStart = '';
  433. $rangeEnd = '';
  434. $startingCol = 0;
  435. $startingRow = 0;
  436. $endingCol = 0;
  437. $endingRow = 0;
  438. list($rangeStart, $rangeEnd) = explode(':', $explodedSpaces);
  439. list($startingCol, $startingRow) = PHPExcel_Cell::coordinateFromString($rangeStart);
  440. list($endingCol, $endingRow) = PHPExcel_Cell::coordinateFromString($rangeEnd);
  441. // Conversions...
  442. $startingCol = PHPExcel_Cell::columnIndexFromString($startingCol) - 1;
  443. $endingCol = PHPExcel_Cell::columnIndexFromString($endingCol) - 1;
  444. // Current data
  445. $currentCol = $startingCol;
  446. $currentRow = $startingRow;
  447. // Loop cells
  448. while ($currentCol >= $startingCol && $currentCol <= $endingCol) {
  449. while ($currentRow >= $startingRow && $currentRow <= $endingRow) {
  450. if (strlen(PHPExcel_Cell::stringFromColumnIndex($currentCol)) <= 2) {
  451. $returnValue[] = PHPExcel_Cell::stringFromColumnIndex($currentCol) . $currentRow;
  452. }
  453. $currentRow++;
  454. }
  455. $currentCol++;
  456. $currentRow = $startingRow;
  457. }
  458. }
  459. // Return value
  460. return $returnValue;
  461. }
  462. /**
  463. * Compare 2 cells
  464. *
  465. * @param PHPExcel_Cell $a Cell a
  466. * @param PHPExcel_Cell $a Cell b
  467. * @return int Result of comparison (always -1 or 1, never zero!)
  468. */
  469. public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)
  470. {
  471. if ($a->_row < $b->_row) {
  472. return -1;
  473. } elseif ($a->_row > $b->_row) {
  474. return 1;
  475. } elseif (PHPExcel_Cell::columnIndexFromString($a->_column) < PHPExcel_Cell::columnIndexFromString($b->_column)) {
  476. return -1;
  477. } else {
  478. return 1;
  479. }
  480. }
  481. /**
  482. * Implement PHP __clone to create a deep clone, not just a shallow copy.
  483. */
  484. public function __clone() {
  485. $vars = get_object_vars($this);
  486. foreach ($vars as $key => $value) {
  487. if (is_object($value)) {
  488. $this->$key = clone $value;
  489. } else {
  490. $this->$key = $value;
  491. }
  492. }
  493. }
  494. }