/branches/v1.7.3/Classes/PHPExcel/Writer/Excel2007/Worksheet.php

# · PHP · 1095 lines · 631 code · 153 blank · 311 comment · 160 complexity · 89acb85bb07281aeed48047a1df73977 MD5 · raw file

  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2010 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_Writer_Excel2007
  23. * @copyright Copyright (c) 2006 - 2010 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. /**
  28. * PHPExcel_Writer_Excel2007_Worksheet
  29. *
  30. * @category PHPExcel
  31. * @package PHPExcel_Writer_Excel2007
  32. * @copyright Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  33. */
  34. class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart
  35. {
  36. /**
  37. * Write worksheet to XML format
  38. *
  39. * @param PHPExcel_Worksheet $pSheet
  40. * @param string[] $pStringTable
  41. * @return string XML Output
  42. * @throws Exception
  43. */
  44. public function writeWorksheet($pSheet = null, $pStringTable = null)
  45. {
  46. if (!is_null($pSheet)) {
  47. // Create XML writer
  48. $objWriter = null;
  49. if ($this->getParentWriter()->getUseDiskCaching()) {
  50. $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
  51. } else {
  52. $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
  53. }
  54. // XML header
  55. $objWriter->startDocument('1.0','UTF-8','yes');
  56. // Worksheet
  57. $objWriter->startElement('worksheet');
  58. $objWriter->writeAttribute('xml:space', 'preserve');
  59. $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
  60. $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
  61. // sheetPr
  62. $this->_writeSheetPr($objWriter, $pSheet);
  63. // Dimension
  64. $this->_writeDimension($objWriter, $pSheet);
  65. // sheetViews
  66. $this->_writeSheetViews($objWriter, $pSheet);
  67. // sheetFormatPr
  68. $this->_writeSheetFormatPr($objWriter, $pSheet);
  69. // cols
  70. $this->_writeCols($objWriter, $pSheet);
  71. // sheetData
  72. $this->_writeSheetData($objWriter, $pSheet, $pStringTable);
  73. // sheetProtection
  74. $this->_writeSheetProtection($objWriter, $pSheet);
  75. // protectedRanges
  76. $this->_writeProtectedRanges($objWriter, $pSheet);
  77. // autoFilter
  78. $this->_writeAutoFilter($objWriter, $pSheet);
  79. // mergeCells
  80. $this->_writeMergeCells($objWriter, $pSheet);
  81. // conditionalFormatting
  82. $this->_writeConditionalFormatting($objWriter, $pSheet);
  83. // dataValidations
  84. $this->_writeDataValidations($objWriter, $pSheet);
  85. // hyperlinks
  86. $this->_writeHyperlinks($objWriter, $pSheet);
  87. // Print options
  88. $this->_writePrintOptions($objWriter, $pSheet);
  89. // Page margins
  90. $this->_writePageMargins($objWriter, $pSheet);
  91. // Page setup
  92. $this->_writePageSetup($objWriter, $pSheet);
  93. // Header / footer
  94. $this->_writeHeaderFooter($objWriter, $pSheet);
  95. // Breaks
  96. $this->_writeBreaks($objWriter, $pSheet);
  97. // Drawings
  98. $this->_writeDrawings($objWriter, $pSheet);
  99. // LegacyDrawing
  100. $this->_writeLegacyDrawing($objWriter, $pSheet);
  101. // LegacyDrawingHF
  102. $this->_writeLegacyDrawingHF($objWriter, $pSheet);
  103. $objWriter->endElement();
  104. // Return
  105. return $objWriter->getData();
  106. } else {
  107. throw new Exception("Invalid PHPExcel_Worksheet object passed.");
  108. }
  109. }
  110. /**
  111. * Write SheetPr
  112. *
  113. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  114. * @param PHPExcel_Worksheet $pSheet Worksheet
  115. * @throws Exception
  116. */
  117. private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  118. {
  119. // sheetPr
  120. $objWriter->startElement('sheetPr');
  121. //$objWriter->writeAttribute('codeName', $pSheet->getTitle());
  122. // tabColor
  123. if ($pSheet->isTabColorSet()) {
  124. $objWriter->startElement('tabColor');
  125. $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
  126. $objWriter->endElement();
  127. }
  128. // outlinePr
  129. $objWriter->startElement('outlinePr');
  130. $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
  131. $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
  132. $objWriter->endElement();
  133. // pageSetUpPr
  134. if ($pSheet->getPageSetup()->getFitToPage()) {
  135. $objWriter->startElement('pageSetUpPr');
  136. $objWriter->writeAttribute('fitToPage', '1');
  137. $objWriter->endElement();
  138. }
  139. $objWriter->endElement();
  140. }
  141. /**
  142. * Write Dimension
  143. *
  144. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  145. * @param PHPExcel_Worksheet $pSheet Worksheet
  146. * @throws Exception
  147. */
  148. private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  149. {
  150. // dimension
  151. $objWriter->startElement('dimension');
  152. $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
  153. $objWriter->endElement();
  154. }
  155. /**
  156. * Write SheetViews
  157. *
  158. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  159. * @param PHPExcel_Worksheet $pSheet Worksheet
  160. * @throws Exception
  161. */
  162. private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  163. {
  164. // sheetViews
  165. $objWriter->startElement('sheetViews');
  166. // Sheet selected?
  167. $sheetSelected = false;
  168. if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex())
  169. $sheetSelected = true;
  170. // sheetView
  171. $objWriter->startElement('sheetView');
  172. $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
  173. $objWriter->writeAttribute('workbookViewId', '0');
  174. // Zoom scales
  175. if ($pSheet->getSheetView()->getZoomScale() != 100) {
  176. $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
  177. }
  178. if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
  179. $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
  180. }
  181. // Gridlines
  182. if ($pSheet->getShowGridlines()) {
  183. $objWriter->writeAttribute('showGridLines', 'true');
  184. } else {
  185. $objWriter->writeAttribute('showGridLines', 'false');
  186. }
  187. // Row and column headers
  188. if ($pSheet->getShowRowColHeaders()) {
  189. $objWriter->writeAttribute('showRowColHeaders', '1');
  190. } else {
  191. $objWriter->writeAttribute('showRowColHeaders', '0');
  192. }
  193. // Right-to-left
  194. if ($pSheet->getRightToLeft()) {
  195. $objWriter->writeAttribute('rightToLeft', 'true');
  196. }
  197. // Pane
  198. if ($pSheet->getFreezePane() != '') {
  199. // Calculate freeze coordinates
  200. $xSplit = 0;
  201. $ySplit = 0;
  202. $topLeftCell = $pSheet->getFreezePane();
  203. list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($pSheet->getFreezePane());
  204. $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit);
  205. // pane
  206. $objWriter->startElement('pane');
  207. $objWriter->writeAttribute('xSplit', $xSplit - 1);
  208. $objWriter->writeAttribute('ySplit', $ySplit - 1);
  209. $objWriter->writeAttribute('topLeftCell', $topLeftCell);
  210. $objWriter->writeAttribute('activePane', 'bottomRight');
  211. $objWriter->writeAttribute('state', 'frozen');
  212. $objWriter->endElement();
  213. }
  214. // Selection
  215. $objWriter->startElement('selection');
  216. $objWriter->writeAttribute('activeCell', $pSheet->getActiveCell());
  217. $objWriter->writeAttribute('sqref', $pSheet->getSelectedCells());
  218. $objWriter->endElement();
  219. $objWriter->endElement();
  220. $objWriter->endElement();
  221. }
  222. /**
  223. * Write SheetFormatPr
  224. *
  225. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  226. * @param PHPExcel_Worksheet $pSheet Worksheet
  227. * @throws Exception
  228. */
  229. private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  230. {
  231. // sheetFormatPr
  232. $objWriter->startElement('sheetFormatPr');
  233. // Default row height
  234. if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
  235. $objWriter->writeAttribute('customHeight', 'true');
  236. $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
  237. } else {
  238. $objWriter->writeAttribute('defaultRowHeight', '12.75');
  239. }
  240. // Default column width
  241. if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
  242. $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
  243. }
  244. // Outline level - row
  245. $outlineLevelRow = 0;
  246. foreach ($pSheet->getRowDimensions() as $dimension) {
  247. if ($dimension->getOutlineLevel() > $outlineLevelRow) {
  248. $outlineLevelRow = $dimension->getOutlineLevel();
  249. }
  250. }
  251. $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow);
  252. // Outline level - column
  253. $outlineLevelCol = 0;
  254. foreach ($pSheet->getColumnDimensions() as $dimension) {
  255. if ($dimension->getOutlineLevel() > $outlineLevelCol) {
  256. $outlineLevelCol = $dimension->getOutlineLevel();
  257. }
  258. }
  259. $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol);
  260. $objWriter->endElement();
  261. }
  262. /**
  263. * Write Cols
  264. *
  265. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  266. * @param PHPExcel_Worksheet $pSheet Worksheet
  267. * @throws Exception
  268. */
  269. private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  270. {
  271. // cols
  272. if (count($pSheet->getColumnDimensions()) > 0) {
  273. $objWriter->startElement('cols');
  274. $pSheet->calculateColumnWidths();
  275. // Loop through column dimensions
  276. foreach ($pSheet->getColumnDimensions() as $colDimension) {
  277. // col
  278. $objWriter->startElement('col');
  279. $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex()));
  280. $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex()));
  281. if ($colDimension->getWidth() < 0) {
  282. // No width set, apply default of 10
  283. $objWriter->writeAttribute('width', '9.10');
  284. } else {
  285. // Width set
  286. $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth()));
  287. }
  288. // Column visibility
  289. if ($colDimension->getVisible() == false) {
  290. $objWriter->writeAttribute('hidden', 'true');
  291. }
  292. // Auto size?
  293. if ($colDimension->getAutoSize()) {
  294. $objWriter->writeAttribute('bestFit', 'true');
  295. }
  296. // Custom width?
  297. if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
  298. $objWriter->writeAttribute('customWidth', 'true');
  299. }
  300. // Collapsed
  301. if ($colDimension->getCollapsed() == true) {
  302. $objWriter->writeAttribute('collapsed', 'true');
  303. }
  304. // Outline level
  305. if ($colDimension->getOutlineLevel() > 0) {
  306. $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
  307. }
  308. // Style
  309. $objWriter->writeAttribute('style', $colDimension->getXfIndex());
  310. $objWriter->endElement();
  311. }
  312. $objWriter->endElement();
  313. }
  314. }
  315. /**
  316. * Write SheetProtection
  317. *
  318. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  319. * @param PHPExcel_Worksheet $pSheet Worksheet
  320. * @throws Exception
  321. */
  322. private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  323. {
  324. // sheetProtection
  325. $objWriter->startElement('sheetProtection');
  326. if ($pSheet->getProtection()->getPassword() != '') {
  327. $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
  328. }
  329. $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
  330. $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
  331. $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
  332. $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
  333. $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
  334. $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
  335. $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
  336. $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
  337. $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
  338. $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
  339. $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
  340. $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
  341. $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
  342. $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
  343. $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
  344. $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
  345. $objWriter->endElement();
  346. }
  347. /**
  348. * Write ConditionalFormatting
  349. *
  350. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  351. * @param PHPExcel_Worksheet $pSheet Worksheet
  352. * @throws Exception
  353. */
  354. private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  355. {
  356. // Conditional id
  357. $id = 1;
  358. // Loop through styles in the current worksheet
  359. foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
  360. foreach ($conditionalStyles as $conditional) {
  361. // WHY was this again?
  362. // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') {
  363. // continue;
  364. // }
  365. if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) {
  366. // conditionalFormatting
  367. $objWriter->startElement('conditionalFormatting');
  368. $objWriter->writeAttribute('sqref', $cellCoordinate);
  369. // cfRule
  370. $objWriter->startElement('cfRule');
  371. $objWriter->writeAttribute('type', $conditional->getConditionType());
  372. $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ));
  373. $objWriter->writeAttribute('priority', $id++);
  374. if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS
  375. ||
  376. $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT)
  377. && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) {
  378. $objWriter->writeAttribute('operator', $conditional->getOperatorType());
  379. }
  380. if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  381. && !is_null($conditional->getText())) {
  382. $objWriter->writeAttribute('text', $conditional->getText());
  383. }
  384. if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  385. && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT
  386. && !is_null($conditional->getText())) {
  387. $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
  388. } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  389. && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH
  390. && !is_null($conditional->getText())) {
  391. $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
  392. } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  393. && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH
  394. && !is_null($conditional->getText())) {
  395. $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
  396. } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  397. && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS
  398. && !is_null($conditional->getText())) {
  399. $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
  400. } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS
  401. || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  402. || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) {
  403. foreach ($conditional->getConditions() as $formula) {
  404. // Formula
  405. $objWriter->writeElement('formula', $formula);
  406. }
  407. }
  408. $objWriter->endElement();
  409. $objWriter->endElement();
  410. }
  411. }
  412. }
  413. }
  414. /**
  415. * Write DataValidations
  416. *
  417. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  418. * @param PHPExcel_Worksheet $pSheet Worksheet
  419. * @throws Exception
  420. */
  421. private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  422. {
  423. // Datavalidation collection
  424. $dataValidationCollection = $pSheet->getDataValidationCollection();
  425. // Write data validations?
  426. if (count($dataValidationCollection) > 0) {
  427. $objWriter->startElement('dataValidations');
  428. $objWriter->writeAttribute('count', count($dataValidationCollection));
  429. foreach ($dataValidationCollection as $coordinate => $dv) {
  430. $objWriter->startElement('dataValidation');
  431. if ($dv->getType() != '') {
  432. $objWriter->writeAttribute('type', $dv->getType());
  433. }
  434. if ($dv->getErrorStyle() != '') {
  435. $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
  436. }
  437. if ($dv->getOperator() != '') {
  438. $objWriter->writeAttribute('operator', $dv->getOperator());
  439. }
  440. $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
  441. $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
  442. $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
  443. $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
  444. if ($dv->getErrorTitle() !== '') {
  445. $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
  446. }
  447. if ($dv->getError() !== '') {
  448. $objWriter->writeAttribute('error', $dv->getError());
  449. }
  450. if ($dv->getPromptTitle() !== '') {
  451. $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
  452. }
  453. if ($dv->getPrompt() !== '') {
  454. $objWriter->writeAttribute('prompt', $dv->getPrompt());
  455. }
  456. $objWriter->writeAttribute('sqref', $coordinate);
  457. if ($dv->getFormula1() !== '') {
  458. $objWriter->writeElement('formula1', $dv->getFormula1());
  459. }
  460. if ($dv->getFormula2() !== '') {
  461. $objWriter->writeElement('formula2', $dv->getFormula2());
  462. }
  463. $objWriter->endElement();
  464. }
  465. $objWriter->endElement();
  466. }
  467. }
  468. /**
  469. * Write Hyperlinks
  470. *
  471. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  472. * @param PHPExcel_Worksheet $pSheet Worksheet
  473. * @throws Exception
  474. */
  475. private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  476. {
  477. // Hyperlink collection
  478. $hyperlinkCollection = $pSheet->getHyperlinkCollection();
  479. // Relation ID
  480. $relationId = 1;
  481. // Write hyperlinks?
  482. if (count($hyperlinkCollection) > 0) {
  483. $objWriter->startElement('hyperlinks');
  484. foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
  485. $objWriter->startElement('hyperlink');
  486. $objWriter->writeAttribute('ref', $coordinate);
  487. if (!$hyperlink->isInternal()) {
  488. $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
  489. ++$relationId;
  490. } else {
  491. $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
  492. }
  493. if ($hyperlink->getTooltip() != '') {
  494. $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
  495. }
  496. $objWriter->endElement();
  497. }
  498. $objWriter->endElement();
  499. }
  500. }
  501. /**
  502. * Write ProtectedRanges
  503. *
  504. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  505. * @param PHPExcel_Worksheet $pSheet Worksheet
  506. * @throws Exception
  507. */
  508. private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  509. {
  510. if (count($pSheet->getProtectedCells()) > 0) {
  511. // protectedRanges
  512. $objWriter->startElement('protectedRanges');
  513. // Loop protectedRanges
  514. foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
  515. // protectedRange
  516. $objWriter->startElement('protectedRange');
  517. $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
  518. $objWriter->writeAttribute('sqref', $protectedCell);
  519. $objWriter->writeAttribute('password', $passwordHash);
  520. $objWriter->endElement();
  521. }
  522. $objWriter->endElement();
  523. }
  524. }
  525. /**
  526. * Write MergeCells
  527. *
  528. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  529. * @param PHPExcel_Worksheet $pSheet Worksheet
  530. * @throws Exception
  531. */
  532. private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  533. {
  534. if (count($pSheet->getMergeCells()) > 0) {
  535. // mergeCells
  536. $objWriter->startElement('mergeCells');
  537. // Loop mergeCells
  538. foreach ($pSheet->getMergeCells() as $mergeCell) {
  539. // mergeCell
  540. $objWriter->startElement('mergeCell');
  541. $objWriter->writeAttribute('ref', $mergeCell);
  542. $objWriter->endElement();
  543. }
  544. $objWriter->endElement();
  545. }
  546. }
  547. /**
  548. * Write PrintOptions
  549. *
  550. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  551. * @param PHPExcel_Worksheet $pSheet Worksheet
  552. * @throws Exception
  553. */
  554. private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  555. {
  556. // printOptions
  557. $objWriter->startElement('printOptions');
  558. $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false'));
  559. $objWriter->writeAttribute('gridLinesSet', 'true');
  560. if ($pSheet->getPageSetup()->getHorizontalCentered()) {
  561. $objWriter->writeAttribute('horizontalCentered', 'true');
  562. }
  563. if ($pSheet->getPageSetup()->getVerticalCentered()) {
  564. $objWriter->writeAttribute('verticalCentered', 'true');
  565. }
  566. $objWriter->endElement();
  567. }
  568. /**
  569. * Write PageMargins
  570. *
  571. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  572. * @param PHPExcel_Worksheet $pSheet Worksheet
  573. * @throws Exception
  574. */
  575. private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  576. {
  577. // pageMargins
  578. $objWriter->startElement('pageMargins');
  579. $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()));
  580. $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()));
  581. $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()));
  582. $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()));
  583. $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader()));
  584. $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter()));
  585. $objWriter->endElement();
  586. }
  587. /**
  588. * Write AutoFilter
  589. *
  590. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  591. * @param PHPExcel_Worksheet $pSheet Worksheet
  592. * @throws Exception
  593. */
  594. private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  595. {
  596. if ($pSheet->getAutoFilter() != '') {
  597. // autoFilter
  598. $objWriter->startElement('autoFilter');
  599. $objWriter->writeAttribute('ref', $pSheet->getAutoFilter());
  600. $objWriter->endElement();
  601. }
  602. }
  603. /**
  604. * Write PageSetup
  605. *
  606. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  607. * @param PHPExcel_Worksheet $pSheet Worksheet
  608. * @throws Exception
  609. */
  610. private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  611. {
  612. // pageSetup
  613. $objWriter->startElement('pageSetup');
  614. $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
  615. $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
  616. if (!is_null($pSheet->getPageSetup()->getScale())) {
  617. $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
  618. }
  619. if (!is_null($pSheet->getPageSetup()->getFitToHeight())) {
  620. $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
  621. } else {
  622. $objWriter->writeAttribute('fitToHeight', '0');
  623. }
  624. if (!is_null($pSheet->getPageSetup()->getFitToWidth())) {
  625. $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
  626. } else {
  627. $objWriter->writeAttribute('fitToWidth', '0');
  628. }
  629. if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) {
  630. $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
  631. $objWriter->writeAttribute('useFirstPageNumber', '1');
  632. }
  633. $objWriter->endElement();
  634. }
  635. /**
  636. * Write Header / Footer
  637. *
  638. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  639. * @param PHPExcel_Worksheet $pSheet Worksheet
  640. * @throws Exception
  641. */
  642. private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  643. {
  644. // headerFooter
  645. $objWriter->startElement('headerFooter');
  646. $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
  647. $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
  648. $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
  649. $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
  650. $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
  651. $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
  652. $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
  653. $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
  654. $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
  655. $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
  656. $objWriter->endElement();
  657. }
  658. /**
  659. * Write Breaks
  660. *
  661. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  662. * @param PHPExcel_Worksheet $pSheet Worksheet
  663. * @throws Exception
  664. */
  665. private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  666. {
  667. // Get row and column breaks
  668. $aRowBreaks = array();
  669. $aColumnBreaks = array();
  670. foreach ($pSheet->getBreaks() as $cell => $breakType) {
  671. if ($breakType == PHPExcel_Worksheet::BREAK_ROW) {
  672. $aRowBreaks[] = $cell;
  673. } else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) {
  674. $aColumnBreaks[] = $cell;
  675. }
  676. }
  677. // rowBreaks
  678. if (count($aRowBreaks) > 0) {
  679. $objWriter->startElement('rowBreaks');
  680. $objWriter->writeAttribute('count', count($aRowBreaks));
  681. $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
  682. foreach ($aRowBreaks as $cell) {
  683. $coords = PHPExcel_Cell::coordinateFromString($cell);
  684. $objWriter->startElement('brk');
  685. $objWriter->writeAttribute('id', $coords[1]);
  686. $objWriter->writeAttribute('man', '1');
  687. $objWriter->endElement();
  688. }
  689. $objWriter->endElement();
  690. }
  691. // Second, write column breaks
  692. if (count($aColumnBreaks) > 0) {
  693. $objWriter->startElement('colBreaks');
  694. $objWriter->writeAttribute('count', count($aColumnBreaks));
  695. $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
  696. foreach ($aColumnBreaks as $cell) {
  697. $coords = PHPExcel_Cell::coordinateFromString($cell);
  698. $objWriter->startElement('brk');
  699. $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1);
  700. $objWriter->writeAttribute('man', '1');
  701. $objWriter->endElement();
  702. }
  703. $objWriter->endElement();
  704. }
  705. }
  706. /**
  707. * Write SheetData
  708. *
  709. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  710. * @param PHPExcel_Worksheet $pSheet Worksheet
  711. * @param string[] $pStringTable String table
  712. * @throws Exception
  713. */
  714. private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null)
  715. {
  716. if (is_array($pStringTable)) {
  717. // Flipped stringtable, for faster index searching
  718. $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
  719. // sheetData
  720. $objWriter->startElement('sheetData');
  721. // Get column count
  722. $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn());
  723. // Highest row number
  724. $highestRow = $pSheet->getHighestRow();
  725. // Loop through cells
  726. $cellCollection = $pSheet->getCellCollection();
  727. $cellsByRow = array();
  728. foreach ($cellCollection as $cellID) {
  729. $cell = $pSheet->getCell($cellID);
  730. $cellsByRow[$cell->getRow()][] = $cell;
  731. }
  732. for ($currentRow = 1; $currentRow <= $highestRow; ++$currentRow) {
  733. // Get row dimension
  734. $rowDimension = $pSheet->getRowDimension($currentRow);
  735. // Write current row?
  736. $writeCurrentRow = isset($cellsByRow[$currentRow]) ||
  737. $rowDimension->getRowHeight() >= 0 ||
  738. $rowDimension->getVisible() == false ||
  739. $rowDimension->getCollapsed() == true ||
  740. $rowDimension->getOutlineLevel() > 0 ||
  741. $rowDimension->getXfIndex() !== null;
  742. if ($writeCurrentRow) {
  743. // Start a new row
  744. $objWriter->startElement('row');
  745. $objWriter->writeAttribute('r', $currentRow);
  746. $objWriter->writeAttribute('spans', '1:' . $colCount);
  747. // Row dimensions
  748. if ($rowDimension->getRowHeight() >= 0) {
  749. $objWriter->writeAttribute('customHeight', '1');
  750. $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight()));
  751. }
  752. // Row visibility
  753. if ($rowDimension->getVisible() == false) {
  754. $objWriter->writeAttribute('hidden', 'true');
  755. }
  756. // Collapsed
  757. if ($rowDimension->getCollapsed() == true) {
  758. $objWriter->writeAttribute('collapsed', 'true');
  759. }
  760. // Outline level
  761. if ($rowDimension->getOutlineLevel() > 0) {
  762. $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
  763. }
  764. // Style
  765. if ($rowDimension->getXfIndex() !== null) {
  766. $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
  767. $objWriter->writeAttribute('customFormat', '1');
  768. }
  769. // Write cells
  770. if (isset($cellsByRow[$currentRow])) {
  771. foreach($cellsByRow[$currentRow] as $cell) {
  772. // Write cell
  773. $this->_writeCell($objWriter, $pSheet, $cell, $pStringTable, $aFlippedStringTable);
  774. }
  775. }
  776. // End row
  777. $objWriter->endElement();
  778. }
  779. }
  780. $objWriter->endElement();
  781. } else {
  782. throw new Exception("Invalid parameters passed.");
  783. }
  784. }
  785. /**
  786. * Write Cell
  787. *
  788. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  789. * @param PHPExcel_Worksheet $pSheet Worksheet
  790. * @param PHPExcel_Cell $pCell Cell
  791. * @param string[] $pStringTable String table
  792. * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
  793. * @throws Exception
  794. */
  795. private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, PHPExcel_Cell $pCell = null, $pStringTable = null, $pFlippedStringTable = null)
  796. {
  797. $pCell->attach($pSheet);
  798. if (is_array($pStringTable) && is_array($pFlippedStringTable)) {
  799. // Cell
  800. $objWriter->startElement('c');
  801. $objWriter->writeAttribute('r', $pCell->getCoordinate());
  802. // Sheet styles
  803. if ($pCell->getXfIndex() != '') {
  804. $objWriter->writeAttribute('s', $pCell->getXfIndex());
  805. }
  806. // If cell value is supplied, write cell value
  807. if (is_object($pCell->getValue()) || $pCell->getValue() !== '') {
  808. // Map type
  809. $mappedType = $pCell->getDataType();
  810. // Write data type depending on its type
  811. switch (strtolower($mappedType)) {
  812. case 'inlinestr': // Inline string
  813. $objWriter->writeAttribute('t', $mappedType);
  814. break;
  815. case 's': // String
  816. $objWriter->writeAttribute('t', $mappedType);
  817. break;
  818. case 'b': // Boolean
  819. $objWriter->writeAttribute('t', $mappedType);
  820. break;
  821. case 'f': // Formula
  822. $calculatedValue = null;
  823. if ($this->getParentWriter()->getPreCalculateFormulas()) {
  824. $calculatedValue = $pCell->getCalculatedValue();
  825. } else {
  826. $calculatedValue = $pCell->getValue();
  827. }
  828. if (is_string($calculatedValue)) {
  829. $objWriter->writeAttribute('t', 'str');
  830. }
  831. break;
  832. case 'e': // Error
  833. $objWriter->writeAttribute('t', $mappedType);
  834. }
  835. // Write data depending on its type
  836. switch (strtolower($mappedType)) {
  837. case 'inlinestr': // Inline string
  838. if (! $pCell->getValue() instanceof PHPExcel_RichText) {
  839. $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($pCell->getValue()) ) );
  840. } else if ($pCell->getValue() instanceof PHPExcel_RichText) {
  841. $objWriter->startElement('is');
  842. $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pCell->getValue());
  843. $objWriter->endElement();
  844. }
  845. break;
  846. case 's': // String
  847. if (! $pCell->getValue() instanceof PHPExcel_RichText) {
  848. if (isset($pFlippedStringTable[$pCell->getValue()])) {
  849. $objWriter->writeElement('v', $pFlippedStringTable[$pCell->getValue()]);
  850. }
  851. } else if ($pCell->getValue() instanceof PHPExcel_RichText) {
  852. $objWriter->writeElement('v', $pFlippedStringTable[$pCell->getValue()->getHashCode()]);
  853. }
  854. break;
  855. case 'f': // Formula
  856. $objWriter->writeElement('f', substr($pCell->getValue(), 1));
  857. if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
  858. if ($this->getParentWriter()->getPreCalculateFormulas()) {
  859. $calculatedValue = $pCell->getCalculatedValue();
  860. if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
  861. $v = PHPExcel_Shared_String::FormatNumber($calculatedValue);
  862. $objWriter->writeElement('v', $v);
  863. } else {
  864. $objWriter->writeElement('v', '0');
  865. }
  866. } else {
  867. $objWriter->writeElement('v', '0');
  868. }
  869. }
  870. break;
  871. case 'n': // Numeric
  872. // force point as decimal separator in case current locale uses comma
  873. $v = str_replace(',', '.', $pCell->getValue());
  874. $objWriter->writeElement('v', $v);
  875. break;
  876. case 'b': // Boolean
  877. $objWriter->writeElement('v', ($pCell->getValue() ? '1' : '0'));
  878. break;
  879. case 'e': // Error
  880. if (substr($pCell->getValue(), 0, 1) == '=') {
  881. $objWriter->writeElement('f', substr($pCell->getValue(), 1));
  882. $objWriter->writeElement('v', substr($pCell->getValue(), 1));
  883. } else {
  884. $objWriter->writeElement('v', $pCell->getValue());
  885. }
  886. break;
  887. }
  888. }
  889. $objWriter->endElement();
  890. } else {
  891. throw new Exception("Invalid parameters passed.");
  892. }
  893. }
  894. /**
  895. * Write Drawings
  896. *
  897. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  898. * @param PHPExcel_Worksheet $pSheet Worksheet
  899. * @throws Exception
  900. */
  901. private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  902. {
  903. // If sheet contains drawings, add the relationships
  904. if ($pSheet->getDrawingCollection()->count() > 0) {
  905. $objWriter->startElement('drawing');
  906. $objWriter->writeAttribute('r:id', 'rId1');
  907. $objWriter->endElement();
  908. }
  909. }
  910. /**
  911. * Write LegacyDrawing
  912. *
  913. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  914. * @param PHPExcel_Worksheet $pSheet Worksheet
  915. * @throws Exception
  916. */
  917. private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  918. {
  919. // If sheet contains comments, add the relationships
  920. if (count($pSheet->getComments()) > 0) {
  921. $objWriter->startElement('legacyDrawing');
  922. $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
  923. $objWriter->endElement();
  924. }
  925. }
  926. /**
  927. * Write LegacyDrawingHF
  928. *
  929. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  930. * @param PHPExcel_Worksheet $pSheet Worksheet
  931. * @throws Exception
  932. */
  933. private function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
  934. {
  935. // If sheet contains comments, add the relationships
  936. if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
  937. $objWriter->startElement('legacyDrawingHF');
  938. $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
  939. $objWriter->endElement();
  940. }
  941. }
  942. }