Subversion Repositories eFlore/Applications.cel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2388 jpm 1
<?php
2
/**
3
 * PHPExcel
4
 *
5
 * Copyright (c) 2006 - 2013 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_Reader
23
 * @copyright  Copyright (c) 2006 - 2013 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
 
29
/** PHPExcel root directory */
30
if (!defined('PHPEXCEL_ROOT')) {
31
	/**
32
	 * @ignore
33
	 */
34
	define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
35
	require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
36
}
37
 
38
/**
39
 * PHPExcel_Reader_Excel2007
40
 *
41
 * @category	PHPExcel
42
 * @package	PHPExcel_Reader
43
 * @copyright	Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)
44
 */
45
class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
46
{
47
	/**
48
	 * PHPExcel_ReferenceHelper instance
49
	 *
50
	 * @var PHPExcel_ReferenceHelper
51
	 */
52
	private $_referenceHelper = NULL;
53
 
54
	/**
55
	 * PHPExcel_Reader_Excel2007_Theme instance
56
	 *
57
	 * @var PHPExcel_Reader_Excel2007_Theme
58
	 */
59
	private static $_theme = NULL;
60
 
61
 
62
	/**
63
	 * Create a new PHPExcel_Reader_Excel2007 instance
64
	 */
65
	public function __construct() {
66
		$this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
67
		$this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance();
68
	}
69
 
70
 
71
	/**
72
	 * Can the current PHPExcel_Reader_IReader read the file?
73
	 *
74
	 * @param 	string 		$pFilename
75
	 * @return 	boolean
76
	 * @throws PHPExcel_Reader_Exception
77
	 */
78
	public function canRead($pFilename)
79
	{
80
		// Check if file exists
81
		if (!file_exists($pFilename)) {
82
			throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
83
		}
84
 
85
		// Check if zip class exists
86
		if (!class_exists('ZipArchive',FALSE)) {
87
			throw new PHPExcel_Reader_Exception("ZipArchive library is not enabled");
88
		}
89
 
90
		$xl = false;
91
		// Load file
92
		$zip = new ZipArchive;
93
		if ($zip->open($pFilename) === true) {
94
			// check if it is an OOXML archive
95
			$rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"));
96
			if ($rels !== false) {
97
				foreach ($rels->Relationship as $rel) {
98
					switch ($rel["Type"]) {
99
						case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
100
							if (basename($rel["Target"]) == 'workbook.xml') {
101
								$xl = true;
102
							}
103
							break;
104
 
105
					}
106
				}
107
			}
108
			$zip->close();
109
		}
110
 
111
		return $xl;
112
	}
113
 
114
 
115
	/**
116
	 * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
117
	 *
118
	 * @param 	string 		$pFilename
119
	 * @throws 	PHPExcel_Reader_Exception
120
	 */
121
	public function listWorksheetNames($pFilename)
122
	{
123
		// Check if file exists
124
		if (!file_exists($pFilename)) {
125
			throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
126
		}
127
 
128
		$worksheetNames = array();
129
 
130
		$zip = new ZipArchive;
131
		$zip->open($pFilename);
132
 
133
		//	The files we're looking at here are small enough that simpleXML is more efficient than XMLReader
134
		$rels = simplexml_load_string(
135
		    $this->_getFromZipArchive($zip, "_rels/.rels")
136
		); //~ http://schemas.openxmlformats.org/package/2006/relationships");
137
		foreach ($rels->Relationship as $rel) {
138
			switch ($rel["Type"]) {
139
				case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
140
					$xmlWorkbook = simplexml_load_string(
141
					    $this->_getFromZipArchive($zip, "{$rel['Target']}")
142
					);  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
143
 
144
					if ($xmlWorkbook->sheets) {
145
						foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
146
							// Check if sheet should be skipped
147
							$worksheetNames[] = (string) $eleSheet["name"];
148
						}
149
					}
150
			}
151
		}
152
 
153
		$zip->close();
154
 
155
		return $worksheetNames;
156
	}
157
 
158
 
159
	/**
160
	 * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
161
	 *
162
	 * @param   string     $pFilename
163
	 * @throws   PHPExcel_Reader_Exception
164
	 */
165
	public function listWorksheetInfo($pFilename)
166
	{
167
		// Check if file exists
168
		if (!file_exists($pFilename)) {
169
			throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
170
		}
171
 
172
		$worksheetInfo = array();
173
 
174
		$zip = new ZipArchive;
175
		$zip->open($pFilename);
176
 
177
		$rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
178
		foreach ($rels->Relationship as $rel) {
179
			if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") {
180
				$dir = dirname($rel["Target"]);
181
				$relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"));  //~ http://schemas.openxmlformats.org/package/2006/relationships");
182
				$relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships");
183
 
184
				$worksheets = array();
185
				foreach ($relsWorkbook->Relationship as $ele) {
186
					if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") {
187
						$worksheets[(string) $ele["Id"]] = $ele["Target"];
188
					}
189
				}
190
 
191
				$xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"));  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
192
				if ($xmlWorkbook->sheets) {
193
					$dir = dirname($rel["Target"]);
194
					foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
195
						$tmpInfo = array(
196
							'worksheetName' => (string) $eleSheet["name"],
197
							'lastColumnLetter' => 'A',
198
							'lastColumnIndex' => 0,
199
							'totalRows' => 0,
200
							'totalColumns' => 0,
201
						);
202
 
203
						$fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
204
 
205
						$xml = new XMLReader();
206
						$res = $xml->open('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet");
207
						$xml->setParserProperty(2,true);
208
 
209
						$currCells = 0;
210
						while ($xml->read()) {
211
							if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) {
212
								$row = $xml->getAttribute('r');
213
								$tmpInfo['totalRows'] = $row;
214
								$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
215
								$currCells = 0;
216
							} elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) {
217
								$currCells++;
218
							}
219
						}
220
						$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
221
						$xml->close();
222
 
223
						$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
224
						$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
225
 
226
						$worksheetInfo[] = $tmpInfo;
227
					}
228
				}
229
			}
230
		}
231
 
232
		$zip->close();
233
 
234
		return $worksheetInfo;
235
	}
236
 
237
 
238
	private static function _castToBool($c) {
239
//		echo 'Initial Cast to Boolean<br />';
240
		$value = isset($c->v) ? (string) $c->v : NULL;
241
		if ($value == '0') {
242
			return FALSE;
243
		} elseif ($value == '1') {
244
			return TRUE;
245
		} else {
246
			return (bool)$c->v;
247
		}
248
		return $value;
249
	}	//	function _castToBool()
250
 
251
 
252
	private static function _castToError($c) {
253
//		echo 'Initial Cast to Error<br />';
254
		return isset($c->v) ? (string) $c->v : NULL;
255
	}	//	function _castToError()
256
 
257
 
258
	private static function _castToString($c) {
259
//		echo 'Initial Cast to String<br />';
260
		return isset($c->v) ? (string) $c->v : NULL;
261
	}	//	function _castToString()
262
 
263
 
264
	private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) {
265
//		echo 'Formula<br />';
266
//		echo '$c->f is '.$c->f.'<br />';
267
		$cellDataType 		= 'f';
268
		$value 				= "={$c->f}";
269
		$calculatedValue 	= self::$castBaseType($c);
270
 
271
		// Shared formula?
272
		if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') {
273
//			echo 'SHARED FORMULA<br />';
274
			$instance = (string)$c->f['si'];
275
 
276
//			echo 'Instance ID = '.$instance.'<br />';
277
//
278
//			echo 'Shared Formula Array:<pre>';
279
//			print_r($sharedFormulas);
280
//			echo '</pre>';
281
			if (!isset($sharedFormulas[(string)$c->f['si']])) {
282
//				echo 'SETTING NEW SHARED FORMULA<br />';
283
//				echo 'Master is '.$r.'<br />';
284
//				echo 'Formula is '.$value.'<br />';
285
				$sharedFormulas[$instance] = array(	'master' => $r,
286
													'formula' => $value
287
												  );
288
//				echo 'New Shared Formula Array:<pre>';
289
//				print_r($sharedFormulas);
290
//				echo '</pre>';
291
			} else {
292
//				echo 'GETTING SHARED FORMULA<br />';
293
//				echo 'Master is '.$sharedFormulas[$instance]['master'].'<br />';
294
//				echo 'Formula is '.$sharedFormulas[$instance]['formula'].'<br />';
295
				$master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']);
296
				$current = PHPExcel_Cell::coordinateFromString($r);
297
 
298
				$difference = array(0, 0);
299
				$difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]);
300
				$difference[1] = $current[1] - $master[1];
301
 
302
				$value = $this->_referenceHelper->updateFormulaReferences(	$sharedFormulas[$instance]['formula'],
303
																			'A1',
304
																			$difference[0],
305
																			$difference[1]
306
																		 );
307
//				echo 'Adjusted Formula is '.$value.'<br />';
308
			}
309
		}
310
	}
311
 
312
 
313
	public function _getFromZipArchive(ZipArchive $archive, $fileName = '')
314
	{
315
		// Root-relative paths
316
		if (strpos($fileName, '//') !== false)
317
		{
318
			$fileName = substr($fileName, strpos($fileName, '//') + 1);
319
		}
320
		$fileName = PHPExcel_Shared_File::realpath($fileName);
321
 
322
		// Apache POI fixes
323
		$contents = $archive->getFromName($fileName);
324
		if ($contents === false)
325
		{
326
			$contents = $archive->getFromName(substr($fileName, 1));
327
		}
328
 
329
		return $contents;
330
	}
331
 
332
 
333
	/**
334
	 * Loads PHPExcel from file
335
	 *
336
	 * @param 	string 		$pFilename
337
	 * @throws 	PHPExcel_Reader_Exception
338
	 */
339
	public function load($pFilename)
340
	{
341
		// Check if file exists
342
		if (!file_exists($pFilename)) {
343
			throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
344
		}
345
 
346
		// Initialisations
347
		$excel = new PHPExcel;
348
		$excel->removeSheetByIndex(0);
349
		if (!$this->_readDataOnly) {
350
			$excel->removeCellStyleXfByIndex(0); // remove the default style
351
			$excel->removeCellXfByIndex(0); // remove the default style
352
		}
353
		$zip = new ZipArchive;
354
		$zip->open($pFilename);
355
 
356
		//	Read the theme first, because we need the colour scheme when reading the styles
357
		$wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
358
		foreach ($wbRels->Relationship as $rel) {
359
			switch ($rel["Type"]) {
360
				case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme":
361
					$themeOrderArray = array('lt1','dk1','lt2','dk2');
362
					$themeOrderAdditional = count($themeOrderArray);
363
 
364
					$xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}"));
365
					if (is_object($xmlTheme)) {
366
						$xmlThemeName = $xmlTheme->attributes();
367
						$xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main");
368
						$themeName = (string)$xmlThemeName['name'];
369
 
370
						$colourScheme = $xmlTheme->themeElements->clrScheme->attributes();
371
						$colourSchemeName = (string)$colourScheme['name'];
372
						$colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main");
373
 
374
						$themeColours = array();
375
						foreach ($colourScheme as $k => $xmlColour) {
376
							$themePos = array_search($k,$themeOrderArray);
377
							if ($themePos === false) {
378
								$themePos = $themeOrderAdditional++;
379
							}
380
							if (isset($xmlColour->sysClr)) {
381
								$xmlColourData = $xmlColour->sysClr->attributes();
382
								$themeColours[$themePos] = $xmlColourData['lastClr'];
383
							} elseif (isset($xmlColour->srgbClr)) {
384
								$xmlColourData = $xmlColour->srgbClr->attributes();
385
								$themeColours[$themePos] = $xmlColourData['val'];
386
							}
387
						}
388
						self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours);
389
					}
390
					break;
391
			}
392
		}
393
 
394
		$rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
395
		foreach ($rels->Relationship as $rel) {
396
			switch ($rel["Type"]) {
397
				case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties":
398
					$xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"));
399
					if (is_object($xmlCore)) {
400
						$xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/");
401
						$xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/");
402
						$xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
403
						$docProps = $excel->getProperties();
404
						$docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator")));
405
						$docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy")));
406
						$docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type
407
						$docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type
408
						$docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title")));
409
						$docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description")));
410
						$docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject")));
411
						$docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords")));
412
						$docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category")));
413
					}
414
				break;
415
 
416
				case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties":
417
					$xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"));
418
					if (is_object($xmlCore)) {
419
						$docProps = $excel->getProperties();
420
						if (isset($xmlCore->Company))
421
							$docProps->setCompany((string) $xmlCore->Company);
422
						if (isset($xmlCore->Manager))
423
							$docProps->setManager((string) $xmlCore->Manager);
424
					}
425
				break;
426
 
427
				case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties":
428
					$xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"));
429
					if (is_object($xmlCore)) {
430
						$docProps = $excel->getProperties();
431
						foreach ($xmlCore as $xmlProperty) {
432
							$cellDataOfficeAttributes = $xmlProperty->attributes();
433
							if (isset($cellDataOfficeAttributes['name'])) {
434
								$propertyName = (string) $cellDataOfficeAttributes['name'];
435
								$cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
436
								$attributeType = $cellDataOfficeChildren->getName();
437
								$attributeValue = (string) $cellDataOfficeChildren->{$attributeType};
438
								$attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType);
439
								$attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType);
440
								$docProps->setCustomProperty($propertyName,$attributeValue,$attributeType);
441
							}
442
						}
443
					}
444
				break;
445
 
446
				case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
447
					$dir = dirname($rel["Target"]);
448
					$relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"));  //~ http://schemas.openxmlformats.org/package/2006/relationships");
449
					$relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships");
450
 
451
					$sharedStrings = array();
452
					$xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']"));
453
					$xmlStrings = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"));  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
454
					if (isset($xmlStrings) && isset($xmlStrings->si)) {
455
						foreach ($xmlStrings->si as $val) {
456
							if (isset($val->t)) {
457
								$sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t );
458
							} elseif (isset($val->r)) {
459
								$sharedStrings[] = $this->_parseRichText($val);
460
							}
461
						}
462
					}
463
 
464
					$worksheets = array();
465
					foreach ($relsWorkbook->Relationship as $ele) {
466
						if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") {
467
							$worksheets[(string) $ele["Id"]] = $ele["Target"];
468
						}
469
					}
470
 
471
					$styles 	= array();
472
					$cellStyles = array();
473
					$xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']"));
474
					$xmlStyles = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
475
					$numFmts = null;
476
					if ($xmlStyles && $xmlStyles->numFmts[0]) {
477
						$numFmts = $xmlStyles->numFmts[0];
478
					}
479
					if (isset($numFmts) && ($numFmts !== NULL)) {
480
						$numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
481
					}
482
					if (!$this->_readDataOnly && $xmlStyles) {
483
						foreach ($xmlStyles->cellXfs->xf as $xf) {
484
							$numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
485
 
486
							if ($xf["numFmtId"]) {
487
								if (isset($numFmts)) {
488
									$tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
489
 
490
									if (isset($tmpNumFmt["formatCode"])) {
491
										$numFmt = (string) $tmpNumFmt["formatCode"];
492
									}
493
								}
494
 
495
								if ((int)$xf["numFmtId"] < 164) {
496
									$numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]);
497
								}
498
							}
499
							//$numFmt = str_replace('mm', 'i', $numFmt);
500
							//$numFmt = str_replace('h', 'H', $numFmt);
501
 
502
							$style = (object) array(
503
								"numFmt" => $numFmt,
504
								"font" => $xmlStyles->fonts->font[intval($xf["fontId"])],
505
								"fill" => $xmlStyles->fills->fill[intval($xf["fillId"])],
506
								"border" => $xmlStyles->borders->border[intval($xf["borderId"])],
507
								"alignment" => $xf->alignment,
508
								"protection" => $xf->protection,
509
							);
510
							$styles[] = $style;
511
 
512
							// add style to cellXf collection
513
							$objStyle = new PHPExcel_Style;
514
							self::_readStyle($objStyle, $style);
515
							$excel->addCellXf($objStyle);
516
						}
517
 
518
						foreach ($xmlStyles->cellStyleXfs->xf as $xf) {
519
							$numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
520
							if ($numFmts && $xf["numFmtId"]) {
521
								$tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
522
								if (isset($tmpNumFmt["formatCode"])) {
523
									$numFmt = (string) $tmpNumFmt["formatCode"];
524
								} else if ((int)$xf["numFmtId"] < 165) {
525
									$numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]);
526
								}
527
							}
528
 
529
							$cellStyle = (object) array(
530
								"numFmt" => $numFmt,
531
								"font" => $xmlStyles->fonts->font[intval($xf["fontId"])],
532
								"fill" => $xmlStyles->fills->fill[intval($xf["fillId"])],
533
								"border" => $xmlStyles->borders->border[intval($xf["borderId"])],
534
								"alignment" => $xf->alignment,
535
								"protection" => $xf->protection,
536
							);
537
							$cellStyles[] = $cellStyle;
538
 
539
							// add style to cellStyleXf collection
540
							$objStyle = new PHPExcel_Style;
541
							self::_readStyle($objStyle, $cellStyle);
542
							$excel->addCellStyleXf($objStyle);
543
						}
544
					}
545
 
546
					$dxfs = array();
547
					if (!$this->_readDataOnly && $xmlStyles) {
548
						//	Conditional Styles
549
						if ($xmlStyles->dxfs) {
550
							foreach ($xmlStyles->dxfs->dxf as $dxf) {
551
								$style = new PHPExcel_Style(FALSE, TRUE);
552
								self::_readStyle($style, $dxf);
553
								$dxfs[] = $style;
554
							}
555
						}
556
						//	Cell Styles
557
						if ($xmlStyles->cellStyles) {
558
							foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) {
559
								if (intval($cellStyle['builtinId']) == 0) {
560
									if (isset($cellStyles[intval($cellStyle['xfId'])])) {
561
										// Set default style
562
										$style = new PHPExcel_Style;
563
										self::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]);
564
 
565
										// normal style, currently not using it for anything
566
									}
567
								}
568
							}
569
						}
570
					}
571
 
572
					$xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"));  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
573
 
574
					// Set base date
575
					if ($xmlWorkbook->workbookPr) {
576
						PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);
577
						if (isset($xmlWorkbook->workbookPr['date1904'])) {
578
							if (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) {
579
								PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);
580
							}
581
						}
582
					}
583
 
584
					$sheetId = 0; // keep track of new sheet id in final workbook
585
					$oldSheetId = -1; // keep track of old sheet id in final workbook
586
					$countSkippedSheets = 0; // keep track of number of skipped sheets
587
					$mapSheetId = array(); // mapping of sheet ids from old to new
588
 
589
 
590
					$charts = $chartDetails = array();
591
 
592
					if ($xmlWorkbook->sheets) {
593
						foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
594
							++$oldSheetId;
595
 
596
							// Check if sheet should be skipped
597
							if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) {
598
								++$countSkippedSheets;
599
								$mapSheetId[$oldSheetId] = null;
600
								continue;
601
							}
602
 
603
							// Map old sheet id in original workbook to new sheet id.
604
							// They will differ if loadSheetsOnly() is being used
605
							$mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets;
606
 
607
							// Load sheet
608
							$docSheet = $excel->createSheet();
609
							//	Use false for $updateFormulaCellReferences to prevent adjustment of worksheet
610
							//		references in formula cells... during the load, all formulae should be correct,
611
							//		and we're simply bringing the worksheet name in line with the formula, not the
612
							//		reverse
613
							$docSheet->setTitle((string) $eleSheet["name"],false);
614
							$fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
615
							$xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet"));  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
616
 
617
							$sharedFormulas = array();
618
 
619
							if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') {
620
								$docSheet->setSheetState( (string) $eleSheet["state"] );
621
							}
622
 
623
							if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) {
624
							    if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) {
625
								    $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) );
626
								}
627
 
628
							    if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) {
629
								    $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) );
630
								}
631
 
632
							    if (isset($xmlSheet->sheetViews->sheetView['view'])) {
633
								    $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']);
634
								}
635
 
636
								if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) {
637
									$docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines']));
638
								}
639
 
640
								if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) {
641
									$docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders']));
642
								}
643
 
644
								if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) {
645
									$docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft']));
646
								}
647
 
648
								if (isset($xmlSheet->sheetViews->sheetView->pane)) {
649
								    if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) {
650
								        $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] );
651
								    } else {
652
								        $xSplit = 0;
653
								        $ySplit = 0;
654
 
655
								        if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) {
656
								            $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']);
657
								        }
658
 
659
								    	if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) {
660
								            $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']);
661
								        }
662
 
663
								        $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit);
664
								    }
665
								}
666
 
667
								if (isset($xmlSheet->sheetViews->sheetView->selection)) {
668
									if (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) {
669
										$sqref = (string)$xmlSheet->sheetViews->sheetView->selection['sqref'];
670
										$sqref = explode(' ', $sqref);
671
										$sqref = $sqref[0];
672
										$docSheet->setSelectedCells($sqref);
673
									}
674
								}
675
 
676
							}
677
 
678
							if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) {
679
								if (isset($xmlSheet->sheetPr->tabColor['rgb'])) {
680
									$docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] );
681
								}
682
							}
683
 
684
							if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) {
685
								if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) &&
686
									!self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) {
687
									$docSheet->setShowSummaryRight(FALSE);
688
								} else {
689
									$docSheet->setShowSummaryRight(TRUE);
690
								}
691
 
692
								if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) &&
693
									!self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) {
694
									$docSheet->setShowSummaryBelow(FALSE);
695
								} else {
696
									$docSheet->setShowSummaryBelow(TRUE);
697
								}
698
							}
699
 
700
							if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) {
701
								if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) &&
702
									!self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) {
703
									$docSheet->getPageSetup()->setFitToPage(FALSE);
704
								} else {
705
									$docSheet->getPageSetup()->setFitToPage(TRUE);
706
								}
707
							}
708
 
709
							if (isset($xmlSheet->sheetFormatPr)) {
710
								if (isset($xmlSheet->sheetFormatPr['customHeight']) &&
711
									self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) &&
712
									isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) {
713
									$docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] );
714
								}
715
								if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) {
716
									$docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] );
717
								}
718
								if (isset($xmlSheet->sheetFormatPr['zeroHeight']) &&
719
									((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) {
720
									$docSheet->getDefaultRowDimension()->setzeroHeight(true);
721
								}
722
							}
723
 
724
							if (isset($xmlSheet->cols) && !$this->_readDataOnly) {
725
								foreach ($xmlSheet->cols->col as $col) {
726
									for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) {
727
										if ($col["style"] && !$this->_readDataOnly) {
728
											$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"]));
729
										}
730
										if (self::boolean($col["bestFit"])) {
731
											//$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE);
732
										}
733
										if (self::boolean($col["hidden"])) {
734
											$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE);
735
										}
736
										if (self::boolean($col["collapsed"])) {
737
											$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE);
738
										}
739
										if ($col["outlineLevel"] > 0) {
740
											$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"]));
741
										}
742
										$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col["width"]));
743
 
744
										if (intval($col["max"]) == 16384) {
745
											break;
746
										}
747
									}
748
								}
749
							}
750
 
751
							if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) {
752
								if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) {
753
									$docSheet->setShowGridlines(TRUE);
754
								}
755
 
756
								if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) {
757
									$docSheet->setPrintGridlines(TRUE);
758
								}
759
 
760
								if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) {
761
									$docSheet->getPageSetup()->setHorizontalCentered(TRUE);
762
								}
763
								if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) {
764
									$docSheet->getPageSetup()->setVerticalCentered(TRUE);
765
								}
766
							}
767
 
768
							if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {
769
								foreach ($xmlSheet->sheetData->row as $row) {
770
									if ($row["ht"] && !$this->_readDataOnly) {
771
										$docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"]));
772
									}
773
									if (self::boolean($row["hidden"]) && !$this->_readDataOnly) {
774
										$docSheet->getRowDimension(intval($row["r"]))->setVisible(FALSE);
775
									}
776
									if (self::boolean($row["collapsed"])) {
777
										$docSheet->getRowDimension(intval($row["r"]))->setCollapsed(TRUE);
778
									}
779
									if ($row["outlineLevel"] > 0) {
780
										$docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"]));
781
									}
782
									if ($row["s"] && !$this->_readDataOnly) {
783
										$docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"]));
784
									}
785
 
786
									foreach ($row->c as $c) {
787
										$r 					= (string) $c["r"];
788
										$cellDataType 		= (string) $c["t"];
789
										$value				= null;
790
										$calculatedValue 	= null;
791
 
792
										// Read cell?
793
										if ($this->getReadFilter() !== NULL) {
794
											$coordinates = PHPExcel_Cell::coordinateFromString($r);
795
 
796
											if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) {
797
												continue;
798
											}
799
										}
800
 
801
	//									echo '<b>Reading cell '.$coordinates[0].$coordinates[1].'</b><br />';
802
	//									print_r($c);
803
	//									echo '<br />';
804
	//									echo 'Cell Data Type is '.$cellDataType.': ';
805
	//
806
										// Read cell!
807
										switch ($cellDataType) {
808
											case "s":
809
	//											echo 'String<br />';
810
												if ((string)$c->v != '') {
811
													$value = $sharedStrings[intval($c->v)];
812
 
813
													if ($value instanceof PHPExcel_RichText) {
814
														$value = clone $value;
815
													}
816
												} else {
817
													$value = '';
818
												}
819
 
820
												break;
821
											case "b":
822
	//											echo 'Boolean<br />';
823
												if (!isset($c->f)) {
824
													$value = self::_castToBool($c);
825
												} else {
826
													// Formula
827
													$this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool');
828
													if (isset($c->f['t'])) {
829
														$att = array();
830
														$att = $c->f;
831
														$docSheet->getCell($r)->setFormulaAttributes($att);
832
													}
833
	//												echo '$calculatedValue = '.$calculatedValue.'<br />';
834
												}
835
												break;
836
											case "inlineStr":
837
	//											echo 'Inline String<br />';
838
												$value = $this->_parseRichText($c->is);
839
 
840
												break;
841
											case "e":
842
	//											echo 'Error<br />';
843
												if (!isset($c->f)) {
844
													$value = self::_castToError($c);
845
												} else {
846
													// Formula
847
													$this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError');
848
	//												echo '$calculatedValue = '.$calculatedValue.'<br />';
849
												}
850
 
851
												break;
852
 
853
											default:
854
	//											echo 'Default<br />';
855
												if (!isset($c->f)) {
856
	//												echo 'Not a Formula<br />';
857
													$value = self::_castToString($c);
858
												} else {
859
	//												echo 'Treat as Formula<br />';
860
													// Formula
861
													$this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString');
862
	//												echo '$calculatedValue = '.$calculatedValue.'<br />';
863
												}
864
 
865
												break;
866
										}
867
	//									echo 'Value is '.$value.'<br />';
868
 
869
										// Check for numeric values
870
										if (is_numeric($value) && $cellDataType != 's') {
871
											if ($value == (int)$value) $value = (int)$value;
872
											elseif ($value == (float)$value) $value = (float)$value;
873
											elseif ($value == (double)$value) $value = (double)$value;
874
										}
875
 
876
										// Rich text?
877
										if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) {
878
											$value = $value->getPlainText();
879
										}
880
 
881
										$cell = $docSheet->getCell($r);
882
										// Assign value
883
										if ($cellDataType != '') {
884
											$cell->setValueExplicit($value, $cellDataType);
885
										} else {
886
											$cell->setValue($value);
887
										}
888
										if ($calculatedValue !== NULL) {
889
											$cell->setCalculatedValue($calculatedValue);
890
										}
891
 
892
										// Style information?
893
										if ($c["s"] && !$this->_readDataOnly) {
894
											// no style index means 0, it seems
895
											$cell->setXfIndex(isset($styles[intval($c["s"])]) ?
896
												intval($c["s"]) : 0);
897
										}
898
									}
899
								}
900
							}
901
 
902
							$conditionals = array();
903
							if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) {
904
								foreach ($xmlSheet->conditionalFormatting as $conditional) {
905
									foreach ($conditional->cfRule as $cfRule) {
906
										if (
907
											(
908
												(string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE ||
909
												(string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS ||
910
												(string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT ||
911
												(string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION
912
											) && isset($dxfs[intval($cfRule["dxfId"])])
913
										) {
914
											$conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule;
915
										}
916
									}
917
								}
918
 
919
								foreach ($conditionals as $ref => $cfRules) {
920
									ksort($cfRules);
921
									$conditionalStyles = array();
922
									foreach ($cfRules as $cfRule) {
923
										$objConditional = new PHPExcel_Style_Conditional();
924
										$objConditional->setConditionType((string)$cfRule["type"]);
925
										$objConditional->setOperatorType((string)$cfRule["operator"]);
926
 
927
										if ((string)$cfRule["text"] != '') {
928
											$objConditional->setText((string)$cfRule["text"]);
929
										}
930
 
931
										if (count($cfRule->formula) > 1) {
932
											foreach ($cfRule->formula as $formula) {
933
												$objConditional->addCondition((string)$formula);
934
											}
935
										} else {
936
											$objConditional->addCondition((string)$cfRule->formula);
937
										}
938
										$objConditional->setStyle(clone $dxfs[intval($cfRule["dxfId"])]);
939
										$conditionalStyles[] = $objConditional;
940
									}
941
 
942
									// Extract all cell references in $ref
943
									$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref);
944
									foreach ($aReferences as $reference) {
945
										$docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles);
946
									}
947
								}
948
							}
949
 
950
							$aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells");
951
							if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
952
								foreach ($aKeys as $key) {
953
									$method = "set" . ucfirst($key);
954
									$docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key]));
955
								}
956
							}
957
 
958
							if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
959
								$docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], TRUE);
960
								if ($xmlSheet->protectedRanges->protectedRange) {
961
									foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) {
962
										$docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true);
963
									}
964
								}
965
							}
966
 
967
							if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) {
968
								$autoFilter = $docSheet->getAutoFilter();
969
								$autoFilter->setRange((string) $xmlSheet->autoFilter["ref"]);
970
								foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) {
971
									$column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]);
972
									//	Check for standard filters
973
									if ($filterColumn->filters) {
974
										$column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER);
975
										$filters = $filterColumn->filters;
976
										if ((isset($filters["blank"])) && ($filters["blank"] == 1)) {
977
											$column->createRule()->setRule(
978
												NULL,	//	Operator is undefined, but always treated as EQUAL
979
												''
980
											)
981
											->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER);
982
										}
983
										//	Standard filters are always an OR join, so no join rule needs to be set
984
										//	Entries can be either filter elements
985
										foreach ($filters->filter as $filterRule) {
986
											$column->createRule()->setRule(
987
												NULL,	//	Operator is undefined, but always treated as EQUAL
988
												(string) $filterRule["val"]
989
											)
990
											->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER);
991
										}
992
										//	Or Date Group elements
993
										foreach ($filters->dateGroupItem as $dateGroupItem) {
994
											$column->createRule()->setRule(
995
												NULL,	//	Operator is undefined, but always treated as EQUAL
996
												array(
997
													'year' => (string) $dateGroupItem["year"],
998
													'month' => (string) $dateGroupItem["month"],
999
													'day' => (string) $dateGroupItem["day"],
1000
													'hour' => (string) $dateGroupItem["hour"],
1001
													'minute' => (string) $dateGroupItem["minute"],
1002
													'second' => (string) $dateGroupItem["second"],
1003
												),
1004
												(string) $dateGroupItem["dateTimeGrouping"]
1005
											)
1006
											->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP);
1007
										}
1008
									}
1009
									//	Check for custom filters
1010
									if ($filterColumn->customFilters) {
1011
										$column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
1012
										$customFilters = $filterColumn->customFilters;
1013
										//	Custom filters can an AND or an OR join;
1014
										//		and there should only ever be one or two entries
1015
										if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) {
1016
											$column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND);
1017
										}
1018
										foreach ($customFilters->customFilter as $filterRule) {
1019
											$column->createRule()->setRule(
1020
												(string) $filterRule["operator"],
1021
												(string) $filterRule["val"]
1022
											)
1023
											->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
1024
										}
1025
									}
1026
									//	Check for dynamic filters
1027
									if ($filterColumn->dynamicFilter) {
1028
										$column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
1029
										//	We should only ever have one dynamic filter
1030
										foreach ($filterColumn->dynamicFilter as $filterRule) {
1031
											$column->createRule()->setRule(
1032
												NULL,	//	Operator is undefined, but always treated as EQUAL
1033
												(string) $filterRule["val"],
1034
												(string) $filterRule["type"]
1035
											)
1036
											->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
1037
											if (isset($filterRule["val"])) {
1038
												$column->setAttribute('val',(string) $filterRule["val"]);
1039
											}
1040
											if (isset($filterRule["maxVal"])) {
1041
												$column->setAttribute('maxVal',(string) $filterRule["maxVal"]);
1042
											}
1043
										}
1044
									}
1045
									//	Check for dynamic filters
1046
									if ($filterColumn->top10) {
1047
										$column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);
1048
										//	We should only ever have one top10 filter
1049
										foreach ($filterColumn->top10 as $filterRule) {
1050
											$column->createRule()->setRule(
1051
												(((isset($filterRule["percent"])) && ($filterRule["percent"] == 1))
1052
													? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT
1053
													: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE
1054
												),
1055
												(string) $filterRule["val"],
1056
												(((isset($filterRule["top"])) && ($filterRule["top"] == 1))
1057
													? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP
1058
													: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM
1059
												)
1060
											)
1061
											->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);
1062
										}
1063
									}
1064
								}
1065
							}
1066
 
1067
							if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) {
1068
								foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) {
1069
									$mergeRef = (string) $mergeCell["ref"];
1070
									if (strpos($mergeRef,':') !== FALSE) {
1071
										$docSheet->mergeCells((string) $mergeCell["ref"]);
1072
									}
1073
								}
1074
							}
1075
 
1076
							if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) {
1077
								$docPageMargins = $docSheet->getPageMargins();
1078
								$docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"]));
1079
								$docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"]));
1080
								$docPageMargins->setTop(floatval($xmlSheet->pageMargins["top"]));
1081
								$docPageMargins->setBottom(floatval($xmlSheet->pageMargins["bottom"]));
1082
								$docPageMargins->setHeader(floatval($xmlSheet->pageMargins["header"]));
1083
								$docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"]));
1084
							}
1085
 
1086
							if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) {
1087
								$docPageSetup = $docSheet->getPageSetup();
1088
 
1089
								if (isset($xmlSheet->pageSetup["orientation"])) {
1090
									$docPageSetup->setOrientation((string) $xmlSheet->pageSetup["orientation"]);
1091
								}
1092
								if (isset($xmlSheet->pageSetup["paperSize"])) {
1093
									$docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"]));
1094
								}
1095
								if (isset($xmlSheet->pageSetup["scale"])) {
1096
									$docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), FALSE);
1097
								}
1098
								if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) {
1099
									$docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), FALSE);
1100
								}
1101
								if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) {
1102
									$docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), FALSE);
1103
								}
1104
								if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) &&
1105
									self::boolean((string) $xmlSheet->pageSetup["useFirstPageNumber"])) {
1106
									$docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"]));
1107
								}
1108
							}
1109
 
1110
							if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) {
1111
								$docHeaderFooter = $docSheet->getHeaderFooter();
1112
 
1113
								if (isset($xmlSheet->headerFooter["differentOddEven"]) &&
1114
									self::boolean((string)$xmlSheet->headerFooter["differentOddEven"])) {
1115
									$docHeaderFooter->setDifferentOddEven(TRUE);
1116
								} else {
1117
									$docHeaderFooter->setDifferentOddEven(FALSE);
1118
								}
1119
								if (isset($xmlSheet->headerFooter["differentFirst"]) &&
1120
									self::boolean((string)$xmlSheet->headerFooter["differentFirst"])) {
1121
									$docHeaderFooter->setDifferentFirst(TRUE);
1122
								} else {
1123
									$docHeaderFooter->setDifferentFirst(FALSE);
1124
								}
1125
								if (isset($xmlSheet->headerFooter["scaleWithDoc"]) &&
1126
									!self::boolean((string)$xmlSheet->headerFooter["scaleWithDoc"])) {
1127
									$docHeaderFooter->setScaleWithDocument(FALSE);
1128
								} else {
1129
									$docHeaderFooter->setScaleWithDocument(TRUE);
1130
								}
1131
								if (isset($xmlSheet->headerFooter["alignWithMargins"]) &&
1132
									!self::boolean((string)$xmlSheet->headerFooter["alignWithMargins"])) {
1133
									$docHeaderFooter->setAlignWithMargins(FALSE);
1134
								} else {
1135
									$docHeaderFooter->setAlignWithMargins(TRUE);
1136
								}
1137
 
1138
								$docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader);
1139
								$docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter);
1140
								$docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader);
1141
								$docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter);
1142
								$docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader);
1143
								$docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter);
1144
							}
1145
 
1146
							if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) {
1147
								foreach ($xmlSheet->rowBreaks->brk as $brk) {
1148
									if ($brk["man"]) {
1149
										$docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW);
1150
									}
1151
								}
1152
							}
1153
							if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) {
1154
								foreach ($xmlSheet->colBreaks->brk as $brk) {
1155
									if ($brk["man"]) {
1156
										$docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN);
1157
									}
1158
								}
1159
							}
1160
 
1161
							if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) {
1162
								foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) {
1163
								    // Uppercase coordinate
1164
							    	$range = strtoupper($dataValidation["sqref"]);
1165
									$rangeSet = explode(' ',$range);
1166
									foreach($rangeSet as $range) {
1167
										$stRange = $docSheet->shrinkRangeToFit($range);
1168
 
1169
										// Extract all cell references in $range
1170
										$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange);
1171
										foreach ($aReferences as $reference) {
1172
											// Create validation
1173
											$docValidation = $docSheet->getCell($reference)->getDataValidation();
1174
											$docValidation->setType((string) $dataValidation["type"]);
1175
											$docValidation->setErrorStyle((string) $dataValidation["errorStyle"]);
1176
											$docValidation->setOperator((string) $dataValidation["operator"]);
1177
											$docValidation->setAllowBlank($dataValidation["allowBlank"] != 0);
1178
											$docValidation->setShowDropDown($dataValidation["showDropDown"] == 0);
1179
											$docValidation->setShowInputMessage($dataValidation["showInputMessage"] != 0);
1180
											$docValidation->setShowErrorMessage($dataValidation["showErrorMessage"] != 0);
1181
											$docValidation->setErrorTitle((string) $dataValidation["errorTitle"]);
1182
											$docValidation->setError((string) $dataValidation["error"]);
1183
											$docValidation->setPromptTitle((string) $dataValidation["promptTitle"]);
1184
											$docValidation->setPrompt((string) $dataValidation["prompt"]);
1185
											$docValidation->setFormula1((string) $dataValidation->formula1);
1186
											$docValidation->setFormula2((string) $dataValidation->formula2);
1187
										}
1188
									}
1189
								}
1190
							}
1191
 
1192
							// Add hyperlinks
1193
							$hyperlinks = array();
1194
							if (!$this->_readDataOnly) {
1195
								// Locate hyperlink relations
1196
								if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
1197
									$relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip,  dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
1198
									foreach ($relsWorksheet->Relationship as $ele) {
1199
										if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") {
1200
											$hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"];
1201
										}
1202
									}
1203
								}
1204
 
1205
								// Loop through hyperlinks
1206
								if ($xmlSheet && $xmlSheet->hyperlinks) {
1207
									foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) {
1208
										// Link url
1209
										$linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
1210
 
1211
										foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) {
1212
											$cell = $docSheet->getCell( $cellReference );
1213
											if (isset($linkRel['id'])) {
1214
												$hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ];
1215
												if (isset($hyperlink['location'])) {
1216
													$hyperlinkUrl .= '#' . (string) $hyperlink['location'];
1217
												}
1218
												$cell->getHyperlink()->setUrl($hyperlinkUrl);
1219
											} elseif (isset($hyperlink['location'])) {
1220
												$cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] );
1221
											}
1222
 
1223
											// Tooltip
1224
											if (isset($hyperlink['tooltip'])) {
1225
												$cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] );
1226
											}
1227
										}
1228
									}
1229
								}
1230
							}
1231
 
1232
							// Add comments
1233
							$comments = array();
1234
							$vmlComments = array();
1235
							if (!$this->_readDataOnly) {
1236
								// Locate comment relations
1237
								if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
1238
									$relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip,  dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
1239
									foreach ($relsWorksheet->Relationship as $ele) {
1240
									    if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") {
1241
											$comments[(string)$ele["Id"]] = (string)$ele["Target"];
1242
										}
1243
									    if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") {
1244
											$vmlComments[(string)$ele["Id"]] = (string)$ele["Target"];
1245
										}
1246
									}
1247
								}
1248
 
1249
								// Loop through comments
1250
								foreach ($comments as $relName => $relPath) {
1251
									// Load comments file
1252
									$relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath);
1253
									$commentsFile = simplexml_load_string($this->_getFromZipArchive($zip, $relPath) );
1254
 
1255
									// Utility variables
1256
									$authors = array();
1257
 
1258
									// Loop through authors
1259
									foreach ($commentsFile->authors->author as $author) {
1260
										$authors[] = (string)$author;
1261
									}
1262
 
1263
									// Loop through contents
1264
									foreach ($commentsFile->commentList->comment as $comment) {
1265
										$docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] );
1266
										$docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) );
1267
									}
1268
								}
1269
 
1270
								// Loop through VML comments
1271
							    foreach ($vmlComments as $relName => $relPath) {
1272
									// Load VML comments file
1273
									$relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath);
1274
									$vmlCommentsFile = simplexml_load_string( $this->_getFromZipArchive($zip, $relPath) );
1275
									$vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1276
 
1277
									$shapes = $vmlCommentsFile->xpath('//v:shape');
1278
									foreach ($shapes as $shape) {
1279
										$shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1280
 
1281
										if (isset($shape['style'])) {
1282
	    									$style        = (string)$shape['style'];
1283
	    									$fillColor    = strtoupper( substr( (string)$shape['fillcolor'], 1 ) );
1284
	    									$column       = null;
1285
	    									$row          = null;
1286
 
1287
	    									$clientData   = $shape->xpath('.//x:ClientData');
1288
	    									if (is_array($clientData) && !empty($clientData)) {
1289
	        									$clientData   = $clientData[0];
1290
 
1291
	        									if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) {
1292
	        									    $temp = $clientData->xpath('.//x:Row');
1293
	        									    if (is_array($temp)) $row = $temp[0];
1294
 
1295
	        									    $temp = $clientData->xpath('.//x:Column');
1296
	        									    if (is_array($temp)) $column = $temp[0];
1297
	        									}
1298
	    									}
1299
 
1300
	    									if (($column !== NULL) && ($row !== NULL)) {
1301
	    									    // Set comment properties
1302
	    									    $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1);
1303
	    									    $comment->getFillColor()->setRGB( $fillColor );
1304
 
1305
	    									    // Parse style
1306
	    									    $styleArray = explode(';', str_replace(' ', '', $style));
1307
	    									    foreach ($styleArray as $stylePair) {
1308
	    									        $stylePair = explode(':', $stylePair);
1309
 
1310
	    									        if ($stylePair[0] == 'margin-left')     $comment->setMarginLeft($stylePair[1]);
1311
	    									        if ($stylePair[0] == 'margin-top')      $comment->setMarginTop($stylePair[1]);
1312
	    									        if ($stylePair[0] == 'width')           $comment->setWidth($stylePair[1]);
1313
	    									        if ($stylePair[0] == 'height')          $comment->setHeight($stylePair[1]);
1314
	    									        if ($stylePair[0] == 'visibility')      $comment->setVisible( $stylePair[1] == 'visible' );
1315
 
1316
	    									    }
1317
	    									}
1318
										}
1319
									}
1320
								}
1321
 
1322
								// Header/footer images
1323
								if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) {
1324
									if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
1325
										$relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip,  dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
1326
										$vmlRelationship = '';
1327
 
1328
										foreach ($relsWorksheet->Relationship as $ele) {
1329
											if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") {
1330
												$vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]);
1331
											}
1332
										}
1333
 
1334
										if ($vmlRelationship != '') {
1335
											// Fetch linked images
1336
											$relsVML = simplexml_load_string($this->_getFromZipArchive($zip,  dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' )); //~ http://schemas.openxmlformats.org/package/2006/relationships");
1337
											$drawings = array();
1338
											foreach ($relsVML->Relationship as $ele) {
1339
												if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") {
1340
													$drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]);
1341
												}
1342
											}
1343
 
1344
											// Fetch VML document
1345
											$vmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $vmlRelationship));
1346
											$vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1347
 
1348
											$hfImages = array();
1349
 
1350
											$shapes = $vmlDrawing->xpath('//v:shape');
1351
											foreach ($shapes as $shape) {
1352
												$shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1353
												$imageData = $shape->xpath('//v:imagedata');
1354
												$imageData = $imageData[0];
1355
 
1356
												$imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office');
1357
												$style = self::toCSSArray( (string)$shape['style'] );
1358
 
1359
												$hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing();
1360
												if (isset($imageData['title'])) {
1361
													$hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] );
1362
												}
1363
 
1364
												$hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false);
1365
												$hfImages[ (string)$shape['id'] ]->setResizeProportional(false);
1366
												$hfImages[ (string)$shape['id'] ]->setWidth($style['width']);
1367
												$hfImages[ (string)$shape['id'] ]->setHeight($style['height']);
1368
												$hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']);
1369
												$hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']);
1370
												$hfImages[ (string)$shape['id'] ]->setResizeProportional(true);
1371
											}
1372
 
1373
											$docSheet->getHeaderFooter()->setImages($hfImages);
1374
										}
1375
									}
1376
								}
1377
 
1378
							}
1379
 
1380
// TODO: Autoshapes from twoCellAnchors!
1381
							if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
1382
								$relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip,  dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
1383
								$drawings = array();
1384
								foreach ($relsWorksheet->Relationship as $ele) {
1385
									if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") {
1386
										$drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]);
1387
									}
1388
								}
1389
								if ($xmlSheet->drawing && !$this->_readDataOnly) {
1390
									foreach ($xmlSheet->drawing as $drawing) {
1391
										$fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
1392
										$relsDrawing = simplexml_load_string($this->_getFromZipArchive($zip,  dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
1393
										$images = array();
1394
 
1395
										if ($relsDrawing && $relsDrawing->Relationship) {
1396
											foreach ($relsDrawing->Relationship as $ele) {
1397
												if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") {
1398
													$images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]);
1399
												} elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") {
1400
													if ($this->_includeCharts) {
1401
														$charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id'		=> (string) $ele["Id"],
1402
																													 'sheet'	=> $docSheet->getTitle()
1403
																													);
1404
													}
1405
												}
1406
											}
1407
										}
1408
										$xmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $fileDrawing))->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
1409
 
1410
										if ($xmlDrawing->oneCellAnchor) {
1411
											foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) {
1412
												if ($oneCellAnchor->pic->blipFill) {
1413
													$blip = $oneCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip;
1414
													$xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm;
1415
													$outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw;
1416
													$objDrawing = new PHPExcel_Worksheet_Drawing;
1417
													$objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name"));
1418
													$objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr"));
1419
													$objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false);
1420
													$objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1));
1421
													$objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff));
1422
													$objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff));
1423
													$objDrawing->setResizeProportional(false);
1424
													$objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")));
1425
													$objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")));
1426
													if ($xfrm) {
1427
														$objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot")));
1428
													}
1429
													if ($outerShdw) {
1430
														$shadow = $objDrawing->getShadow();
1431
														$shadow->setVisible(true);
1432
														$shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad")));
1433
														$shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist")));
1434
														$shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir")));
1435
														$shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn"));
1436
														$shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val"));
1437
														$shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000);
1438
													}
1439
													$objDrawing->setWorksheet($docSheet);
1440
												} else {
1441
													//	? Can charts be positioned with a oneCellAnchor ?
1442
													$coordinates	= PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1);
1443
													$offsetX		= PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff);
1444
													$offsetY		= PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff);
1445
													$width			= PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx"));
1446
													$height			= PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy"));
1447
												}
1448
											}
1449
										}
1450
										if ($xmlDrawing->twoCellAnchor) {
1451
											foreach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) {
1452
												if ($twoCellAnchor->pic->blipFill) {
1453
													$blip = $twoCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip;
1454
													$xfrm = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm;
1455
													$outerShdw = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw;
1456
													$objDrawing = new PHPExcel_Worksheet_Drawing;
1457
													$objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name"));
1458
													$objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr"));
1459
													$objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false);
1460
													$objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1));
1461
													$objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff));
1462
													$objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff));
1463
													$objDrawing->setResizeProportional(false);
1464
 
1465
													$objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx")));
1466
													$objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy")));
1467
 
1468
													if ($xfrm) {
1469
														$objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot")));
1470
													}
1471
													if ($outerShdw) {
1472
														$shadow = $objDrawing->getShadow();
1473
														$shadow->setVisible(true);
1474
														$shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad")));
1475
														$shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist")));
1476
														$shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir")));
1477
														$shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn"));
1478
														$shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val"));
1479
														$shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000);
1480
													}
1481
													$objDrawing->setWorksheet($docSheet);
1482
												} elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) {
1483
													$fromCoordinate	= PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1);
1484
													$fromOffsetX	= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff);
1485
													$fromOffsetY	= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff);
1486
													$toCoordinate	= PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1);
1487
													$toOffsetX		= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff);
1488
													$toOffsetY		= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff);
1489
													$graphic		= $twoCellAnchor->graphicFrame->children("http://schemas.openxmlformats.org/drawingml/2006/main")->graphic;
1490
													$chartRef		= $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart;
1491
													$thisChart		= (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
1492
 
1493
													$chartDetails[$docSheet->getTitle().'!'.$thisChart] =
1494
															array(	'fromCoordinate'	=> $fromCoordinate,
1495
																	'fromOffsetX'		=> $fromOffsetX,
1496
																	'fromOffsetY'		=> $fromOffsetY,
1497
																	'toCoordinate'		=> $toCoordinate,
1498
																	'toOffsetX'			=> $toOffsetX,
1499
																	'toOffsetY'			=> $toOffsetY,
1500
																	'worksheetTitle'	=> $docSheet->getTitle()
1501
																 );
1502
												}
1503
											}
1504
										}
1505
 
1506
									}
1507
								}
1508
							}
1509
 
1510
							// Loop through definedNames
1511
							if ($xmlWorkbook->definedNames) {
1512
								foreach ($xmlWorkbook->definedNames->definedName as $definedName) {
1513
									// Extract range
1514
									$extractedRange = (string)$definedName;
1515
									$extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange);
1516
									if (($spos = strpos($extractedRange,'!')) !== false) {
1517
										$extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos));
1518
									} else {
1519
										$extractedRange = str_replace('$', '', $extractedRange);
1520
									}
1521
 
1522
									// Valid range?
1523
									if (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') {
1524
										continue;
1525
									}
1526
 
1527
									// Some definedNames are only applicable if we are on the same sheet...
1528
									if ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) {
1529
										// Switch on type
1530
										switch ((string)$definedName['name']) {
1531
 
1532
											case '_xlnm._FilterDatabase':
1533
												if ((string)$definedName['hidden'] !== '1') {
1534
													$docSheet->getAutoFilter()->setRange($extractedRange);
1535
												}
1536
												break;
1537
 
1538
											case '_xlnm.Print_Titles':
1539
												// Split $extractedRange
1540
												$extractedRange = explode(',', $extractedRange);
1541
 
1542
												// Set print titles
1543
												foreach ($extractedRange as $range) {
1544
													$matches = array();
1545
													$range = str_replace('$', '', $range);
1546
 
1547
													// check for repeating columns, e g. 'A:A' or 'A:D'
1548
													if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) {
1549
														$docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2]));
1550
													}
1551
													// check for repeating rows, e.g. '1:1' or '1:5'
1552
													elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) {
1553
														$docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2]));
1554
													}
1555
												}
1556
												break;
1557
 
1558
											case '_xlnm.Print_Area':
1559
												$rangeSets = explode(',', $extractedRange);		// FIXME: what if sheetname contains comma?
1560
												$newRangeSets = array();
1561
												foreach($rangeSets as $rangeSet) {
1562
													$range = explode('!', $rangeSet);	// FIXME: what if sheetname contains exclamation mark?
1563
													$rangeSet = isset($range[1]) ? $range[1] : $range[0];
1564
													if (strpos($rangeSet, ':') === FALSE) {
1565
														$rangeSet = $rangeSet . ':' . $rangeSet;
1566
													}
1567
													$newRangeSets[] = str_replace('$', '', $rangeSet);
1568
												}
1569
												$docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets));
1570
												break;
1571
 
1572
											default:
1573
												break;
1574
										}
1575
									}
1576
								}
1577
							}
1578
 
1579
							// Next sheet id
1580
							++$sheetId;
1581
						}
1582
 
1583
						// Loop through definedNames
1584
						if ($xmlWorkbook->definedNames) {
1585
							foreach ($xmlWorkbook->definedNames->definedName as $definedName) {
1586
								// Extract range
1587
								$extractedRange = (string)$definedName;
1588
								$extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange);
1589
								if (($spos = strpos($extractedRange,'!')) !== false) {
1590
									$extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos));
1591
								} else {
1592
									$extractedRange = str_replace('$', '', $extractedRange);
1593
								}
1594
 
1595
								// Valid range?
1596
								if (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') {
1597
									continue;
1598
								}
1599
 
1600
								// Some definedNames are only applicable if we are on the same sheet...
1601
								if ((string)$definedName['localSheetId'] != '') {
1602
									// Local defined name
1603
									// Switch on type
1604
									switch ((string)$definedName['name']) {
1605
 
1606
										case '_xlnm._FilterDatabase':
1607
										case '_xlnm.Print_Titles':
1608
										case '_xlnm.Print_Area':
1609
											break;
1610
 
1611
										default:
1612
											if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) {
1613
												$range = explode('!', (string)$definedName);
1614
												if (count($range) == 2) {
1615
													$range[0] = str_replace("''", "'", $range[0]);
1616
													$range[0] = str_replace("'", "", $range[0]);
1617
													if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) {
1618
														$extractedRange = str_replace('$', '', $range[1]);
1619
														$scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]);
1620
														$excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) );
1621
													}
1622
												}
1623
											}
1624
											break;
1625
									}
1626
								} else if (!isset($definedName['localSheetId'])) {
1627
									// "Global" definedNames
1628
									$locatedSheet = null;
1629
									$extractedSheetName = '';
1630
									if (strpos( (string)$definedName, '!' ) !== false) {
1631
										// Extract sheet name
1632
										$extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true );
1633
										$extractedSheetName = $extractedSheetName[0];
1634
 
1635
										// Locate sheet
1636
										$locatedSheet = $excel->getSheetByName($extractedSheetName);
1637
 
1638
										// Modify range
1639
										$range = explode('!', $extractedRange);
1640
										$extractedRange = isset($range[1]) ? $range[1] : $range[0];
1641
									}
1642
 
1643
									if ($locatedSheet !== NULL) {
1644
										$excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) );
1645
									}
1646
								}
1647
							}
1648
						}
1649
					}
1650
 
1651
					if ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) {
1652
						// active sheet index
1653
						$activeTab = intval($xmlWorkbook->bookViews->workbookView["activeTab"]); // refers to old sheet index
1654
 
1655
						// keep active sheet index if sheet is still loaded, else first sheet is set as the active
1656
						if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {
1657
							$excel->setActiveSheetIndex($mapSheetId[$activeTab]);
1658
						} else {
1659
							if ($excel->getSheetCount() == 0) {
1660
								$excel->createSheet();
1661
							}
1662
							$excel->setActiveSheetIndex(0);
1663
						}
1664
					}
1665
				break;
1666
			}
1667
 
1668
		}
1669
 
1670
 
1671
		if (!$this->_readDataOnly) {
1672
			$contentTypes = simplexml_load_string($this->_getFromZipArchive($zip, "[Content_Types].xml"));
1673
			foreach ($contentTypes->Override as $contentType) {
1674
				switch ($contentType["ContentType"]) {
1675
					case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml":
1676
						if ($this->_includeCharts) {
1677
							$chartEntryRef = ltrim($contentType['PartName'],'/');
1678
							$chartElements = simplexml_load_string($this->_getFromZipArchive($zip, $chartEntryRef));
1679
							$objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml'));
1680
 
1681
//							echo 'Chart ',$chartEntryRef,'<br />';
1682
//							var_dump($charts[$chartEntryRef]);
1683
//
1684
							if (isset($charts[$chartEntryRef])) {
1685
								$chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id'];
1686
//								echo 'Position Ref ',$chartPositionRef,'<br />';
1687
								if (isset($chartDetails[$chartPositionRef])) {
1688
//									var_dump($chartDetails[$chartPositionRef]);
1689
 
1690
									$excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart);
1691
									$objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet']));
1692
									$objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'],
1693
																   $chartDetails[$chartPositionRef]['fromOffsetX'],
1694
																   $chartDetails[$chartPositionRef]['fromOffsetY']
1695
																 );
1696
									$objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'],
1697
																	   $chartDetails[$chartPositionRef]['toOffsetX'],
1698
																	   $chartDetails[$chartPositionRef]['toOffsetY']
1699
																	 );
1700
								}
1701
							}
1702
						}
1703
				}
1704
			}
1705
		}
1706
 
1707
		$zip->close();
1708
 
1709
		return $excel;
1710
	}
1711
 
1712
 
1713
	private static function _readColor($color, $background=FALSE) {
1714
		if (isset($color["rgb"])) {
1715
			return (string)$color["rgb"];
1716
		} else if (isset($color["indexed"])) {
1717
			return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB();
1718
		} else if (isset($color["theme"])) {
1719
			if (self::$_theme !== NULL) {
1720
				$returnColour = self::$_theme->getColourByIndex((int)$color["theme"]);
1721
				if (isset($color["tint"])) {
1722
					$tintAdjust = (float) $color["tint"];
1723
					$returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust);
1724
				}
1725
				return 'FF'.$returnColour;
1726
			}
1727
		}
1728
 
1729
		if ($background) {
1730
			return 'FFFFFFFF';
1731
		}
1732
		return 'FF000000';
1733
	}
1734
 
1735
 
1736
	private static function _readStyle($docStyle, $style) {
1737
		// format code
1738
//		if (isset($style->numFmt)) {
1739
//			if (isset($style->numFmt['formatCode'])) {
1740
//				$docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']);
1741
//			} else {
1742
				$docStyle->getNumberFormat()->setFormatCode($style->numFmt);
1743
//			}
1744
//		}
1745
 
1746
		// font
1747
		if (isset($style->font)) {
1748
			$docStyle->getFont()->setName((string) $style->font->name["val"]);
1749
			$docStyle->getFont()->setSize((string) $style->font->sz["val"]);
1750
			if (isset($style->font->b)) {
1751
				$docStyle->getFont()->setBold(!isset($style->font->b["val"]) || self::boolean((string) $style->font->b["val"]));
1752
			}
1753
			if (isset($style->font->i)) {
1754
				$docStyle->getFont()->setItalic(!isset($style->font->i["val"]) || self::boolean((string) $style->font->i["val"]));
1755
			}
1756
			if (isset($style->font->strike)) {
1757
				$docStyle->getFont()->setStrikethrough(!isset($style->font->strike["val"]) || self::boolean((string) $style->font->strike["val"]));
1758
			}
1759
			$docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color));
1760
 
1761
			if (isset($style->font->u) && !isset($style->font->u["val"])) {
1762
				$docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
1763
			} else if (isset($style->font->u) && isset($style->font->u["val"])) {
1764
				$docStyle->getFont()->setUnderline((string)$style->font->u["val"]);
1765
			}
1766
 
1767
			if (isset($style->font->vertAlign) && isset($style->font->vertAlign["val"])) {
1768
				$vertAlign = strtolower((string)$style->font->vertAlign["val"]);
1769
				if ($vertAlign == 'superscript') {
1770
					$docStyle->getFont()->setSuperScript(true);
1771
				}
1772
				if ($vertAlign == 'subscript') {
1773
					$docStyle->getFont()->setSubScript(true);
1774
				}
1775
			}
1776
		}
1777
 
1778
		// fill
1779
		if (isset($style->fill)) {
1780
			if ($style->fill->gradientFill) {
1781
				$gradientFill = $style->fill->gradientFill[0];
1782
				if(!empty($gradientFill["type"])) {
1783
					$docStyle->getFill()->setFillType((string) $gradientFill["type"]);
1784
				}
1785
				$docStyle->getFill()->setRotation(floatval($gradientFill["degree"]));
1786
				$gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
1787
				$docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) );
1788
				$docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) );
1789
			} elseif ($style->fill->patternFill) {
1790
				$patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid';
1791
				$docStyle->getFill()->setFillType($patternType);
1792
				if ($style->fill->patternFill->fgColor) {
1793
					$docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true));
1794
				} else {
1795
					$docStyle->getFill()->getStartColor()->setARGB('FF000000');
1796
				}
1797
				if ($style->fill->patternFill->bgColor) {
1798
					$docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true));
1799
				}
1800
			}
1801
		}
1802
 
1803
		// border
1804
		if (isset($style->border)) {
1805
			$diagonalUp = self::boolean((string) $style->border["diagonalUp"]);
1806
			$diagonalDown = self::boolean((string) $style->border["diagonalDown"]);
1807
			if (!$diagonalUp && !$diagonalDown) {
1808
				$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE);
1809
			} elseif ($diagonalUp && !$diagonalDown) {
1810
				$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP);
1811
			} elseif (!$diagonalUp && $diagonalDown) {
1812
				$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN);
1813
			} else {
1814
				$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH);
1815
			}
1816
			self::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left);
1817
			self::_readBorder($docStyle->getBorders()->getRight(), $style->border->right);
1818
			self::_readBorder($docStyle->getBorders()->getTop(), $style->border->top);
1819
			self::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom);
1820
			self::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal);
1821
		}
1822
 
1823
		// alignment
1824
		if (isset($style->alignment)) {
1825
			$docStyle->getAlignment()->setHorizontal((string) $style->alignment["horizontal"]);
1826
			$docStyle->getAlignment()->setVertical((string) $style->alignment["vertical"]);
1827
 
1828
			$textRotation = 0;
1829
			if ((int)$style->alignment["textRotation"] <= 90) {
1830
				$textRotation = (int)$style->alignment["textRotation"];
1831
			} else if ((int)$style->alignment["textRotation"] > 90) {
1832
				$textRotation = 90 - (int)$style->alignment["textRotation"];
1833
			}
1834
 
1835
			$docStyle->getAlignment()->setTextRotation(intval($textRotation));
1836
			$docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"]));
1837
			$docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"]));
1838
			$docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 );
1839
		}
1840
 
1841
		// protection
1842
		if (isset($style->protection)) {
1843
			if (isset($style->protection['locked'])) {
1844
				if (self::boolean((string) $style->protection['locked'])) {
1845
					$docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED);
1846
				} else {
1847
					$docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);
1848
				}
1849
			}
1850
 
1851
			if (isset($style->protection['hidden'])) {
1852
				if (self::boolean((string) $style->protection['hidden'])) {
1853
					$docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_PROTECTED);
1854
				} else {
1855
					$docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);
1856
				}
1857
			}
1858
		}
1859
	}
1860
 
1861
 
1862
	private static function _readBorder($docBorder, $eleBorder) {
1863
		if (isset($eleBorder["style"])) {
1864
			$docBorder->setBorderStyle((string) $eleBorder["style"]);
1865
		}
1866
		if (isset($eleBorder->color)) {
1867
			$docBorder->getColor()->setARGB(self::_readColor($eleBorder->color));
1868
		}
1869
	}
1870
 
1871
 
1872
	private function _parseRichText($is = null) {
1873
		$value = new PHPExcel_RichText();
1874
 
1875
		if (isset($is->t)) {
1876
			$value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) );
1877
		} else {
1878
			foreach ($is->r as $run) {
1879
				if (!isset($run->rPr)) {
1880
					$objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) );
1881
 
1882
				} else {
1883
					$objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) );
1884
 
1885
					if (isset($run->rPr->rFont["val"])) {
1886
						$objText->getFont()->setName((string) $run->rPr->rFont["val"]);
1887
					}
1888
 
1889
					if (isset($run->rPr->sz["val"])) {
1890
						$objText->getFont()->setSize((string) $run->rPr->sz["val"]);
1891
					}
1892
 
1893
					if (isset($run->rPr->color)) {
1894
						$objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) );
1895
					}
1896
 
1897
					if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) ||
1898
						(isset($run->rPr->b) && !isset($run->rPr->b["val"]))) {
1899
						$objText->getFont()->setBold(TRUE);
1900
					}
1901
 
1902
					if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) ||
1903
						(isset($run->rPr->i) && !isset($run->rPr->i["val"]))) {
1904
						$objText->getFont()->setItalic(TRUE);
1905
					}
1906
 
1907
					if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) {
1908
						$vertAlign = strtolower((string)$run->rPr->vertAlign["val"]);
1909
						if ($vertAlign == 'superscript') {
1910
							$objText->getFont()->setSuperScript(TRUE);
1911
						}
1912
						if ($vertAlign == 'subscript') {
1913
							$objText->getFont()->setSubScript(TRUE);
1914
						}
1915
					}
1916
 
1917
					if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) {
1918
						$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
1919
					} else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) {
1920
						$objText->getFont()->setUnderline((string)$run->rPr->u["val"]);
1921
					}
1922
 
1923
					if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) ||
1924
						(isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) {
1925
						$objText->getFont()->setStrikethrough(TRUE);
1926
					}
1927
				}
1928
			}
1929
		}
1930
 
1931
		return $value;
1932
	}
1933
 
1934
 
1935
	private static function array_item($array, $key = 0) {
1936
		return (isset($array[$key]) ? $array[$key] : null);
1937
	}
1938
 
1939
 
1940
	private static function dir_add($base, $add) {
1941
		return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add");
1942
	}
1943
 
1944
 
1945
	private static function toCSSArray($style) {
1946
		$style = str_replace(array("\r","\n"), "", $style);
1947
 
1948
		$temp = explode(';', $style);
1949
		$style = array();
1950
		foreach ($temp as $item) {
1951
			$item = explode(':', $item);
1952
 
1953
			if (strpos($item[1], 'px') !== false) {
1954
				$item[1] = str_replace('px', '', $item[1]);
1955
			}
1956
			if (strpos($item[1], 'pt') !== false) {
1957
				$item[1] = str_replace('pt', '', $item[1]);
1958
				$item[1] = PHPExcel_Shared_Font::fontSizeToPixels($item[1]);
1959
			}
1960
			if (strpos($item[1], 'in') !== false) {
1961
				$item[1] = str_replace('in', '', $item[1]);
1962
				$item[1] = PHPExcel_Shared_Font::inchSizeToPixels($item[1]);
1963
			}
1964
			if (strpos($item[1], 'cm') !== false) {
1965
				$item[1] = str_replace('cm', '', $item[1]);
1966
				$item[1] = PHPExcel_Shared_Font::centimeterSizeToPixels($item[1]);
1967
			}
1968
 
1969
			$style[$item[0]] = $item[1];
1970
		}
1971
 
1972
		return $style;
1973
	}
1974
 
1975
	private static function boolean($value = NULL)
1976
	{
1977
		if (is_numeric($value)) {
1978
			return (bool) $value;
1979
		}
1980
		return ($value === 'true' || $value === 'TRUE') ? TRUE : FALSE;
1981
	}
1982
}