Worksheet.php 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2011 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_Worksheet
  23. * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.7.6, 2011-02-27
  26. */
  27. /**
  28. * PHPExcel_Worksheet
  29. *
  30. * @category PHPExcel
  31. * @package PHPExcel_Worksheet
  32. * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  33. */
  34. class PHPExcel_Worksheet implements PHPExcel_IComparable
  35. {
  36. /* Break types */
  37. const BREAK_NONE = 0;
  38. const BREAK_ROW = 1;
  39. const BREAK_COLUMN = 2;
  40. /* Sheet state */
  41. const SHEETSTATE_VISIBLE = 'visible';
  42. const SHEETSTATE_HIDDEN = 'hidden';
  43. const SHEETSTATE_VERYHIDDEN = 'veryHidden';
  44. /**
  45. * Invalid characters in sheet title
  46. *
  47. * @var array
  48. */
  49. private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']');
  50. /**
  51. * Parent spreadsheet
  52. *
  53. * @var PHPExcel
  54. */
  55. private $_parent;
  56. /**
  57. * Cacheable collection of cells
  58. *
  59. * @var PHPExcel_CachedObjectStorage_xxx
  60. */
  61. private $_cellCollection = null;
  62. /**
  63. * Collection of row dimensions
  64. *
  65. * @var PHPExcel_Worksheet_RowDimension[]
  66. */
  67. private $_rowDimensions = array();
  68. /**
  69. * Default row dimension
  70. *
  71. * @var PHPExcel_Worksheet_RowDimension
  72. */
  73. private $_defaultRowDimension = null;
  74. /**
  75. * Collection of column dimensions
  76. *
  77. * @var PHPExcel_Worksheet_ColumnDimension[]
  78. */
  79. private $_columnDimensions = array();
  80. /**
  81. * Default column dimension
  82. *
  83. * @var PHPExcel_Worksheet_ColumnDimension
  84. */
  85. private $_defaultColumnDimension = null;
  86. /**
  87. * Collection of drawings
  88. *
  89. * @var PHPExcel_Worksheet_BaseDrawing[]
  90. */
  91. private $_drawingCollection = null;
  92. /**
  93. * Worksheet title
  94. *
  95. * @var string
  96. */
  97. private $_title;
  98. /**
  99. * Sheet state
  100. *
  101. * @var string
  102. */
  103. private $_sheetState;
  104. /**
  105. * Page setup
  106. *
  107. * @var PHPExcel_Worksheet_PageSetup
  108. */
  109. private $_pageSetup;
  110. /**
  111. * Page margins
  112. *
  113. * @var PHPExcel_Worksheet_PageMargins
  114. */
  115. private $_pageMargins;
  116. /**
  117. * Page header/footer
  118. *
  119. * @var PHPExcel_Worksheet_HeaderFooter
  120. */
  121. private $_headerFooter;
  122. /**
  123. * Sheet view
  124. *
  125. * @var PHPExcel_Worksheet_SheetView
  126. */
  127. private $_sheetView;
  128. /**
  129. * Protection
  130. *
  131. * @var PHPExcel_Worksheet_Protection
  132. */
  133. private $_protection;
  134. /**
  135. * Collection of styles
  136. *
  137. * @var PHPExcel_Style[]
  138. */
  139. private $_styles = array();
  140. /**
  141. * Conditional styles. Indexed by cell coordinate, e.g. 'A1'
  142. *
  143. * @var array
  144. */
  145. private $_conditionalStylesCollection = array();
  146. /**
  147. * Is the current cell collection sorted already?
  148. *
  149. * @var boolean
  150. */
  151. private $_cellCollectionIsSorted = false;
  152. /**
  153. * Collection of breaks
  154. *
  155. * @var array
  156. */
  157. private $_breaks = array();
  158. /**
  159. * Collection of merged cell ranges
  160. *
  161. * @var array
  162. */
  163. private $_mergeCells = array();
  164. /**
  165. * Collection of protected cell ranges
  166. *
  167. * @var array
  168. */
  169. private $_protectedCells = array();
  170. /**
  171. * Autofilter Range
  172. *
  173. * @var string
  174. */
  175. private $_autoFilter = '';
  176. /**
  177. * Freeze pane
  178. *
  179. * @var string
  180. */
  181. private $_freezePane = '';
  182. /**
  183. * Show gridlines?
  184. *
  185. * @var boolean
  186. */
  187. private $_showGridlines = true;
  188. /**
  189. * Print gridlines?
  190. *
  191. * @var boolean
  192. */
  193. private $_printGridlines = false;
  194. /**
  195. * Show row and column headers?
  196. *
  197. * @var boolean
  198. */
  199. private $_showRowColHeaders = true;
  200. /**
  201. * Show summary below? (Row/Column outline)
  202. *
  203. * @var boolean
  204. */
  205. private $_showSummaryBelow = true;
  206. /**
  207. * Show summary right? (Row/Column outline)
  208. *
  209. * @var boolean
  210. */
  211. private $_showSummaryRight = true;
  212. /**
  213. * Collection of comments
  214. *
  215. * @var PHPExcel_Comment[]
  216. */
  217. private $_comments = array();
  218. /**
  219. * Active cell. (Only one!)
  220. *
  221. * @var string
  222. */
  223. private $_activeCell = 'A1';
  224. /**
  225. * Selected cells
  226. *
  227. * @var string
  228. */
  229. private $_selectedCells = 'A1';
  230. /**
  231. * Cached highest column
  232. *
  233. * @var string
  234. */
  235. private $_cachedHighestColumn = 'A';
  236. /**
  237. * Cached highest row
  238. *
  239. * @var int
  240. */
  241. private $_cachedHighestRow = 1;
  242. /**
  243. * Right-to-left?
  244. *
  245. * @var boolean
  246. */
  247. private $_rightToLeft = false;
  248. /**
  249. * Hyperlinks. Indexed by cell coordinate, e.g. 'A1'
  250. *
  251. * @var array
  252. */
  253. private $_hyperlinkCollection = array();
  254. /**
  255. * Data validation objects. Indexed by cell coordinate, e.g. 'A1'
  256. *
  257. * @var array
  258. */
  259. private $_dataValidationCollection = array();
  260. /**
  261. * Tab color
  262. *
  263. * @var PHPExcel_Style_Color
  264. */
  265. private $_tabColor;
  266. /**
  267. * Dirty flag
  268. *
  269. * @var boolean
  270. */
  271. private $_dirty = true;
  272. /**
  273. * Hash
  274. *
  275. * @var string
  276. */
  277. private $_hash = null;
  278. /**
  279. * Create a new worksheet
  280. *
  281. * @param PHPExcel $pParent
  282. * @param string $pTitle
  283. */
  284. public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet')
  285. {
  286. // Set parent and title
  287. $this->_parent = $pParent;
  288. $this->setTitle($pTitle);
  289. $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE);
  290. $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this);
  291. // Set page setup
  292. $this->_pageSetup = new PHPExcel_Worksheet_PageSetup();
  293. // Set page margins
  294. $this->_pageMargins = new PHPExcel_Worksheet_PageMargins();
  295. // Set page header/footer
  296. $this->_headerFooter = new PHPExcel_Worksheet_HeaderFooter();
  297. // Set sheet view
  298. $this->_sheetView = new PHPExcel_Worksheet_SheetView();
  299. // Drawing collection
  300. $this->_drawingCollection = new ArrayObject();
  301. // Protection
  302. $this->_protection = new PHPExcel_Worksheet_Protection();
  303. // Default row dimension
  304. $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null);
  305. // Default column dimension
  306. $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null);
  307. }
  308. public function disconnectCells() {
  309. $this->_cellCollection->unsetWorksheetCells();
  310. $this->_cellCollection = null;
  311. // detach ourself from the workbook, so that it can then delete this worksheet successfully
  312. $this->_parent = null;
  313. }
  314. /**
  315. * Return the cache controller for the cell collection
  316. *
  317. * @return PHPExcel_CachedObjectStorage_xxx
  318. */
  319. public function getCellCacheController() {
  320. return $this->_cellCollection;
  321. } // function getCellCacheController()
  322. /**
  323. * Get array of invalid characters for sheet title
  324. *
  325. * @return array
  326. */
  327. public static function getInvalidCharacters()
  328. {
  329. return self::$_invalidCharacters;
  330. }
  331. /**
  332. * Check sheet title for valid Excel syntax
  333. *
  334. * @param string $pValue The string to check
  335. * @return string The valid string
  336. * @throws Exception
  337. */
  338. private static function _checkSheetTitle($pValue)
  339. {
  340. // Some of the printable ASCII characters are invalid: * : / \ ? [ ]
  341. if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) {
  342. throw new Exception('Invalid character found in sheet title');
  343. }
  344. // Maximum 31 characters allowed for sheet title
  345. if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) {
  346. throw new Exception('Maximum 31 characters allowed in sheet title.');
  347. }
  348. return $pValue;
  349. }
  350. /**
  351. * Get collection of cells
  352. *
  353. * @param boolean $pSorted Also sort the cell collection?
  354. * @return PHPExcel_Cell[]
  355. */
  356. public function getCellCollection($pSorted = true)
  357. {
  358. if ($pSorted) {
  359. // Re-order cell collection
  360. return $this->sortCellCollection();
  361. }
  362. if (!is_null($this->_cellCollection)) {
  363. return $this->_cellCollection->getCellList();
  364. }
  365. return array();
  366. }
  367. /**
  368. * Sort collection of cells
  369. *
  370. * @return PHPExcel_Worksheet
  371. */
  372. public function sortCellCollection()
  373. {
  374. if (!is_null($this->_cellCollection)) {
  375. return $this->_cellCollection->getSortedCellList();
  376. }
  377. return array();
  378. }
  379. /**
  380. * Get collection of row dimensions
  381. *
  382. * @return PHPExcel_Worksheet_RowDimension[]
  383. */
  384. public function getRowDimensions()
  385. {
  386. return $this->_rowDimensions;
  387. }
  388. /**
  389. * Get default row dimension
  390. *
  391. * @return PHPExcel_Worksheet_RowDimension
  392. */
  393. public function getDefaultRowDimension()
  394. {
  395. return $this->_defaultRowDimension;
  396. }
  397. /**
  398. * Get collection of column dimensions
  399. *
  400. * @return PHPExcel_Worksheet_ColumnDimension[]
  401. */
  402. public function getColumnDimensions()
  403. {
  404. return $this->_columnDimensions;
  405. }
  406. /**
  407. * Get default column dimension
  408. *
  409. * @return PHPExcel_Worksheet_ColumnDimension
  410. */
  411. public function getDefaultColumnDimension()
  412. {
  413. return $this->_defaultColumnDimension;
  414. }
  415. /**
  416. * Get collection of drawings
  417. *
  418. * @return PHPExcel_Worksheet_BaseDrawing[]
  419. */
  420. public function getDrawingCollection()
  421. {
  422. return $this->_drawingCollection;
  423. }
  424. /**
  425. * Refresh column dimensions
  426. *
  427. * @return PHPExcel_Worksheet
  428. */
  429. public function refreshColumnDimensions()
  430. {
  431. $currentColumnDimensions = $this->getColumnDimensions();
  432. $newColumnDimensions = array();
  433. foreach ($currentColumnDimensions as $objColumnDimension) {
  434. $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension;
  435. }
  436. $this->_columnDimensions = $newColumnDimensions;
  437. return $this;
  438. }
  439. /**
  440. * Refresh row dimensions
  441. *
  442. * @return PHPExcel_Worksheet
  443. */
  444. public function refreshRowDimensions()
  445. {
  446. $currentRowDimensions = $this->getRowDimensions();
  447. $newRowDimensions = array();
  448. foreach ($currentRowDimensions as $objRowDimension) {
  449. $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension;
  450. }
  451. $this->_rowDimensions = $newRowDimensions;
  452. return $this;
  453. }
  454. /**
  455. * Calculate worksheet dimension
  456. *
  457. * @return string String containing the dimension of this worksheet
  458. */
  459. public function calculateWorksheetDimension()
  460. {
  461. // Return
  462. return 'A1' . ':' . $this->getHighestColumn() . $this->getHighestRow();
  463. }
  464. /**
  465. * Calculate widths for auto-size columns
  466. *
  467. * @param boolean $calculateMergeCells Calculate merge cell width
  468. * @return PHPExcel_Worksheet;
  469. */
  470. public function calculateColumnWidths($calculateMergeCells = false)
  471. {
  472. // initialize $autoSizes array
  473. $autoSizes = array();
  474. foreach ($this->getColumnDimensions() as $colDimension) {
  475. if ($colDimension->getAutoSize()) {
  476. $autoSizes[$colDimension->getColumnIndex()] = -1;
  477. }
  478. }
  479. // There is only something to do if there are some auto-size columns
  480. if (!empty($autoSizes)) {
  481. // build list of cells references that participate in a merge
  482. $isMergeCell = array();
  483. foreach ($this->getMergeCells() as $cells) {
  484. foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) {
  485. $isMergeCell[$cellReference] = true;
  486. }
  487. }
  488. // loop through all cells in the worksheet
  489. foreach ($this->getCellCollection(false) as $cellID) {
  490. $cell = $this->getCell($cellID);
  491. if (isset($autoSizes[$cell->getColumn()])) {
  492. // Determine width if cell does not participate in a merge
  493. if (!isset($isMergeCell[$cell->getCoordinate()])) {
  494. // Calculated value
  495. $cellValue = $cell->getCalculatedValue();
  496. // To formatted string
  497. $cellValue = PHPExcel_Style_NumberFormat::toFormattedString($cellValue, $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode());
  498. $autoSizes[$cell->getColumn()] = max(
  499. (float)$autoSizes[$cell->getColumn()],
  500. (float)PHPExcel_Shared_Font::calculateColumnWidth(
  501. $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
  502. $cellValue,
  503. $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
  504. $this->getDefaultStyle()->getFont()
  505. )
  506. );
  507. }
  508. }
  509. }
  510. // adjust column widths
  511. foreach ($autoSizes as $columnIndex => $width) {
  512. if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth();
  513. $this->getColumnDimension($columnIndex)->setWidth($width);
  514. }
  515. }
  516. return $this;
  517. }
  518. /**
  519. * Get parent
  520. *
  521. * @return PHPExcel
  522. */
  523. public function getParent() {
  524. return $this->_parent;
  525. }
  526. /**
  527. * Re-bind parent
  528. *
  529. * @param PHPExcel $parent
  530. * @return PHPExcel_Worksheet
  531. */
  532. public function rebindParent(PHPExcel $parent) {
  533. $namedRanges = $this->_parent->getNamedRanges();
  534. foreach ($namedRanges as $namedRange) {
  535. $parent->addNamedRange($namedRange);
  536. }
  537. $this->_parent->removeSheetByIndex(
  538. $this->_parent->getIndex($this)
  539. );
  540. $this->_parent = $parent;
  541. return $this;
  542. }
  543. /**
  544. * Get title
  545. *
  546. * @return string
  547. */
  548. public function getTitle()
  549. {
  550. return $this->_title;
  551. }
  552. /**
  553. * Set title
  554. *
  555. * @param string $pValue String containing the dimension of this worksheet
  556. * @return PHPExcel_Worksheet
  557. */
  558. public function setTitle($pValue = 'Worksheet')
  559. {
  560. // Is this a 'rename' or not?
  561. if ($this->getTitle() == $pValue) {
  562. return $this;
  563. }
  564. // Syntax check
  565. self::_checkSheetTitle($pValue);
  566. // Old title
  567. $oldTitle = $this->getTitle();
  568. // Is there already such sheet name?
  569. if ($this->getParent()->getSheetByName($pValue)) {
  570. // Use name, but append with lowest possible integer
  571. if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) {
  572. $pValue = PHPExcel_Shared_String::Substring($pValue,0,29);
  573. }
  574. $i = 1;
  575. while ($this->getParent()->getSheetByName($pValue . ' ' . $i)) {
  576. ++$i;
  577. if ($i == 10) {
  578. if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) {
  579. $pValue = PHPExcel_Shared_String::Substring($pValue,0,28);
  580. }
  581. } elseif ($i == 100) {
  582. if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) {
  583. $pValue = PHPExcel_Shared_String::Substring($pValue,0,27);
  584. }
  585. }
  586. }
  587. $altTitle = $pValue . ' ' . $i;
  588. return $this->setTitle($altTitle);
  589. }
  590. // Set title
  591. $this->_title = $pValue;
  592. $this->_dirty = true;
  593. // New title
  594. $newTitle = $this->getTitle();
  595. PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->getParent(), $oldTitle, $newTitle);
  596. return $this;
  597. }
  598. /**
  599. * Get sheet state
  600. *
  601. * @return string Sheet state (visible, hidden, veryHidden)
  602. */
  603. public function getSheetState() {
  604. return $this->_sheetState;
  605. }
  606. /**
  607. * Set sheet state
  608. *
  609. * @param string $value Sheet state (visible, hidden, veryHidden)
  610. * @return PHPExcel_Worksheet
  611. */
  612. public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) {
  613. $this->_sheetState = $value;
  614. return $this;
  615. }
  616. /**
  617. * Get page setup
  618. *
  619. * @return PHPExcel_Worksheet_PageSetup
  620. */
  621. public function getPageSetup()
  622. {
  623. return $this->_pageSetup;
  624. }
  625. /**
  626. * Set page setup
  627. *
  628. * @param PHPExcel_Worksheet_PageSetup $pValue
  629. * @return PHPExcel_Worksheet
  630. */
  631. public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue)
  632. {
  633. $this->_pageSetup = $pValue;
  634. return $this;
  635. }
  636. /**
  637. * Get page margins
  638. *
  639. * @return PHPExcel_Worksheet_PageMargins
  640. */
  641. public function getPageMargins()
  642. {
  643. return $this->_pageMargins;
  644. }
  645. /**
  646. * Set page margins
  647. *
  648. * @param PHPExcel_Worksheet_PageMargins $pValue
  649. * @return PHPExcel_Worksheet
  650. */
  651. public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue)
  652. {
  653. $this->_pageMargins = $pValue;
  654. return $this;
  655. }
  656. /**
  657. * Get page header/footer
  658. *
  659. * @return PHPExcel_Worksheet_HeaderFooter
  660. */
  661. public function getHeaderFooter()
  662. {
  663. return $this->_headerFooter;
  664. }
  665. /**
  666. * Set page header/footer
  667. *
  668. * @param PHPExcel_Worksheet_HeaderFooter $pValue
  669. * @return PHPExcel_Worksheet
  670. */
  671. public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue)
  672. {
  673. $this->_headerFooter = $pValue;
  674. return $this;
  675. }
  676. /**
  677. * Get sheet view
  678. *
  679. * @return PHPExcel_Worksheet_HeaderFooter
  680. */
  681. public function getSheetView()
  682. {
  683. return $this->_sheetView;
  684. }
  685. /**
  686. * Set sheet view
  687. *
  688. * @param PHPExcel_Worksheet_SheetView $pValue
  689. * @return PHPExcel_Worksheet
  690. */
  691. public function setSheetView(PHPExcel_Worksheet_SheetView $pValue)
  692. {
  693. $this->_sheetView = $pValue;
  694. return $this;
  695. }
  696. /**
  697. * Get Protection
  698. *
  699. * @return PHPExcel_Worksheet_Protection
  700. */
  701. public function getProtection()
  702. {
  703. return $this->_protection;
  704. }
  705. /**
  706. * Set Protection
  707. *
  708. * @param PHPExcel_Worksheet_Protection $pValue
  709. * @return PHPExcel_Worksheet
  710. */
  711. public function setProtection(PHPExcel_Worksheet_Protection $pValue)
  712. {
  713. $this->_protection = $pValue;
  714. $this->_dirty = true;
  715. return $this;
  716. }
  717. /**
  718. * Get highest worksheet column
  719. *
  720. * @return string Highest column name
  721. */
  722. public function getHighestColumn()
  723. {
  724. return $this->_cachedHighestColumn;
  725. }
  726. /**
  727. * Get highest worksheet row
  728. *
  729. * @return int Highest row number
  730. */
  731. public function getHighestRow()
  732. {
  733. return $this->_cachedHighestRow;
  734. }
  735. /**
  736. * Set a cell value
  737. *
  738. * @param string $pCoordinate Coordinate of the cell
  739. * @param mixed $pValue Value of the cell
  740. * @param bool $returnCell Return the worksheet (false, default) or the cell (true)
  741. * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified
  742. */
  743. public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false)
  744. {
  745. $cell = $this->getCell($pCoordinate);
  746. $cell->setValue($pValue);
  747. if ($returnCell) {
  748. return $cell;
  749. }
  750. return $this;
  751. }
  752. /**
  753. * Set a cell value by using numeric cell coordinates
  754. *
  755. * @param string $pColumn Numeric column coordinate of the cell
  756. * @param string $pRow Numeric row coordinate of the cell
  757. * @param mixed $pValue Value of the cell
  758. * @param bool $returnCell Return the worksheet (false, default) or the cell (true)
  759. * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified
  760. */
  761. public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false)
  762. {
  763. $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
  764. $cell->setValue($pValue);
  765. if ($returnCell) {
  766. return $cell;
  767. }
  768. return $this;
  769. }
  770. /**
  771. * Set a cell value
  772. *
  773. * @param string $pCoordinate Coordinate of the cell
  774. * @param mixed $pValue Value of the cell
  775. * @param string $pDataType Explicit data type
  776. * @return PHPExcel_Worksheet
  777. */
  778. public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
  779. {
  780. // Set value
  781. $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType);
  782. return $this;
  783. }
  784. /**
  785. * Set a cell value by using numeric cell coordinates
  786. *
  787. * @param string $pColumn Numeric column coordinate of the cell
  788. * @param string $pRow Numeric row coordinate of the cell
  789. * @param mixed $pValue Value of the cell
  790. * @param string $pDataType Explicit data type
  791. * @return PHPExcel_Worksheet
  792. */
  793. public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
  794. {
  795. return $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType);
  796. }
  797. /**
  798. * Get cell at a specific coordinate
  799. *
  800. * @param string $pCoordinate Coordinate of the cell
  801. * @throws Exception
  802. * @return PHPExcel_Cell Cell that was found
  803. */
  804. public function getCell($pCoordinate = 'A1')
  805. {
  806. // Check cell collection
  807. if ($this->_cellCollection->isDataSet($pCoordinate)) {
  808. return $this->_cellCollection->getCacheData($pCoordinate);
  809. }
  810. // Worksheet reference?
  811. if (strpos($pCoordinate, '!') !== false) {
  812. $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
  813. return $this->getParent()->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]);
  814. }
  815. // Named range?
  816. if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
  817. (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
  818. $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
  819. if (!is_null($namedRange)) {
  820. $pCoordinate = $namedRange->getRange();
  821. return $namedRange->getWorksheet()->getCell($pCoordinate);
  822. }
  823. }
  824. // Uppercase coordinate
  825. $pCoordinate = strtoupper($pCoordinate);
  826. if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {
  827. throw new Exception('Cell coordinate can not be a range of cells.');
  828. } elseif (strpos($pCoordinate,'$') !== false) {
  829. throw new Exception('Cell coordinate must not be absolute.');
  830. } else {
  831. // Create new cell object
  832. // Coordinates
  833. $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
  834. $cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell($aCoordinates[0], $aCoordinates[1], null, PHPExcel_Cell_DataType::TYPE_NULL, $this));
  835. $this->_cellCollectionIsSorted = false;
  836. if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0]))
  837. $this->_cachedHighestColumn = $aCoordinates[0];
  838. $this->_cachedHighestRow = max($this->_cachedHighestRow,$aCoordinates[1]);
  839. // Cell needs appropriate xfIndex
  840. $rowDimensions = $this->getRowDimensions();
  841. $columnDimensions = $this->getColumnDimensions();
  842. if ( isset($rowDimensions[$aCoordinates[1]]) && $rowDimensions[$aCoordinates[1]]->getXfIndex() !== null ) {
  843. // then there is a row dimension with explicit style, assign it to the cell
  844. $cell->setXfIndex($rowDimensions[$aCoordinates[1]]->getXfIndex());
  845. } else if ( isset($columnDimensions[$aCoordinates[0]]) ) {
  846. // then there is a column dimension, assign it to the cell
  847. $cell->setXfIndex($columnDimensions[$aCoordinates[0]]->getXfIndex());
  848. } else {
  849. // set to default index
  850. $cell->setXfIndex(0);
  851. }
  852. return $cell;
  853. }
  854. }
  855. /**
  856. * Get cell at a specific coordinate by using numeric cell coordinates
  857. *
  858. * @param string $pColumn Numeric column coordinate of the cell
  859. * @param string $pRow Numeric row coordinate of the cell
  860. * @return PHPExcel_Cell Cell that was found
  861. */
  862. public function getCellByColumnAndRow($pColumn = 0, $pRow = 1)
  863. {
  864. $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn);
  865. $coordinate = $columnLetter . $pRow;
  866. if (!$this->_cellCollection->isDataSet($coordinate)) {
  867. $cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell($columnLetter, $pRow, null, PHPExcel_Cell_DataType::TYPE_NULL, $this));
  868. $this->_cellCollectionIsSorted = false;
  869. if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn)
  870. $this->_cachedHighestColumn = $columnLetter;
  871. $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow);
  872. return $cell;
  873. }
  874. return $this->_cellCollection->getCacheData($coordinate);
  875. }
  876. /**
  877. * Cell at a specific coordinate exists?
  878. *
  879. * @param string $pCoordinate Coordinate of the cell
  880. * @throws Exception
  881. * @return boolean
  882. */
  883. public function cellExists($pCoordinate = 'A1')
  884. {
  885. // Worksheet reference?
  886. if (strpos($pCoordinate, '!') !== false) {
  887. $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
  888. return $this->getParent()->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]);
  889. }
  890. // Named range?
  891. if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
  892. (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
  893. $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
  894. if (!is_null($namedRange)) {
  895. $pCoordinate = $namedRange->getRange();
  896. if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) {
  897. if (!$namedRange->getLocalOnly()) {
  898. return $namedRange->getWorksheet()->cellExists($pCoordinate);
  899. } else {
  900. throw new Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle());
  901. }
  902. }
  903. }
  904. }
  905. // Uppercase coordinate
  906. $pCoordinate = strtoupper($pCoordinate);
  907. if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {
  908. throw new Exception('Cell coordinate can not be a range of cells.');
  909. } elseif (strpos($pCoordinate,'$') !== false) {
  910. throw new Exception('Cell coordinate must not be absolute.');
  911. } else {
  912. // Coordinates
  913. $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
  914. // Cell exists?
  915. return $this->_cellCollection->isDataSet($pCoordinate);
  916. }
  917. }
  918. /**
  919. * Cell at a specific coordinate by using numeric cell coordinates exists?
  920. *
  921. * @param string $pColumn Numeric column coordinate of the cell
  922. * @param string $pRow Numeric row coordinate of the cell
  923. * @return boolean
  924. */
  925. public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1)
  926. {
  927. return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
  928. }
  929. /**
  930. * Get row dimension at a specific row
  931. *
  932. * @param int $pRow Numeric index of the row
  933. * @return PHPExcel_Worksheet_RowDimension
  934. */
  935. public function getRowDimension($pRow = 1)
  936. {
  937. // Found
  938. $found = null;
  939. // Get row dimension
  940. if (!isset($this->_rowDimensions[$pRow])) {
  941. $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow);
  942. $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow);
  943. }
  944. return $this->_rowDimensions[$pRow];
  945. }
  946. /**
  947. * Get column dimension at a specific column
  948. *
  949. * @param string $pColumn String index of the column
  950. * @return PHPExcel_Worksheet_ColumnDimension
  951. */
  952. public function getColumnDimension($pColumn = 'A')
  953. {
  954. // Uppercase coordinate
  955. $pColumn = strtoupper($pColumn);
  956. // Fetch dimensions
  957. if (!isset($this->_columnDimensions[$pColumn])) {
  958. $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn);
  959. if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn))
  960. $this->_cachedHighestColumn = $pColumn;
  961. }
  962. return $this->_columnDimensions[$pColumn];
  963. }
  964. /**
  965. * Get column dimension at a specific column by using numeric cell coordinates
  966. *
  967. * @param string $pColumn Numeric column coordinate of the cell
  968. * @param string $pRow Numeric row coordinate of the cell
  969. * @return PHPExcel_Worksheet_ColumnDimension
  970. */
  971. public function getColumnDimensionByColumn($pColumn = 0)
  972. {
  973. return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn));
  974. }
  975. /**
  976. * Get styles
  977. *
  978. * @return PHPExcel_Style[]
  979. */
  980. public function getStyles()
  981. {
  982. return $this->_styles;
  983. }
  984. /**
  985. * Get default style of workbork.
  986. *
  987. * @deprecated
  988. * @return PHPExcel_Style
  989. * @throws Exception
  990. */
  991. public function getDefaultStyle()
  992. {
  993. return $this->_parent->getDefaultStyle();
  994. }
  995. /**
  996. * Set default style - should only be used by PHPExcel_IReader implementations!
  997. *
  998. * @deprecated
  999. * @param PHPExcel_Style $value
  1000. * @throws Exception
  1001. * @return PHPExcel_Worksheet
  1002. */
  1003. public function setDefaultStyle(PHPExcel_Style $pValue)
  1004. {
  1005. $this->_parent->getDefaultStyle()->applyFromArray(array(
  1006. 'font' => array(
  1007. 'name' => $pValue->getFont()->getName(),
  1008. 'size' => $pValue->getFont()->getSize(),
  1009. ),
  1010. ));
  1011. return $this;
  1012. }
  1013. /**
  1014. * Get style for cell
  1015. *
  1016. * @param string $pCellCoordinate Cell coordinate to get style for
  1017. * @return PHPExcel_Style
  1018. * @throws Exception
  1019. */
  1020. public function getStyle($pCellCoordinate = 'A1')
  1021. {
  1022. // set this sheet as active
  1023. $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this));
  1024. // set cell coordinate as active
  1025. $this->setSelectedCells($pCellCoordinate);
  1026. return $this->_parent->getCellXfSupervisor();
  1027. }
  1028. /**
  1029. * Get conditional styles for a cell
  1030. *
  1031. * @param string $pCoordinate
  1032. * @return PHPExcel_Style_Conditional[]
  1033. */
  1034. public function getConditionalStyles($pCoordinate = 'A1')
  1035. {
  1036. if (!isset($this->_conditionalStylesCollection[$pCoordinate])) {
  1037. $this->_conditionalStylesCollection[$pCoordinate] = array();
  1038. }
  1039. return $this->_conditionalStylesCollection[$pCoordinate];
  1040. }
  1041. /**
  1042. * Do conditional styles exist for this cell?
  1043. *
  1044. * @param string $pCoordinate
  1045. * @return boolean
  1046. */
  1047. public function conditionalStylesExists($pCoordinate = 'A1')
  1048. {
  1049. if (isset($this->_conditionalStylesCollection[$pCoordinate])) {
  1050. return true;
  1051. }
  1052. return false;
  1053. }
  1054. /**
  1055. * Removes conditional styles for a cell
  1056. *
  1057. * @param string $pCoordinate
  1058. * @return PHPExcel_Worksheet
  1059. */
  1060. public function removeConditionalStyles($pCoordinate = 'A1')
  1061. {
  1062. unset($this->_conditionalStylesCollection[$pCoordinate]);
  1063. return $this;
  1064. }
  1065. /**
  1066. * Get collection of conditional styles
  1067. *
  1068. * @return array
  1069. */
  1070. public function getConditionalStylesCollection()
  1071. {
  1072. return $this->_conditionalStylesCollection;
  1073. }
  1074. /**
  1075. * Set conditional styles
  1076. *
  1077. * @param $pCoordinate string E.g. 'A1'
  1078. * @param $pValue PHPExcel_Style_Conditional[]
  1079. * @return PHPExcel_Worksheet
  1080. */
  1081. public function setConditionalStyles($pCoordinate = 'A1', $pValue)
  1082. {
  1083. $this->_conditionalStylesCollection[$pCoordinate] = $pValue;
  1084. return $this;
  1085. }
  1086. /**
  1087. * Get style for cell by using numeric cell coordinates
  1088. *
  1089. * @param int $pColumn Numeric column coordinate of the cell
  1090. * @param int $pRow Numeric row coordinate of the cell
  1091. * @return PHPExcel_Style
  1092. */
  1093. public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1)
  1094. {
  1095. return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
  1096. }
  1097. /**
  1098. * Set shared cell style to a range of cells
  1099. *
  1100. * Please note that this will overwrite existing cell styles for cells in range!
  1101. *
  1102. * @deprecated
  1103. * @param PHPExcel_Style $pSharedCellStyle Cell style to share
  1104. * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1105. * @throws Exception
  1106. * @return PHPExcel_Worksheet
  1107. */
  1108. public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '')
  1109. {
  1110. $this->duplicateStyle($pSharedCellStyle, $pRange);
  1111. return $this;
  1112. }
  1113. /**
  1114. * Duplicate cell style to a range of cells
  1115. *
  1116. * Please note that this will overwrite existing cell styles for cells in range!
  1117. *
  1118. * @param PHPExcel_Style $pCellStyle Cell style to duplicate
  1119. * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1120. * @throws Exception
  1121. * @return PHPExcel_Worksheet
  1122. */
  1123. public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '')
  1124. {
  1125. // make sure we have a real style and not supervisor
  1126. $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle;
  1127. // Add the style to the workbook if necessary
  1128. $workbook = $this->_parent;
  1129. if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) {
  1130. // there is already such cell Xf in our collection
  1131. $xfIndex = $existingStyle->getIndex();
  1132. } else {
  1133. // we don't have such a cell Xf, need to add
  1134. $workbook->addCellXf($pCellStyle);
  1135. $xfIndex = $pCellStyle->getIndex();
  1136. }
  1137. // Uppercase coordinate
  1138. $pRange = strtoupper($pRange);
  1139. // Is it a cell range or a single cell?
  1140. $rangeA = '';
  1141. $rangeB = '';
  1142. if (strpos($pRange, ':') === false) {
  1143. $rangeA = $pRange;
  1144. $rangeB = $pRange;
  1145. } else {
  1146. list($rangeA, $rangeB) = explode(':', $pRange);
  1147. }
  1148. // Calculate range outer borders
  1149. $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
  1150. $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
  1151. // Translate column into index
  1152. $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
  1153. $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
  1154. // Make sure we can loop upwards on rows and columns
  1155. if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
  1156. $tmp = $rangeStart;
  1157. $rangeStart = $rangeEnd;
  1158. $rangeEnd = $tmp;
  1159. }
  1160. // Loop through cells and apply styles
  1161. for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
  1162. for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
  1163. $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex);
  1164. }
  1165. }
  1166. return $this;
  1167. }
  1168. /**
  1169. * Duplicate cell style array to a range of cells
  1170. *
  1171. * Please note that this will overwrite existing cell styles for cells in range,
  1172. * if they are in the styles array. For example, if you decide to set a range of
  1173. * cells to font bold, only include font bold in the styles array.
  1174. *
  1175. * @deprecated
  1176. * @param array $pStyles Array containing style information
  1177. * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1178. * @param boolean $pAdvanced Advanced mode for setting borders.
  1179. * @throws Exception
  1180. * @return PHPExcel_Worksheet
  1181. */
  1182. public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true)
  1183. {
  1184. $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced);
  1185. return $this;
  1186. }
  1187. /**
  1188. * Set break on a cell
  1189. *
  1190. * @param string $pCell Cell coordinate (e.g. A1)
  1191. * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*)
  1192. * @throws Exception
  1193. * @return PHPExcel_Worksheet
  1194. */
  1195. public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE)
  1196. {
  1197. // Uppercase coordinate
  1198. $pCell = strtoupper($pCell);
  1199. if ($pCell != '') {
  1200. $this->_breaks[$pCell] = $pBreak;
  1201. } else {
  1202. throw new Exception('No cell coordinate specified.');
  1203. }
  1204. return $this;
  1205. }
  1206. /**
  1207. * Set break on a cell by using numeric cell coordinates
  1208. *
  1209. * @param integer $pColumn Numeric column coordinate of the cell
  1210. * @param integer $pRow Numeric row coordinate of the cell
  1211. * @param integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*)
  1212. * @throws Exception
  1213. * @return PHPExcel_Worksheet
  1214. */
  1215. public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE)
  1216. {
  1217. return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak);
  1218. }
  1219. /**
  1220. * Get breaks
  1221. *
  1222. * @return array[]
  1223. */
  1224. public function getBreaks()
  1225. {
  1226. return $this->_breaks;
  1227. }
  1228. /**
  1229. * Set merge on a cell range
  1230. *
  1231. * @param string $pRange Cell range (e.g. A1:E1)
  1232. * @throws Exception
  1233. * @return PHPExcel_Worksheet
  1234. */
  1235. public function mergeCells($pRange = 'A1:A1')
  1236. {
  1237. // Uppercase coordinate
  1238. $pRange = strtoupper($pRange);
  1239. if (strpos($pRange,':') !== false) {
  1240. $this->_mergeCells[$pRange] = $pRange;
  1241. // make sure cells are created
  1242. // get the cells in the range
  1243. $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
  1244. // create upper left cell if it does not already exist
  1245. $upperLeft = $aReferences[0];
  1246. if (!$this->cellExists($upperLeft)) {
  1247. $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);
  1248. }
  1249. // create or blank out the rest of the cells in the range
  1250. $count = count($aReferences);
  1251. for ($i = 1; $i < $count; $i++) {
  1252. $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);
  1253. }
  1254. } else {
  1255. throw new Exception('Merge must be set on a range of cells.');
  1256. }
  1257. return $this;
  1258. }
  1259. /**
  1260. * Set merge on a cell range by using numeric cell coordinates
  1261. *
  1262. * @param int $pColumn1 Numeric column coordinate of the first cell
  1263. * @param int $pRow1 Numeric row coordinate of the first cell
  1264. * @param int $pColumn2 Numeric column coordinate of the last cell
  1265. * @param int $pRow2 Numeric row coordinate of the last cell
  1266. * @throws Exception
  1267. * @return PHPExcel_Worksheet
  1268. */
  1269. public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
  1270. {
  1271. $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
  1272. return $this->mergeCells($cellRange);
  1273. }
  1274. /**
  1275. * Remove merge on a cell range
  1276. *
  1277. * @param string $pRange Cell range (e.g. A1:E1)
  1278. * @throws Exception
  1279. * @return PHPExcel_Worksheet
  1280. */
  1281. public function unmergeCells($pRange = 'A1:A1')
  1282. {
  1283. // Uppercase coordinate
  1284. $pRange = strtoupper($pRange);
  1285. if (strpos($pRange,':') !== false) {
  1286. if (isset($this->_mergeCells[$pRange])) {
  1287. unset($this->_mergeCells[$pRange]);
  1288. } else {
  1289. throw new Exception('Cell range ' . $pRange . ' not known as merged.');
  1290. }
  1291. } else {
  1292. throw new Exception('Merge can only be removed from a range of cells.');
  1293. }
  1294. return $this;
  1295. }
  1296. /**
  1297. * Remove merge on a cell range by using numeric cell coordinates
  1298. *
  1299. * @param int $pColumn1 Numeric column coordinate of the first cell
  1300. * @param int $pRow1 Numeric row coordinate of the first cell
  1301. * @param int $pColumn2 Numeric column coordinate of the last cell
  1302. * @param int $pRow2 Numeric row coordinate of the last cell
  1303. * @throws Exception
  1304. * @return PHPExcel_Worksheet
  1305. */
  1306. public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
  1307. {
  1308. $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
  1309. return $this->unmergeCells($cellRange);
  1310. }
  1311. /**
  1312. * Get merge cells array.
  1313. *
  1314. * @return array[]
  1315. */
  1316. public function getMergeCells()
  1317. {
  1318. return $this->_mergeCells;
  1319. }
  1320. /**
  1321. * Set merge cells array for the entire sheet. Use instead mergeCells() to merge
  1322. * a single cell range.
  1323. *
  1324. * @param array
  1325. */
  1326. public function setMergeCells($pValue = array())
  1327. {
  1328. $this->_mergeCells = $pValue;
  1329. return $this;
  1330. }
  1331. /**
  1332. * Set protection on a cell range
  1333. *
  1334. * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1)
  1335. * @param string $pPassword Password to unlock the protection
  1336. * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
  1337. * @throws Exception
  1338. * @return PHPExcel_Worksheet
  1339. */
  1340. public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false)
  1341. {
  1342. // Uppercase coordinate
  1343. $pRange = strtoupper($pRange);
  1344. if (!$pAlreadyHashed) {
  1345. $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword);
  1346. }
  1347. $this->_protectedCells[$pRange] = $pPassword;
  1348. return $this;
  1349. }
  1350. /**
  1351. * Set protection on a cell range by using numeric cell coordinates
  1352. *
  1353. * @param int $pColumn1 Numeric column coordinate of the first cell
  1354. * @param int $pRow1 Numeric row coordinate of the first cell
  1355. * @param int $pColumn2 Numeric column coordinate of the last cell
  1356. * @param int $pRow2 Numeric row coordinate of the last cell
  1357. * @param string $pPassword Password to unlock the protection
  1358. * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
  1359. * @throws Exception
  1360. * @return PHPExcel_Worksheet
  1361. */
  1362. public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)
  1363. {
  1364. $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
  1365. return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed);
  1366. }
  1367. /**
  1368. * Remove protection on a cell range
  1369. *
  1370. * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1)
  1371. * @throws Exception
  1372. * @return PHPExcel_Worksheet
  1373. */
  1374. public function unprotectCells($pRange = 'A1')
  1375. {
  1376. // Uppercase coordinate
  1377. $pRange = strtoupper($pRange);
  1378. if (isset($this->_protectedCells[$pRange])) {
  1379. unset($this->_protectedCells[$pRange]);
  1380. } else {
  1381. throw new Exception('Cell range ' . $pRange . ' not known as protected.');
  1382. }
  1383. return $this;
  1384. }
  1385. /**
  1386. * Remove protection on a cell range by using numeric cell coordinates
  1387. *
  1388. * @param int $pColumn1 Numeric column coordinate of the first cell
  1389. * @param int $pRow1 Numeric row coordinate of the first cell
  1390. * @param int $pColumn2 Numeric column coordinate of the last cell
  1391. * @param int $pRow2 Numeric row coordinate of the last cell
  1392. * @param string $pPassword Password to unlock the protection
  1393. * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true
  1394. * @throws Exception
  1395. * @return PHPExcel_Worksheet
  1396. */
  1397. public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)
  1398. {
  1399. $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
  1400. return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed);
  1401. }
  1402. /**
  1403. * Get protected cells
  1404. *
  1405. * @return array[]
  1406. */
  1407. public function getProtectedCells()
  1408. {
  1409. return $this->_protectedCells;
  1410. }
  1411. /**
  1412. * Get Autofilter Range
  1413. *
  1414. * @return string
  1415. */
  1416. public function getAutoFilter()
  1417. {
  1418. return $this->_autoFilter;
  1419. }
  1420. /**
  1421. * Set Autofilter Range
  1422. *
  1423. * @param string $pRange Cell range (i.e. A1:E10)
  1424. * @throws Exception
  1425. * @return PHPExcel_Worksheet
  1426. */
  1427. public function setAutoFilter($pRange = '')
  1428. {
  1429. // Uppercase coordinate
  1430. $pRange = strtoupper($pRange);
  1431. if (strpos($pRange,':') !== false) {
  1432. $this->_autoFilter = $pRange;
  1433. $this->_dirty = true;
  1434. } else {
  1435. throw new Exception('Autofilter must be set on a range of cells.');
  1436. }
  1437. return $this;
  1438. }
  1439. /**
  1440. * Set Autofilter Range by using numeric cell coordinates
  1441. *
  1442. * @param int $pColumn1 Numeric column coordinate of the first cell
  1443. * @param int $pRow1 Numeric row coordinate of the first cell
  1444. * @param int $pColumn2 Numeric column coordinate of the second cell
  1445. * @param int $pRow2 Numeric row coordinate of the second cell
  1446. * @throws Exception
  1447. * @return PHPExcel_Worksheet
  1448. */
  1449. public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
  1450. {
  1451. return $this->setAutoFilter(
  1452. PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1
  1453. . ':' .
  1454. PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2
  1455. );
  1456. }
  1457. /**
  1458. * Remove autofilter
  1459. *
  1460. * @return PHPExcel_Worksheet
  1461. */
  1462. public function removeAutoFilter()
  1463. {
  1464. $this->_autoFilter = '';
  1465. return $this;
  1466. }
  1467. /**
  1468. * Get Freeze Pane
  1469. *
  1470. * @return string
  1471. */
  1472. public function getFreezePane()
  1473. {
  1474. return $this->_freezePane;
  1475. }
  1476. /**
  1477. * Freeze Pane
  1478. *
  1479. * @param string $pCell Cell (i.e. A1)
  1480. * @throws Exception
  1481. * @return PHPExcel_Worksheet
  1482. */
  1483. public function freezePane($pCell = '')
  1484. {
  1485. // Uppercase coordinate
  1486. $pCell = strtoupper($pCell);
  1487. if (strpos($pCell,':') === false && strpos($pCell,',') === false) {
  1488. $this->_freezePane = $pCell;
  1489. } else {
  1490. throw new Exception('Freeze pane can not be set on a range of cells.');
  1491. }
  1492. return $this;
  1493. }
  1494. /**
  1495. * Freeze Pane by using numeric cell coordinates
  1496. *
  1497. * @param int $pColumn Numeric column coordinate of the cell
  1498. * @param int $pRow Numeric row coordinate of the cell
  1499. * @throws Exception
  1500. * @return PHPExcel_Worksheet
  1501. */
  1502. public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1)
  1503. {
  1504. return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
  1505. }
  1506. /**
  1507. * Unfreeze Pane
  1508. *
  1509. * @return PHPExcel_Worksheet
  1510. */
  1511. public function unfreezePane()
  1512. {
  1513. return $this->freezePane('');
  1514. }
  1515. /**
  1516. * Insert a new row, updating all possible related data
  1517. *
  1518. * @param int $pBefore Insert before this one
  1519. * @param int $pNumRows Number of rows to insert
  1520. * @throws Exception
  1521. * @return PHPExcel_Worksheet
  1522. */
  1523. public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) {
  1524. if ($pBefore >= 1) {
  1525. $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
  1526. $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this);
  1527. } else {
  1528. throw new Exception("Rows can only be inserted before at least row 1.");
  1529. }
  1530. return $this;
  1531. }
  1532. /**
  1533. * Insert a new column, updating all possible related data
  1534. *
  1535. * @param int $pBefore Insert before this one
  1536. * @param int $pNumCols Number of columns to insert
  1537. * @throws Exception
  1538. * @return PHPExcel_Worksheet
  1539. */
  1540. public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) {
  1541. if (!is_numeric($pBefore)) {
  1542. $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
  1543. $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this);
  1544. } else {
  1545. throw new Exception("Column references should not be numeric.");
  1546. }
  1547. return $this;
  1548. }
  1549. /**
  1550. * Insert a new column, updating all possible related data
  1551. *
  1552. * @param int $pBefore Insert before this one (numeric column coordinate of the cell)
  1553. * @param int $pNumCols Number of columns to insert
  1554. * @throws Exception
  1555. * @return PHPExcel_Worksheet
  1556. */
  1557. public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) {
  1558. if ($pBefore >= 0) {
  1559. return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols);
  1560. } else {
  1561. throw new Exception("Columns can only be inserted before at least column A (0).");
  1562. }
  1563. }
  1564. /**
  1565. * Delete a row, updating all possible related data
  1566. *
  1567. * @param int $pRow Remove starting with this one
  1568. * @param int $pNumRows Number of rows to remove
  1569. * @throws Exception
  1570. * @return PHPExcel_Worksheet
  1571. */
  1572. public function removeRow($pRow = 1, $pNumRows = 1) {
  1573. if ($pRow >= 1) {
  1574. $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
  1575. $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this);
  1576. } else {
  1577. throw new Exception("Rows to be deleted should at least start from row 1.");
  1578. }
  1579. return $this;
  1580. }
  1581. /**
  1582. * Remove a column, updating all possible related data
  1583. *
  1584. * @param int $pColumn Remove starting with this one
  1585. * @param int $pNumCols Number of columns to remove
  1586. * @throws Exception
  1587. * @return PHPExcel_Worksheet
  1588. */
  1589. public function removeColumn($pColumn = 'A', $pNumCols = 1) {
  1590. if (!is_numeric($pColumn)) {
  1591. $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols);
  1592. $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
  1593. $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
  1594. } else {
  1595. throw new Exception("Column references should not be numeric.");
  1596. }
  1597. return $this;
  1598. }
  1599. /**
  1600. * Remove a column, updating all possible related data
  1601. *
  1602. * @param int $pColumn Remove starting with this one (numeric column coordinate of the cell)
  1603. * @param int $pNumCols Number of columns to remove
  1604. * @throws Exception
  1605. * @return PHPExcel_Worksheet
  1606. */
  1607. public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) {
  1608. if ($pColumn >= 0) {
  1609. return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols);
  1610. } else {
  1611. throw new Exception("Columns to be deleted should at least start from column 0");
  1612. }
  1613. }
  1614. /**
  1615. * Show gridlines?
  1616. *
  1617. * @return boolean
  1618. */
  1619. public function getShowGridlines() {
  1620. return $this->_showGridlines;
  1621. }
  1622. /**
  1623. * Set show gridlines
  1624. *
  1625. * @param boolean $pValue Show gridlines (true/false)
  1626. * @return PHPExcel_Worksheet
  1627. */
  1628. public function setShowGridlines($pValue = false) {
  1629. $this->_showGridlines = $pValue;
  1630. return $this;
  1631. }
  1632. /**
  1633. * Print gridlines?
  1634. *
  1635. * @return boolean
  1636. */
  1637. public function getPrintGridlines() {
  1638. return $this->_printGridlines;
  1639. }
  1640. /**
  1641. * Set print gridlines
  1642. *
  1643. * @param boolean $pValue Print gridlines (true/false)
  1644. * @return PHPExcel_Worksheet
  1645. */
  1646. public function setPrintGridlines($pValue = false) {
  1647. $this->_printGridlines = $pValue;
  1648. return $this;
  1649. }
  1650. /**
  1651. * Show row and column headers?
  1652. *
  1653. * @return boolean
  1654. */
  1655. public function getShowRowColHeaders() {
  1656. return $this->_showRowColHeaders;
  1657. }
  1658. /**
  1659. * Set show row and column headers
  1660. *
  1661. * @param boolean $pValue Show row and column headers (true/false)
  1662. * @return PHPExcel_Worksheet
  1663. */
  1664. public function setShowRowColHeaders($pValue = false) {
  1665. $this->_showRowColHeaders = $pValue;
  1666. return $this;
  1667. }
  1668. /**
  1669. * Show summary below? (Row/Column outlining)
  1670. *
  1671. * @return boolean
  1672. */
  1673. public function getShowSummaryBelow() {
  1674. return $this->_showSummaryBelow;
  1675. }
  1676. /**
  1677. * Set show summary below
  1678. *
  1679. * @param boolean $pValue Show summary below (true/false)
  1680. * @return PHPExcel_Worksheet
  1681. */
  1682. public function setShowSummaryBelow($pValue = true) {
  1683. $this->_showSummaryBelow = $pValue;
  1684. return $this;
  1685. }
  1686. /**
  1687. * Show summary right? (Row/Column outlining)
  1688. *
  1689. * @return boolean
  1690. */
  1691. public function getShowSummaryRight() {
  1692. return $this->_showSummaryRight;
  1693. }
  1694. /**
  1695. * Set show summary right
  1696. *
  1697. * @param boolean $pValue Show summary right (true/false)
  1698. * @return PHPExcel_Worksheet
  1699. */
  1700. public function setShowSummaryRight($pValue = true) {
  1701. $this->_showSummaryRight = $pValue;
  1702. return $this;
  1703. }
  1704. /**
  1705. * Get comments
  1706. *
  1707. * @return PHPExcel_Comment[]
  1708. */
  1709. public function getComments()
  1710. {
  1711. return $this->_comments;
  1712. }
  1713. /**
  1714. * Set comments array for the entire sheet.
  1715. *
  1716. * @param array of PHPExcel_Comment
  1717. * @return PHPExcel_Worksheet
  1718. */
  1719. public function setComments($pValue = array())
  1720. {
  1721. $this->_comments = $pValue;
  1722. return $this;
  1723. }
  1724. /**
  1725. * Get comment for cell
  1726. *
  1727. * @param string $pCellCoordinate Cell coordinate to get comment for
  1728. * @return PHPExcel_Comment
  1729. * @throws Exception
  1730. */
  1731. public function getComment($pCellCoordinate = 'A1')
  1732. {
  1733. // Uppercase coordinate
  1734. $pCellCoordinate = strtoupper($pCellCoordinate);
  1735. if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) {
  1736. throw new Exception('Cell coordinate string can not be a range of cells.');
  1737. } else if (strpos($pCellCoordinate,'$') !== false) {
  1738. throw new Exception('Cell coordinate string must not be absolute.');
  1739. } else if ($pCellCoordinate == '') {
  1740. throw new Exception('Cell coordinate can not be zero-length string.');
  1741. } else {
  1742. // Check if we already have a comment for this cell.
  1743. // If not, create a new comment.
  1744. if (isset($this->_comments[$pCellCoordinate])) {
  1745. return $this->_comments[$pCellCoordinate];
  1746. } else {
  1747. $newComment = new PHPExcel_Comment();
  1748. $this->_comments[$pCellCoordinate] = $newComment;
  1749. return $newComment;
  1750. }
  1751. }
  1752. }
  1753. /**
  1754. * Get comment for cell by using numeric cell coordinates
  1755. *
  1756. * @param int $pColumn Numeric column coordinate of the cell
  1757. * @param int $pRow Numeric row coordinate of the cell
  1758. * @return PHPExcel_Comment
  1759. */
  1760. public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1)
  1761. {
  1762. return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
  1763. }
  1764. /**
  1765. * Get selected cell
  1766. *
  1767. * @deprecated
  1768. * @return string
  1769. */
  1770. public function getSelectedCell()
  1771. {
  1772. return $this->getSelectedCells();
  1773. }
  1774. /**
  1775. * Get active cell
  1776. *
  1777. * @return string Example: 'A1'
  1778. */
  1779. public function getActiveCell()
  1780. {
  1781. return $this->_activeCell;
  1782. }
  1783. /**
  1784. * Get selected cells
  1785. *
  1786. * @return string
  1787. */
  1788. public function getSelectedCells()
  1789. {
  1790. return $this->_selectedCells;
  1791. }
  1792. /**
  1793. * Selected cell
  1794. *
  1795. * @param string $pCell Cell (i.e. A1)
  1796. * @return PHPExcel_Worksheet
  1797. */
  1798. public function setSelectedCell($pCoordinate = 'A1')
  1799. {
  1800. return $this->setSelectedCells($pCoordinate);
  1801. }
  1802. /**
  1803. * Select a range of cells.
  1804. *
  1805. * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6'
  1806. * @throws Exception
  1807. * @return PHPExcel_Worksheet
  1808. */
  1809. public function setSelectedCells($pCoordinate = 'A1')
  1810. {
  1811. // Uppercase coordinate
  1812. $pCoordinate = strtoupper($pCoordinate);
  1813. // Convert 'A' to 'A:A'
  1814. $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate);
  1815. // Convert '1' to '1:1'
  1816. $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate);
  1817. // Convert 'A:C' to 'A1:C1048576'
  1818. $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate);
  1819. // Convert '1:3' to 'A1:XFD3'
  1820. $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate);
  1821. if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {
  1822. list($first, ) = PHPExcel_Cell::splitRange($pCoordinate);
  1823. $this->_activeCell = $first[0];
  1824. } else {
  1825. $this->_activeCell = $pCoordinate;
  1826. }
  1827. $this->_selectedCells = $pCoordinate;
  1828. return $this;
  1829. }
  1830. /**
  1831. * Selected cell by using numeric cell coordinates
  1832. *
  1833. * @param int $pColumn Numeric column coordinate of the cell
  1834. * @param int $pRow Numeric row coordinate of the cell
  1835. * @throws Exception
  1836. * @return PHPExcel_Worksheet
  1837. */
  1838. public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1)
  1839. {
  1840. return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
  1841. }
  1842. /**
  1843. * Get right-to-left
  1844. *
  1845. * @return boolean
  1846. */
  1847. public function getRightToLeft() {
  1848. return $this->_rightToLeft;
  1849. }
  1850. /**
  1851. * Set right-to-left
  1852. *
  1853. * @param boolean $value Right-to-left true/false
  1854. * @return PHPExcel_Worksheet
  1855. */
  1856. public function setRightToLeft($value = false) {
  1857. $this->_rightToLeft = $value;
  1858. return $this;
  1859. }
  1860. /**
  1861. * Fill worksheet from values in array
  1862. *
  1863. * @param array $source Source array
  1864. * @param mixed $nullValue Value in source array that stands for blank cell
  1865. * @param string $startCell Insert array starting from this cell address as the top left coordinate
  1866. * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array
  1867. * @throws Exception
  1868. * @return PHPExcel_Worksheet
  1869. */
  1870. public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) {
  1871. if (is_array($source)) {
  1872. // Convert a 1-D array to 2-D (for ease of looping)
  1873. if (!is_array(end($source))) {
  1874. $source = array($source);
  1875. }
  1876. // start coordinate
  1877. list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell);
  1878. // Loop through $source
  1879. foreach ($source as $rowData) {
  1880. $currentColumn = $startColumn;
  1881. foreach($rowData as $cellValue) {
  1882. if ($strictNullComparison) {
  1883. if ($cellValue !== $nullValue) {
  1884. // Set cell value
  1885. $this->getCell($currentColumn . $startRow)->setValue($cellValue);
  1886. }
  1887. } else {
  1888. if ($cellValue != $nullValue) {
  1889. // Set cell value
  1890. $this->getCell($currentColumn . $startRow)->setValue($cellValue);
  1891. }
  1892. }
  1893. ++$currentColumn;
  1894. }
  1895. ++$startRow;
  1896. }
  1897. } else {
  1898. throw new Exception("Parameter \$source should be an array.");
  1899. }
  1900. return $this;
  1901. }
  1902. /**
  1903. * Create array from a range of cells
  1904. *
  1905. * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
  1906. * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
  1907. * @param boolean $calculateFormulas Should formulas be calculated?
  1908. * @param boolean $formatData Should formatting be applied to cell values?
  1909. * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
  1910. * True - Return rows and columns indexed by their actual row and column IDs
  1911. * @return array
  1912. */
  1913. public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
  1914. // Returnvalue
  1915. $returnValue = array();
  1916. // Identify the range that we need to extract from the worksheet
  1917. list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange);
  1918. $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1);
  1919. $minRow = $rangeStart[1];
  1920. $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1);
  1921. $maxRow = $rangeEnd[1];
  1922. $maxCol++;
  1923. // Loop through rows
  1924. for ($row = $minRow; $row <= $maxRow; ++$row) {
  1925. $c = -1;
  1926. // Loop through columns in the current row
  1927. for ($col = $minCol; $col != $maxCol; ++$col) {
  1928. $rRef = ($returnCellRef) ? $row : $row-1;
  1929. $cRef = ($returnCellRef) ? $col : ++$c;
  1930. // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen
  1931. // so we test and retrieve directly against _cellCollection
  1932. if ($this->_cellCollection->isDataSet($col.$row)) {
  1933. // Cell exists
  1934. $cell = $this->_cellCollection->getCacheData($col.$row);
  1935. if ($cell->getValue() !== null) {
  1936. if ($cell->getValue() instanceof PHPExcel_RichText) {
  1937. $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();
  1938. } else {
  1939. if ($calculateFormulas) {
  1940. $returnValue[$rRef][$cRef] = $cell->getCalculatedValue();
  1941. } else {
  1942. $returnValue[$rRef][$cRef] = $cell->getValue();
  1943. }
  1944. }
  1945. if ($formatData) {
  1946. $style = $this->_parent->getCellXfByIndex($cell->getXfIndex());
  1947. $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString($returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode());
  1948. }
  1949. } else {
  1950. // Cell holds a NULL
  1951. $returnValue[$rRef][$cRef] = $nullValue;
  1952. }
  1953. } else {
  1954. // Cell doesn't exist
  1955. $returnValue[$rRef][$cRef] = $nullValue;
  1956. }
  1957. }
  1958. }
  1959. // Return
  1960. return $returnValue;
  1961. }
  1962. /**
  1963. * Create array from a range of cells
  1964. *
  1965. * @param string $pNamedRange Name of the Named Range
  1966. * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
  1967. * @param boolean $calculateFormulas Should formulas be calculated?
  1968. * @param boolean $formatData Should formatting be applied to cell values?
  1969. * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
  1970. * True - Return rows and columns indexed by their actual row and column IDs
  1971. * @return array
  1972. * @throws Exception
  1973. */
  1974. public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
  1975. $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this);
  1976. if (!is_null($namedRange)) {
  1977. $pWorkSheet = $namedRange->getWorksheet();
  1978. $pCellRange = $namedRange->getRange();
  1979. return $pWorkSheet->rangeToArray( $pCellRange,
  1980. $nullValue, $calculateFormulas, $formatData, $returnCellRef);
  1981. }
  1982. throw new Exception('Named Range '.$pNamedRange.' does not exist.');
  1983. }
  1984. /**
  1985. * Create array from worksheet
  1986. *
  1987. * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
  1988. * @param boolean $calculateFormulas Should formulas be calculated?
  1989. * @param boolean $formatData Should formatting be applied to cell values?
  1990. * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
  1991. * True - Return rows and columns indexed by their actual row and column IDs
  1992. * @return array
  1993. */
  1994. public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
  1995. // Garbage collect...
  1996. $this->garbageCollect();
  1997. // Identify the range that we need to extract from the worksheet
  1998. $maxCol = $this->getHighestColumn();
  1999. $maxRow = $this->getHighestRow();
  2000. // Return
  2001. return $this->rangeToArray( 'A1:'.$maxCol.$maxRow,
  2002. $nullValue, $calculateFormulas, $formatData, $returnCellRef);
  2003. }
  2004. /**
  2005. * Get row iterator
  2006. *
  2007. * @return PHPExcel_Worksheet_RowIterator
  2008. */
  2009. public function getRowIterator() {
  2010. return new PHPExcel_Worksheet_RowIterator($this);
  2011. }
  2012. /**
  2013. * Run PHPExcel garabage collector.
  2014. *
  2015. * @return PHPExcel_Worksheet
  2016. */
  2017. public function garbageCollect() {
  2018. // Build a reference table from images
  2019. // $imageCoordinates = array();
  2020. // $iterator = $this->getDrawingCollection()->getIterator();
  2021. // while ($iterator->valid()) {
  2022. // $imageCoordinates[$iterator->current()->getCoordinates()] = true;
  2023. //
  2024. // $iterator->next();
  2025. // }
  2026. //
  2027. // Lookup highest column and highest row if cells are cleaned
  2028. $highestColumn = -1;
  2029. $highestRow = 1;
  2030. // Find cells that can be cleaned
  2031. $col = $row = array();
  2032. foreach ($this->_cellCollection->getCellList() as $coord) {
  2033. list($c,$r) = sscanf($coord,'%[A-Z]%d');
  2034. $row[$r] = $r;
  2035. $col[$c] = strlen($c).$c;
  2036. }
  2037. if (count($row) > 0) {
  2038. // Determine highest column and row
  2039. $highestRow = max($row);
  2040. $highestColumn = PHPExcel_Cell::columnIndexFromString(substr(max($col),1));
  2041. }
  2042. // Loop through column dimensions
  2043. foreach ($this->_columnDimensions as $dimension) {
  2044. $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex()));
  2045. }
  2046. // Loop through row dimensions
  2047. foreach ($this->_rowDimensions as $dimension) {
  2048. $highestRow = max($highestRow,$dimension->getRowIndex());
  2049. }
  2050. // Cache values
  2051. if ($highestColumn < 0) {
  2052. $this->_cachedHighestColumn = 'A';
  2053. } else {
  2054. $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn);
  2055. }
  2056. $this->_cachedHighestRow = $highestRow;
  2057. // Return
  2058. return $this;
  2059. }
  2060. /**
  2061. * Get hash code
  2062. *
  2063. * @return string Hash code
  2064. */
  2065. public function getHashCode() {
  2066. if ($this->_dirty) {
  2067. $this->_hash = md5( $this->_title .
  2068. $this->_autoFilter .
  2069. ($this->_protection->isProtectionEnabled() ? 't' : 'f') .
  2070. __CLASS__
  2071. );
  2072. $this->_dirty = false;
  2073. }
  2074. return $this->_hash;
  2075. }
  2076. /**
  2077. * Extract worksheet title from range.
  2078. *
  2079. * Example: extractSheetTitle("testSheet!A1") ==> 'A1'
  2080. * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1');
  2081. *
  2082. * @param string $pRange Range to extract title from
  2083. * @param bool $returnRange Return range? (see example)
  2084. * @return mixed
  2085. */
  2086. public static function extractSheetTitle($pRange, $returnRange = false) {
  2087. // Sheet title included?
  2088. if (($sep = strpos($pRange, '!')) === false) {
  2089. return '';
  2090. }
  2091. if ($returnRange) {
  2092. return array( trim(substr($pRange, 0, $sep),"'"),
  2093. substr($pRange, $sep + 1)
  2094. );
  2095. }
  2096. return substr($pRange, $sep + 1);
  2097. }
  2098. /**
  2099. * Get hyperlink
  2100. *
  2101. * @param string $pCellCoordinate Cell coordinate to get hyperlink for
  2102. */
  2103. public function getHyperlink($pCellCoordinate = 'A1')
  2104. {
  2105. // return hyperlink if we already have one
  2106. if (isset($this->_hyperlinkCollection[$pCellCoordinate])) {
  2107. return $this->_hyperlinkCollection[$pCellCoordinate];
  2108. }
  2109. // else create hyperlink
  2110. $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink();
  2111. return $this->_hyperlinkCollection[$pCellCoordinate];
  2112. }
  2113. /**
  2114. * Set hyperlnk
  2115. *
  2116. * @param string $pCellCoordinate Cell coordinate to insert hyperlink
  2117. * @param PHPExcel_Cell_Hyperlink $pHyperlink
  2118. * @return PHPExcel_Worksheet
  2119. */
  2120. public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null)
  2121. {
  2122. if ($pHyperlink === null) {
  2123. unset($this->_hyperlinkCollection[$pCellCoordinate]);
  2124. } else {
  2125. $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink;
  2126. }
  2127. return $this;
  2128. }
  2129. /**
  2130. * Hyperlink at a specific coordinate exists?
  2131. *
  2132. * @param string $pCellCoordinate
  2133. * @return boolean
  2134. */
  2135. public function hyperlinkExists($pCoordinate = 'A1')
  2136. {
  2137. return isset($this->_hyperlinkCollection[$pCoordinate]);
  2138. }
  2139. /**
  2140. * Get collection of hyperlinks
  2141. *
  2142. * @return PHPExcel_Cell_Hyperlink[]
  2143. */
  2144. public function getHyperlinkCollection()
  2145. {
  2146. return $this->_hyperlinkCollection;
  2147. }
  2148. /**
  2149. * Get data validation
  2150. *
  2151. * @param string $pCellCoordinate Cell coordinate to get data validation for
  2152. */
  2153. public function getDataValidation($pCellCoordinate = 'A1')
  2154. {
  2155. // return data validation if we already have one
  2156. if (isset($this->_dataValidationCollection[$pCellCoordinate])) {
  2157. return $this->_dataValidationCollection[$pCellCoordinate];
  2158. }
  2159. // else create data validation
  2160. $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation();
  2161. return $this->_dataValidationCollection[$pCellCoordinate];
  2162. }
  2163. /**
  2164. * Set data validation
  2165. *
  2166. * @param string $pCellCoordinate Cell coordinate to insert data validation
  2167. * @param PHPExcel_Cell_DataValidation $pDataValidation
  2168. * @return PHPExcel_Worksheet
  2169. */
  2170. public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null)
  2171. {
  2172. if ($pDataValidation === null) {
  2173. unset($this->_dataValidationCollection[$pCellCoordinate]);
  2174. } else {
  2175. $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation;
  2176. }
  2177. return $this;
  2178. }
  2179. /**
  2180. * Data validation at a specific coordinate exists?
  2181. *
  2182. * @param string $pCellCoordinate
  2183. * @return boolean
  2184. */
  2185. public function dataValidationExists($pCoordinate = 'A1')
  2186. {
  2187. return isset($this->_dataValidationCollection[$pCoordinate]);
  2188. }
  2189. /**
  2190. * Get collection of data validations
  2191. *
  2192. * @return PHPExcel_Cell_DataValidation[]
  2193. */
  2194. public function getDataValidationCollection()
  2195. {
  2196. return $this->_dataValidationCollection;
  2197. }
  2198. /**
  2199. * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet
  2200. *
  2201. * @param string $range
  2202. * @return string Adjusted range value
  2203. */
  2204. public function shrinkRangeToFit($range) {
  2205. $maxCol = $this->getHighestColumn();
  2206. $maxRow = $this->getHighestRow();
  2207. $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol);
  2208. $rangeBlocks = explode(' ',$range);
  2209. foreach ($rangeBlocks as &$rangeSet) {
  2210. $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet);
  2211. if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); }
  2212. if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; }
  2213. if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); }
  2214. if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; }
  2215. $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1];
  2216. }
  2217. unset($rangeSet);
  2218. $stRange = implode(' ',$rangeBlocks);
  2219. return $stRange;
  2220. }
  2221. /**
  2222. * Get tab color
  2223. *
  2224. * @return PHPExcel_Style_Color
  2225. */
  2226. public function getTabColor()
  2227. {
  2228. if (is_null($this->_tabColor))
  2229. $this->_tabColor = new PHPExcel_Style_Color();
  2230. return $this->_tabColor;
  2231. }
  2232. /**
  2233. * Reset tab color
  2234. *
  2235. * @return PHPExcel_Worksheet
  2236. */
  2237. public function resetTabColor()
  2238. {
  2239. $this->_tabColor = null;
  2240. unset($this->_tabColor);
  2241. return $this;
  2242. }
  2243. /**
  2244. * Tab color set?
  2245. *
  2246. * @return boolean
  2247. */
  2248. public function isTabColorSet()
  2249. {
  2250. return !is_null($this->_tabColor);
  2251. }
  2252. /**
  2253. * Copy worksheet (!= clone!)
  2254. *
  2255. * @return PHPExcel_Worksheet
  2256. */
  2257. public function copy() {
  2258. $copied = clone $this;
  2259. return $copied;
  2260. }
  2261. /**
  2262. * Implement PHP __clone to create a deep clone, not just a shallow copy.
  2263. */
  2264. public function __clone() {
  2265. foreach ($this as $key => $val) {
  2266. if ($key == '_parent') {
  2267. continue;
  2268. }
  2269. if (is_object($val) || (is_array($val))) {
  2270. if ($key == '_cellCollection') {
  2271. $newCollection = clone $this->_cellCollection;
  2272. $newCollection->copyCellCollection($this);
  2273. $this->_cellCollection = $newCollection;
  2274. } elseif ($key == '_drawingCollection') {
  2275. $newCollection = clone $this->_drawingCollection;
  2276. $this->_drawingCollection = $newCollection;
  2277. } else {
  2278. $this->{$key} = unserialize(serialize($val));
  2279. }
  2280. }
  2281. }
  2282. }
  2283. }