[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * PHPExcel_Writer_Excel2007 5 * 6 * Copyright (c) 2006 - 2015 PHPExcel 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 * @category PHPExcel 23 * @package PHPExcel_Writer_Excel2007 24 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 25 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 26 * @version ##VERSION##, ##DATE## 27 */ 28 class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter 29 { 30 /** 31 * Pre-calculate formulas 32 * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are 33 * immediately available to MS Excel or other office spreadsheet viewer when opening the file 34 * 35 * Overrides the default TRUE for this specific writer for performance reasons 36 * 37 * @var boolean 38 */ 39 protected $preCalculateFormulas = false; 40 41 /** 42 * Office2003 compatibility 43 * 44 * @var boolean 45 */ 46 private $office2003compatibility = false; 47 48 /** 49 * Private writer parts 50 * 51 * @var PHPExcel_Writer_Excel2007_WriterPart[] 52 */ 53 private $writerParts = array(); 54 55 /** 56 * Private PHPExcel 57 * 58 * @var PHPExcel 59 */ 60 private $spreadSheet; 61 62 /** 63 * Private string table 64 * 65 * @var string[] 66 */ 67 private $stringTable = array(); 68 69 /** 70 * Private unique PHPExcel_Style_Conditional HashTable 71 * 72 * @var PHPExcel_HashTable 73 */ 74 private $stylesConditionalHashTable; 75 76 /** 77 * Private unique PHPExcel_Style HashTable 78 * 79 * @var PHPExcel_HashTable 80 */ 81 private $styleHashTable; 82 83 /** 84 * Private unique PHPExcel_Style_Fill HashTable 85 * 86 * @var PHPExcel_HashTable 87 */ 88 private $fillHashTable; 89 90 /** 91 * Private unique PHPExcel_Style_Font HashTable 92 * 93 * @var PHPExcel_HashTable 94 */ 95 private $fontHashTable; 96 97 /** 98 * Private unique PHPExcel_Style_Borders HashTable 99 * 100 * @var PHPExcel_HashTable 101 */ 102 private $bordersHashTable ; 103 104 /** 105 * Private unique PHPExcel_Style_NumberFormat HashTable 106 * 107 * @var PHPExcel_HashTable 108 */ 109 private $numFmtHashTable; 110 111 /** 112 * Private unique PHPExcel_Worksheet_BaseDrawing HashTable 113 * 114 * @var PHPExcel_HashTable 115 */ 116 private $drawingHashTable; 117 118 /** 119 * Create a new PHPExcel_Writer_Excel2007 120 * 121 * @param PHPExcel $pPHPExcel 122 */ 123 public function __construct(PHPExcel $pPHPExcel = null) 124 { 125 // Assign PHPExcel 126 $this->setPHPExcel($pPHPExcel); 127 128 $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', 129 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', 130 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', 131 'rels' => 'PHPExcel_Writer_Excel2007_Rels', 132 'theme' => 'PHPExcel_Writer_Excel2007_Theme', 133 'style' => 'PHPExcel_Writer_Excel2007_Style', 134 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', 135 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', 136 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', 137 'comments' => 'PHPExcel_Writer_Excel2007_Comments', 138 'chart' => 'PHPExcel_Writer_Excel2007_Chart', 139 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', 140 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' 141 ); 142 143 // Initialise writer parts 144 // and Assign their parent IWriters 145 foreach ($writerPartsArray as $writer => $class) { 146 $this->writerParts[$writer] = new $class($this); 147 } 148 149 $hashTablesArray = array( 'stylesConditionalHashTable', 'fillHashTable', 'fontHashTable', 150 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable', 151 'styleHashTable' 152 ); 153 154 // Set HashTable variables 155 foreach ($hashTablesArray as $tableName) { 156 $this->$tableName = new PHPExcel_HashTable(); 157 } 158 } 159 160 /** 161 * Get writer part 162 * 163 * @param string $pPartName Writer part name 164 * @return PHPExcel_Writer_Excel2007_WriterPart 165 */ 166 public function getWriterPart($pPartName = '') 167 { 168 if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { 169 return $this->writerParts[strtolower($pPartName)]; 170 } else { 171 return null; 172 } 173 } 174 175 /** 176 * Save PHPExcel to file 177 * 178 * @param string $pFilename 179 * @throws PHPExcel_Writer_Exception 180 */ 181 public function save($pFilename = null) 182 { 183 if ($this->spreadSheet !== null) { 184 // garbage collect 185 $this->spreadSheet->garbageCollect(); 186 187 // If $pFilename is php://output or php://stdout, make it a temporary file... 188 $originalFilename = $pFilename; 189 if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { 190 $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); 191 if ($pFilename == '') { 192 $pFilename = $originalFilename; 193 } 194 } 195 196 $saveDebugLog = PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog(); 197 PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false); 198 $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); 199 PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); 200 201 // Create string lookup table 202 $this->stringTable = array(); 203 for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { 204 $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); 205 } 206 207 // Create styles dictionaries 208 $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet)); 209 $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet)); 210 $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet)); 211 $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet)); 212 $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet)); 213 $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet)); 214 215 // Create drawing dictionary 216 $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet)); 217 218 // Create new ZIP file and open it for writing 219 $zipClass = PHPExcel_Settings::getZipClass(); 220 $objZip = new $zipClass(); 221 222 // Retrieve OVERWRITE and CREATE constants from the instantiated zip class 223 // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP 224 $ro = new ReflectionObject($objZip); 225 $zipOverWrite = $ro->getConstant('OVERWRITE'); 226 $zipCreate = $ro->getConstant('CREATE'); 227 228 if (file_exists($pFilename)) { 229 unlink($pFilename); 230 } 231 // Try opening the ZIP file 232 if ($objZip->open($pFilename, $zipOverWrite) !== true) { 233 if ($objZip->open($pFilename, $zipCreate) !== true) { 234 throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing."); 235 } 236 } 237 238 // Add [Content_Types].xml to ZIP file 239 $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts)); 240 241 //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) 242 if ($this->spreadSheet->hasMacros()) { 243 $macrosCode=$this->spreadSheet->getMacrosCode(); 244 if (!is_null($macrosCode)) {// we have the code ? 245 $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin 246 if ($this->spreadSheet->hasMacrosCertificate()) {//signed macros ? 247 // Yes : add the certificate file and the related rels file 248 $objZip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate()); 249 $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet)); 250 } 251 } 252 } 253 //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) 254 if ($this->spreadSheet->hasRibbon()) { 255 $tmpRibbonTarget=$this->spreadSheet->getRibbonXMLData('target'); 256 $objZip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data')); 257 if ($this->spreadSheet->hasRibbonBinObjects()) { 258 $tmpRootPath=dirname($tmpRibbonTarget).'/'; 259 $ribbonBinObjects=$this->spreadSheet->getRibbonBinObjects('data');//the files to write 260 foreach ($ribbonBinObjects as $aPath => $aContent) { 261 $objZip->addFromString($tmpRootPath.$aPath, $aContent); 262 } 263 //the rels for files 264 $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet)); 265 } 266 } 267 268 // Add relationships to ZIP file 269 $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet)); 270 $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet)); 271 272 // Add document properties to ZIP file 273 $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet)); 274 $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet)); 275 $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet); 276 if ($customPropertiesPart !== null) { 277 $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); 278 } 279 280 // Add theme to ZIP file 281 $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet)); 282 283 // Add string table to ZIP file 284 $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable)); 285 286 // Add styles to ZIP file 287 $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet)); 288 289 // Add workbook to ZIP file 290 $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas)); 291 292 $chartCount = 0; 293 // Add worksheets 294 for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { 295 $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts)); 296 if ($this->includeCharts) { 297 $charts = $this->spreadSheet->getSheet($i)->getChartCollection(); 298 if (count($charts) > 0) { 299 foreach ($charts as $chart) { 300 $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); 301 $chartCount++; 302 } 303 } 304 } 305 } 306 307 $chartRef1 = $chartRef2 = 0; 308 // Add worksheet relationships (drawings, ...) 309 for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { 310 // Add relationships 311 $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); 312 313 $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection(); 314 $drawingCount = count($drawings); 315 if ($this->includeCharts) { 316 $chartCount = $this->spreadSheet->getSheet($i)->getChartCount(); 317 } 318 319 // Add drawing and image relationship parts 320 if (($drawingCount > 0) || ($chartCount > 0)) { 321 // Drawing relationships 322 $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); 323 324 // Drawings 325 $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $chartRef2, $this->includeCharts)); 326 } 327 328 // Add comment relationship parts 329 if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) { 330 // VML Comments 331 $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i))); 332 333 // Comments 334 $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i))); 335 } 336 337 // Add header/footer relationship parts 338 if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { 339 // VML Drawings 340 $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i))); 341 342 // VML Drawing relationships 343 $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i))); 344 345 // Media 346 foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { 347 $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); 348 } 349 } 350 } 351 352 // Add media 353 for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { 354 if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { 355 $imageContents = null; 356 $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); 357 if (strpos($imagePath, 'zip://') !== false) { 358 $imagePath = substr($imagePath, 6); 359 $imagePathSplitted = explode('#', $imagePath); 360 361 $imageZip = new ZipArchive(); 362 $imageZip->open($imagePathSplitted[0]); 363 $imageContents = $imageZip->getFromName($imagePathSplitted[1]); 364 $imageZip->close(); 365 unset($imageZip); 366 } else { 367 $imageContents = file_get_contents($imagePath); 368 } 369 370 $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); 371 } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { 372 ob_start(); 373 call_user_func( 374 $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), 375 $this->getDrawingHashTable()->getByIndex($i)->getImageResource() 376 ); 377 $imageContents = ob_get_contents(); 378 ob_end_clean(); 379 380 $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); 381 } 382 } 383 384 PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); 385 PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); 386 387 // Close file 388 if ($objZip->close() === false) { 389 throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); 390 } 391 392 // If a temporary file was used, copy it to the correct file stream 393 if ($originalFilename != $pFilename) { 394 if (copy($pFilename, $originalFilename) === false) { 395 throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); 396 } 397 @unlink($pFilename); 398 } 399 } else { 400 throw new PHPExcel_Writer_Exception("PHPExcel object unassigned."); 401 } 402 } 403 404 /** 405 * Get PHPExcel object 406 * 407 * @return PHPExcel 408 * @throws PHPExcel_Writer_Exception 409 */ 410 public function getPHPExcel() 411 { 412 if ($this->spreadSheet !== null) { 413 return $this->spreadSheet; 414 } else { 415 throw new PHPExcel_Writer_Exception("No PHPExcel object assigned."); 416 } 417 } 418 419 /** 420 * Set PHPExcel object 421 * 422 * @param PHPExcel $pPHPExcel PHPExcel object 423 * @throws PHPExcel_Writer_Exception 424 * @return PHPExcel_Writer_Excel2007 425 */ 426 public function setPHPExcel(PHPExcel $pPHPExcel = null) 427 { 428 $this->spreadSheet = $pPHPExcel; 429 return $this; 430 } 431 432 /** 433 * Get string table 434 * 435 * @return string[] 436 */ 437 public function getStringTable() 438 { 439 return $this->stringTable; 440 } 441 442 /** 443 * Get PHPExcel_Style HashTable 444 * 445 * @return PHPExcel_HashTable 446 */ 447 public function getStyleHashTable() 448 { 449 return $this->styleHashTable; 450 } 451 452 /** 453 * Get PHPExcel_Style_Conditional HashTable 454 * 455 * @return PHPExcel_HashTable 456 */ 457 public function getStylesConditionalHashTable() 458 { 459 return $this->stylesConditionalHashTable; 460 } 461 462 /** 463 * Get PHPExcel_Style_Fill HashTable 464 * 465 * @return PHPExcel_HashTable 466 */ 467 public function getFillHashTable() 468 { 469 return $this->fillHashTable; 470 } 471 472 /** 473 * Get PHPExcel_Style_Font HashTable 474 * 475 * @return PHPExcel_HashTable 476 */ 477 public function getFontHashTable() 478 { 479 return $this->fontHashTable; 480 } 481 482 /** 483 * Get PHPExcel_Style_Borders HashTable 484 * 485 * @return PHPExcel_HashTable 486 */ 487 public function getBordersHashTable() 488 { 489 return $this->bordersHashTable; 490 } 491 492 /** 493 * Get PHPExcel_Style_NumberFormat HashTable 494 * 495 * @return PHPExcel_HashTable 496 */ 497 public function getNumFmtHashTable() 498 { 499 return $this->numFmtHashTable; 500 } 501 502 /** 503 * Get PHPExcel_Worksheet_BaseDrawing HashTable 504 * 505 * @return PHPExcel_HashTable 506 */ 507 public function getDrawingHashTable() 508 { 509 return $this->drawingHashTable; 510 } 511 512 /** 513 * Get Office2003 compatibility 514 * 515 * @return boolean 516 */ 517 public function getOffice2003Compatibility() 518 { 519 return $this->office2003compatibility; 520 } 521 522 /** 523 * Set Office2003 compatibility 524 * 525 * @param boolean $pValue Office2003 compatibility? 526 * @return PHPExcel_Writer_Excel2007 527 */ 528 public function setOffice2003Compatibility($pValue = false) 529 { 530 $this->office2003compatibility = $pValue; 531 return $this; 532 } 533 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |