[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/phpexcel/PHPExcel/Writer/ -> Excel2007.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1