PageRenderTime 59ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/wi6857-memory/Classes/PHPExcel.php

#
PHP | 647 lines | 279 code | 74 blank | 294 comment | 41 complexity | f6aa163702da3f7f1e6fbe6f7425c426 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 - 2009 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 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version ##VERSION##, ##DATE##
  26. */
  27. /** PHPExcel_Cell */
  28. require_once 'PHPExcel/Cell.php';
  29. /** PHPExcel_DocumentProperties */
  30. require_once 'PHPExcel/DocumentProperties.php';
  31. /** PHPExcel_DocumentSecurity */
  32. require_once 'PHPExcel/DocumentSecurity.php';
  33. /** PHPExcel_Worksheet */
  34. require_once 'PHPExcel/Worksheet.php';
  35. /** PHPExcel_Shared_ZipStreamWrapper */
  36. require_once 'PHPExcel/Shared/ZipStreamWrapper.php';
  37. /** PHPExcel_NamedRange */
  38. require_once 'PHPExcel/NamedRange.php';
  39. /** PHPExcel_WorksheetIterator */
  40. require_once 'PHPExcel/WorksheetIterator.php';
  41. /**
  42. * PHPExcel
  43. *
  44. * @category PHPExcel
  45. * @package PHPExcel
  46. * @copyright Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  47. */
  48. class PHPExcel
  49. {
  50. /**
  51. * Document properties
  52. *
  53. * @var PHPExcel_DocumentProperties
  54. */
  55. private $_properties;
  56. /**
  57. * Document security
  58. *
  59. * @var PHPExcel_DocumentSecurity
  60. */
  61. private $_security;
  62. /**
  63. * Collection of Worksheet objects
  64. *
  65. * @var PHPExcel_Worksheet[]
  66. */
  67. private $_workSheetCollection = array();
  68. /**
  69. * Active sheet index
  70. *
  71. * @var int
  72. */
  73. private $_activeSheetIndex = 0;
  74. /**
  75. * Named ranges
  76. *
  77. * @var PHPExcel_NamedRange[]
  78. */
  79. private $_namedRanges = array();
  80. /**
  81. * CellXf supervisor
  82. *
  83. * @var PHPExcel_Style
  84. */
  85. private $_cellXfSupervisor;
  86. /**
  87. * CellXf collection
  88. *
  89. * @var PHPExcel_Style[]
  90. */
  91. private $_cellXfCollection = array();
  92. /**
  93. * CellStyleXf collection
  94. *
  95. * @var PHPExcel_Style[]
  96. */
  97. private $_cellStyleXfCollection = array();
  98. /**
  99. * Create a new PHPExcel with one Worksheet
  100. */
  101. public function __construct()
  102. {
  103. // Initialise worksheet collection and add one worksheet
  104. $this->_workSheetCollection = array();
  105. $this->_workSheetCollection[] = new PHPExcel_Worksheet($this);
  106. $this->_activeSheetIndex = 0;
  107. // Create document properties
  108. $this->_properties = new PHPExcel_DocumentProperties();
  109. // Create document security
  110. $this->_security = new PHPExcel_DocumentSecurity();
  111. // Set named ranges
  112. $this->_namedRanges = array();
  113. // Create the cellXf supervisor
  114. $this->_cellXfSupervisor = new PHPExcel_Style(true);
  115. $this->_cellXfSupervisor->bindParent($this);
  116. // Create the default style
  117. $this->addCellXf(new PHPExcel_Style);
  118. $this->addCellStyleXf(new PHPExcel_Style);
  119. }
  120. /**
  121. * Get properties
  122. *
  123. * @return PHPExcel_DocumentProperties
  124. */
  125. public function getProperties()
  126. {
  127. return $this->_properties;
  128. }
  129. /**
  130. * Set properties
  131. *
  132. * @param PHPExcel_DocumentProperties $pValue
  133. */
  134. public function setProperties(PHPExcel_DocumentProperties $pValue)
  135. {
  136. $this->_properties = $pValue;
  137. }
  138. /**
  139. * Get security
  140. *
  141. * @return PHPExcel_DocumentSecurity
  142. */
  143. public function getSecurity()
  144. {
  145. return $this->_security;
  146. }
  147. /**
  148. * Set security
  149. *
  150. * @param PHPExcel_DocumentSecurity $pValue
  151. */
  152. public function setSecurity(PHPExcel_DocumentSecurity $pValue)
  153. {
  154. $this->_security = $pValue;
  155. }
  156. /**
  157. * Get active sheet
  158. *
  159. * @return PHPExcel_Worksheet
  160. */
  161. public function getActiveSheet()
  162. {
  163. return $this->_workSheetCollection[$this->_activeSheetIndex];
  164. }
  165. /**
  166. * Create sheet and add it to this workbook
  167. *
  168. * @return PHPExcel_Worksheet
  169. */
  170. public function createSheet()
  171. {
  172. $newSheet = new PHPExcel_Worksheet($this);
  173. $this->addSheet($newSheet);
  174. return $newSheet;
  175. }
  176. /**
  177. * Add sheet
  178. *
  179. * @param PHPExcel_Worksheet $pSheet
  180. * @throws Exception
  181. */
  182. public function addSheet(PHPExcel_Worksheet $pSheet = null)
  183. {
  184. $this->_workSheetCollection[] = $pSheet;
  185. }
  186. /**
  187. * Remove sheet by index
  188. *
  189. * @param int $pIndex Active sheet index
  190. * @throws Exception
  191. */
  192. public function removeSheetByIndex($pIndex = 0)
  193. {
  194. if ($pIndex > count($this->_workSheetCollection) - 1) {
  195. throw new Exception("Sheet index is out of bounds.");
  196. } else {
  197. array_splice($this->_workSheetCollection, $pIndex, 1);
  198. }
  199. }
  200. /**
  201. * Get sheet by index
  202. *
  203. * @param int $pIndex Sheet index
  204. * @return PHPExcel_Worksheet
  205. * @throws Exception
  206. */
  207. public function getSheet($pIndex = 0)
  208. {
  209. if ($pIndex > count($this->_workSheetCollection) - 1) {
  210. throw new Exception("Sheet index is out of bounds.");
  211. } else {
  212. return $this->_workSheetCollection[$pIndex];
  213. }
  214. }
  215. /**
  216. * Get all sheets
  217. *
  218. * @return PHPExcel_Worksheet[]
  219. */
  220. public function getAllSheets()
  221. {
  222. return $this->_workSheetCollection;
  223. }
  224. /**
  225. * Get sheet by name
  226. *
  227. * @param string $pName Sheet name
  228. * @return PHPExcel_Worksheet
  229. * @throws Exception
  230. */
  231. public function getSheetByName($pName = '')
  232. {
  233. $worksheetCount = count($this->_workSheetCollection);
  234. for ($i = 0; $i < $worksheetCount; ++$i) {
  235. if ($this->_workSheetCollection[$i]->getTitle() == $pName) {
  236. return $this->_workSheetCollection[$i];
  237. }
  238. }
  239. return null;
  240. }
  241. /**
  242. * Get index for sheet
  243. *
  244. * @param PHPExcel_Worksheet $pSheet
  245. * @return Sheet index
  246. * @throws Exception
  247. */
  248. public function getIndex(PHPExcel_Worksheet $pSheet)
  249. {
  250. foreach ($this->_workSheetCollection as $key => $value) {
  251. if ($value->getHashCode() == $pSheet->getHashCode()) {
  252. return $key;
  253. }
  254. }
  255. }
  256. /**
  257. * Get sheet count
  258. *
  259. * @return int
  260. */
  261. public function getSheetCount()
  262. {
  263. return count($this->_workSheetCollection);
  264. }
  265. /**
  266. * Get active sheet index
  267. *
  268. * @return int Active sheet index
  269. */
  270. public function getActiveSheetIndex()
  271. {
  272. return $this->_activeSheetIndex;
  273. }
  274. /**
  275. * Set active sheet index
  276. *
  277. * @param int $pIndex Active sheet index
  278. * @throws Exception
  279. */
  280. public function setActiveSheetIndex($pIndex = 0)
  281. {
  282. if ($pIndex > count($this->_workSheetCollection) - 1) {
  283. throw new Exception("Active sheet index is out of bounds.");
  284. } else {
  285. $this->_activeSheetIndex = $pIndex;
  286. }
  287. }
  288. /**
  289. * Get sheet names
  290. *
  291. * @return string[]
  292. */
  293. public function getSheetNames()
  294. {
  295. $returnValue = array();
  296. $worksheetCount = $this->getSheetCount();
  297. for ($i = 0; $i < $worksheetCount; ++$i) {
  298. array_push($returnValue, $this->getSheet($i)->getTitle());
  299. }
  300. return $returnValue;
  301. }
  302. /**
  303. * Add external sheet
  304. *
  305. * @param PHPExcel_Worksheet $pSheet External sheet to add
  306. * @throws Exception
  307. */
  308. public function addExternalSheet(PHPExcel_Worksheet $pSheet) {
  309. if (!is_null($this->getSheetByName($pSheet->getTitle()))) {
  310. throw new Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
  311. }
  312. $pSheet->rebindParent($this);
  313. $this->addSheet($pSheet);
  314. }
  315. /**
  316. * Get named ranges
  317. *
  318. * @return PHPExcel_NamedRange[]
  319. */
  320. public function getNamedRanges() {
  321. return $this->_namedRanges;
  322. }
  323. /**
  324. * Add named range
  325. *
  326. * @param PHPExcel_NamedRange $namedRange
  327. */
  328. public function addNamedRange(PHPExcel_NamedRange $namedRange) {
  329. $this->_namedRanges[$namedRange->getName()] = $namedRange;
  330. }
  331. /**
  332. * Get named range
  333. *
  334. * @param string $namedRange
  335. */
  336. public function getNamedRange($namedRange) {
  337. if ($namedRange != '' && !is_null($namedRange) && @isset($this->_namedRanges[$namedRange])) {
  338. return $this->_namedRanges[$namedRange];
  339. }
  340. return null;
  341. }
  342. /**
  343. * Remove named range
  344. *
  345. * @param string $namedRange
  346. */
  347. public function removeNamedRange($namedRange) {
  348. if ($namedRange != '' && !is_null($namedRange) && @isset($this->_namedRanges[$namedRange])) {
  349. unset($this->_namedRanges[$namedRange]);
  350. }
  351. }
  352. /**
  353. * Get worksheet iterator
  354. *
  355. * @return PHPExcel_WorksheetIterator
  356. */
  357. public function getWorksheetIterator() {
  358. return new PHPExcel_WorksheetIterator($this);
  359. }
  360. /**
  361. * Copy workbook (!= clone!)
  362. *
  363. * @return PHPExcel
  364. */
  365. public function copy() {
  366. $copied = clone $this;
  367. $worksheetCount = count($this->_workSheetCollection);
  368. for ($i = 0; $i < $worksheetCount; ++$i) {
  369. $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy();
  370. $this->_workSheetCollection[$i]->rebindParent($this);
  371. }
  372. return $copied;
  373. }
  374. /**
  375. * Implement PHP __clone to create a deep clone, not just a shallow copy.
  376. */
  377. public function __clone() {
  378. foreach($this as $key => $val) {
  379. if (is_object($val) || (is_array($val))) {
  380. $this->{$key} = unserialize(serialize($val));
  381. }
  382. }
  383. }
  384. /**
  385. * Get the workbook collection of cellXfs
  386. *
  387. * @return PHPExcel_Style[]
  388. */
  389. public function getCellXfCollection()
  390. {
  391. return $this->_cellXfCollection;
  392. }
  393. /**
  394. * Get cellXf by index
  395. *
  396. * @param int $index
  397. * @return PHPExcel_Style
  398. */
  399. public function getCellXfByIndex($pIndex = 0)
  400. {
  401. return $this->_cellXfCollection[$pIndex];
  402. }
  403. /**
  404. * Get cellXf by hash code
  405. *
  406. * @param string $pValue
  407. * @return PHPExcel_Style|false
  408. */
  409. public function getCellXfByHashCode($pValue = '')
  410. {
  411. foreach ($this->_cellXfCollection as $cellXf) {
  412. if ($cellXf->getHashCode() == $pValue) {
  413. return $cellXf;
  414. }
  415. }
  416. return false;
  417. }
  418. /**
  419. * Get default style
  420. *
  421. * @return PHPExcel_Style
  422. * @throws Exception
  423. */
  424. public function getDefaultStyle()
  425. {
  426. if (isset($this->_cellXfCollection[0])) {
  427. return $this->_cellXfCollection[0];
  428. }
  429. throw new Exception('No default style found for this workbook');
  430. }
  431. /**
  432. * Add a cellXf to the workbook
  433. *
  434. * @param PHPExcel_Style
  435. */
  436. public function addCellXf(PHPExcel_Style $style)
  437. {
  438. $this->_cellXfCollection[] = $style;
  439. $style->setIndex(count($this->_cellXfCollection) - 1);
  440. }
  441. /**
  442. * Remove cellXf by index. It is ensured that all cells get their xf index updated.
  443. *
  444. * @param int $pIndex Index to cellXf
  445. * @throws Exception
  446. */
  447. public function removeCellXfByIndex($pIndex = 0)
  448. {
  449. if ($pIndex > count($this->_cellXfCollection) - 1) {
  450. throw new Exception("CellXf index is out of bounds.");
  451. } else {
  452. // first remove the cellXf
  453. array_splice($this->_cellXfCollection, $pIndex, 1);
  454. // then update cellXf indexes for cells
  455. foreach ($this->_workSheetCollection as $worksheet) {
  456. foreach ($worksheet->getCellCollection(false) as $cell) {
  457. $xfIndex = $cell->getXfIndex();
  458. if ($xfIndex > $pIndex ) {
  459. // decrease xf index by 1
  460. $cell->setXfIndex($xfIndex - 1);
  461. } else if ($xfIndex == $pIndex) {
  462. // set to default xf index 0
  463. $cell->setXfIndex(0);
  464. }
  465. }
  466. }
  467. }
  468. }
  469. /**
  470. * Get the cellXf supervisor
  471. *
  472. * @return PHPExcel_Style
  473. */
  474. public function getCellXfSupervisor()
  475. {
  476. return $this->_cellXfSupervisor;
  477. }
  478. /**
  479. * Get the workbook collection of cellStyleXfs
  480. *
  481. * @return PHPExcel_Style[]
  482. */
  483. public function getCellStyleXfCollection()
  484. {
  485. return $this->_cellStyleXfCollection;
  486. }
  487. /**
  488. * Get cellStyleXf by index
  489. *
  490. * @param int $pIndex
  491. * @return PHPExcel_Style
  492. */
  493. public function getCellStyleXfByIndex($pIndex = 0)
  494. {
  495. return $this->_cellStyleXfCollection[$pIndex];
  496. }
  497. /**
  498. * Get cellStyleXf by hash code
  499. *
  500. * @param string $pValue
  501. * @return PHPExcel_Style|false
  502. */
  503. public function getCellStyleXfByHashCode($pValue = '')
  504. {
  505. foreach ($this->_cellXfStyleCollection as $cellStyleXf) {
  506. if ($cellStyleXf->getHashCode() == $pValue) {
  507. return $cellStyleXf;
  508. }
  509. }
  510. return false;
  511. }
  512. /**
  513. * Add a cellStyleXf to the workbook
  514. *
  515. * @param PHPExcel_Style $pStyle
  516. */
  517. public function addCellStyleXf(PHPExcel_Style $pStyle)
  518. {
  519. $this->_cellStyleXfCollection[] = $pStyle;
  520. $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1);
  521. }
  522. /**
  523. * Remove cellStyleXf by index
  524. *
  525. * @param int $pIndex
  526. * @throws Exception
  527. */
  528. public function removeCellStyleXfByIndex($pIndex = 0)
  529. {
  530. if ($pIndex > count($this->_cellStyleXfCollection) - 1) {
  531. throw new Exception("CellStyleXf index is out of bounds.");
  532. } else {
  533. array_splice($this->_cellStyleXfCollection, $pIndex, 1);
  534. }
  535. }
  536. /**
  537. * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells in the workbook
  538. */
  539. public function garbageCollect()
  540. {
  541. // how many references are there to each cellXf ?
  542. $countReferencesCellXf = array();
  543. foreach ($this->_cellXfCollection as $index => $cellXf) {
  544. $countReferencesCellXf[$index] = 0;
  545. }
  546. foreach ($this->getWorksheetIterator() as $sheet) {
  547. foreach ($sheet->getCellCollection(false) as $cell) {
  548. ++$countReferencesCellXf[$cell->getXfIndex()];
  549. }
  550. }
  551. // remove those cellXfs that have zero references and create mapping so we can update xfIndex for all cells
  552. $countNeededCellXfs = 0;
  553. foreach ($this->_cellXfCollection as $index => $cellXf) {
  554. if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
  555. ++$countNeededCellXfs;
  556. } else {
  557. unset($this->_cellXfCollection[$index]);
  558. }
  559. $map[$index] = $countNeededCellXfs - 1;
  560. }
  561. $this->_cellXfCollection = array_values($this->_cellXfCollection);
  562. // update the xfIndex for all cells
  563. foreach ($this->getWorksheetIterator() as $sheet) {
  564. foreach ($sheet->getCellCollection(false) as $cell) {
  565. $cell->setXfIndex( $map[$cell->getXfIndex()] );
  566. }
  567. }
  568. // also do garbage collection for all the sheets
  569. foreach ($this->getWorksheetIterator() as $sheet) {
  570. $sheet->garbageCollect();
  571. }
  572. }
  573. }