/**
  * Save PHPExcel to file
  *
  * @param     string         $pFilename
  * @throws     \PHPExcel\Writer\Exception
  */
 public function save($pFilename = null)
 {
     if ($this->spreadSheet !== null) {
         // garbage collect
         $this->spreadSheet->garbageCollect();
         // If $pFilename is php://output or php://stdout, make it a temporary file...
         $originalFilename = $pFilename;
         if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
             $pFilename = @tempnam(\PHPExcel\Shared\File::sysGetTempDir(), 'phpxltmp');
             if ($pFilename == '') {
                 $pFilename = $originalFilename;
             }
         }
         $saveDebugLog = \PHPExcel\Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog();
         \PHPExcel\Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false);
         $saveDateReturnType = \PHPExcel\Calculation\Functions::getReturnDateType();
         \PHPExcel\Calculation\Functions::setReturnDateType(\PHPExcel\Calculation\Functions::RETURNDATE_EXCEL);
         // Create string lookup table
         $this->stringTable = array();
         for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
             $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
         }
         // Create styles dictionaries
         $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet));
         $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet));
         $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet));
         $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet));
         $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet));
         $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet));
         // Create drawing dictionary
         $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet));
         // Create new ZIP file and open it for writing
         $zipClass = \PHPExcel\Settings::getZipClass();
         /** @var \ZipArchive $objZip */
         $objZip = new $zipClass();
         //    Retrieve OVERWRITE and CREATE constants from the instantiated zip class
         //    This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP
         $ro = new \ReflectionObject($objZip);
         $zipOverWrite = $ro->getConstant('OVERWRITE');
         $zipCreate = $ro->getConstant('CREATE');
         if (file_exists($pFilename)) {
             unlink($pFilename);
         }
         // Try opening the ZIP file
         if ($objZip->open($pFilename, $zipOverWrite) !== true) {
             if ($objZip->open($pFilename, $zipCreate) !== true) {
                 throw new \PHPExcel\Writer\Exception("Could not open " . $pFilename . " for writing.");
             }
         }
         // Add [Content_Types].xml to ZIP file
         $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts));
         //if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
         if ($this->spreadSheet->hasMacros()) {
             $macrosCode = $this->spreadSheet->getMacrosCode();
             if (!is_null($macrosCode)) {
                 // we have the code ?
                 $objZip->addFromString('xl/vbaProject.bin', $macrosCode);
                 //allways in 'xl', allways named vbaProject.bin
                 if ($this->spreadSheet->hasMacrosCertificate()) {
                     //signed macros ?
                     // Yes : add the certificate file and the related rels file
                     $objZip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
                     $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet));
                 }
             }
         }
         //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels)
         if ($this->spreadSheet->hasRibbon()) {
             $tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target');
             $objZip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data'));
             if ($this->spreadSheet->hasRibbonBinObjects()) {
                 $tmpRootPath = dirname($tmpRibbonTarget) . '/';
                 $ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data');
                 //the files to write
                 foreach ($ribbonBinObjects as $aPath => $aContent) {
                     $objZip->addFromString($tmpRootPath . $aPath, $aContent);
                 }
                 //the rels for files
                 $objZip->addFromString($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet));
             }
         }
         // Add relationships to ZIP file
         $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet));
         $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet));
         // Add document properties to ZIP file
         $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet));
         $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet));
         $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet);
         if ($customPropertiesPart !== null) {
             $objZip->addFromString('docProps/custom.xml', $customPropertiesPart);
         }
         // Add theme to ZIP file
         $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet));
         // Add string table to ZIP file
         $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable));
         // Add styles to ZIP file
         $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet));
         // Add workbook to ZIP file
         $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
         $chartCount = 0;
         // Add worksheets
         for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
             $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts));
             if ($this->includeCharts) {
                 $charts = $this->spreadSheet->getSheet($i)->getChartCollection();
                 if (count($charts) > 0) {
                     foreach ($charts as $chart) {
                         $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
                         $chartCount++;
                     }
                 }
             }
         }
         $chartRef1 = $chartRef2 = 0;
         // Add worksheet relationships (drawings, ...)
         for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
             // Add relationships
             $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), $i + 1, $this->includeCharts));
             $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection();
             $drawingCount = count($drawings);
             if ($this->includeCharts) {
                 $chartCount = $this->spreadSheet->getSheet($i)->getChartCount();
             }
             // Add drawing and image relationship parts
             if ($drawingCount > 0 || $chartCount > 0) {
                 // Drawing relationships
                 $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
                 // Drawings
                 $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $chartRef2, $this->includeCharts));
             }
             // Add comment relationship parts
             if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
                 // VML Comments
                 $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i)));
                 // Comments
                 $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i)));
             }
             // Add header/footer relationship parts
             if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
                 // VML Drawings
                 $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
                 // VML Drawing relationships
                 $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i)));
                 // Media
                 foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
                     $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));
                 }
             }
         }
         // Add media
         for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
             if ($this->getDrawingHashTable()->getByIndex($i) instanceof \PHPExcel\Worksheet\Drawing) {
                 $imageContents = null;
                 $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();
                 if (strpos($imagePath, 'zip://') !== false) {
                     $imagePath = substr($imagePath, 6);
                     $imagePathSplitted = explode('#', $imagePath);
                     $imageZip = new ZipArchive();
                     $imageZip->open($imagePathSplitted[0]);
                     $imageContents = $imageZip->getFromName($imagePathSplitted[1]);
                     $imageZip->close();
                     unset($imageZip);
                 } else {
                     $imageContents = file_get_contents($imagePath);
                 }
                 $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
             } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof \PHPExcel\Worksheet\MemoryDrawing) {
                 ob_start();
                 call_user_func($this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), $this->getDrawingHashTable()->getByIndex($i)->getImageResource());
                 $imageContents = ob_get_contents();
                 ob_end_clean();
                 $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
             }
         }
         \PHPExcel\Calculation\Functions::setReturnDateType($saveDateReturnType);
         \PHPExcel\Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
         // Close file
         if ($objZip->close() === false) {
             throw new \PHPExcel\Writer\Exception("Could not close zip file {$pFilename}.");
         }
         // If a temporary file was used, copy it to the correct file stream
         if ($originalFilename != $pFilename) {
             if (copy($pFilename, $originalFilename) === false) {
                 throw new \PHPExcel\Writer\Exception("Could not copy temporary zip file {$pFilename} to {$originalFilename}.");
             }
             @unlink($pFilename);
         }
     } else {
         throw new \PHPExcel\Writer\Exception("PHPExcel object unassigned.");
     }
 }
Exemple #2
0
 /**
  * Are there more Worksheet instances available?
  *
  * @return boolean
  */
 public function valid()
 {
     return $this->position < $this->subject->getSheetCount();
 }
Exemple #3
0
 /**
  * Class constructor
  *
  * @param \PHPExcel\Spreadsheet $phpExcel The Workbook
  * @param int        &$str_total        Total number of strings
  * @param int        &$str_unique    Total number of unique strings
  * @param array        &$str_table        String Table
  * @param array        &$colors        Colour Table
  * @param mixed        $parser            The formula parser created for the Workbook
  */
 public function __construct(\PHPExcel\Spreadsheet $phpExcel, &$str_total, &$str_unique, &$str_table, &$colors, $parser)
 {
     // It needs to call its parent's constructor explicitly
     parent::__construct();
     $this->parser = $parser;
     $this->biffSize = 0;
     $this->palette = array();
     $this->countryCode = -1;
     $this->stringTotal =& $str_total;
     $this->stringUnique =& $str_unique;
     $this->stringTable =& $str_table;
     $this->colors =& $colors;
     $this->setPaletteXl97();
     $this->phpExcel = $phpExcel;
     // set BIFFwriter limit for CONTINUE records
     //        $this->_limit = 8224;
     $this->codepage = 0x4b0;
     // Add empty sheets and Build color cache
     $countSheets = $phpExcel->getSheetCount();
     for ($i = 0; $i < $countSheets; ++$i) {
         $phpSheet = $phpExcel->getSheet($i);
         $this->parser->setExtSheet($phpSheet->getTitle(), $i);
         // Register worksheet name with parser
         $supbook_index = 0x0;
         $ref = pack('vvv', $supbook_index, $i, $i);
         $this->parser->references[] = $ref;
         // Register reference with parser
         // Sheet tab colors?
         if ($phpSheet->isTabColorSet()) {
             $this->addColor($phpSheet->getTabColor()->getRGB());
         }
     }
 }
 /**
  * Write content types to XML format
  *
  * @param     \PHPExcel\Spreadsheet    $pPHPExcel
  * @param    boolean        $includeCharts    Flag indicating if we should include drawing details for charts
  * @return string                  XML Output
  * @throws     \PHPExcel\Writer\Exception
  */
 public function writeContentTypes(\PHPExcel\Spreadsheet $pPHPExcel = null, $includeCharts = false)
 {
     // Create XML writer
     $objWriter = null;
     if ($this->getParentWriter()->getUseDiskCaching()) {
         $objWriter = new \PHPExcel\Shared\XMLWriter(\PHPExcel\Shared\XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
     } else {
         $objWriter = new \PHPExcel\Shared\XMLWriter(\PHPExcel\Shared\XMLWriter::STORAGE_MEMORY);
     }
     // XML header
     $objWriter->startDocument('1.0', 'UTF-8', 'yes');
     // Types
     $objWriter->startElement('Types');
     $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types');
     // Theme
     $this->writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml');
     // Styles
     $this->writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml');
     // Rels
     $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml');
     // XML
     $this->writeDefaultContentType($objWriter, 'xml', 'application/xml');
     // VML
     $this->writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing');
     // Workbook
     if ($pPHPExcel->hasMacros()) {
         //Macros in workbook ?
         // Yes : not standard content but "macroEnabled"
         $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml');
         //... and define a new type for the VBA project
         $this->writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject');
         if ($pPHPExcel->hasMacrosCertificate()) {
             // signed macros ?
             // Yes : add needed information
             $this->writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature');
         }
     } else {
         // no macros in workbook, so standard type
         $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml');
     }
     // DocProps
     $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml');
     $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml');
     $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();
     if (!empty($customPropertyList)) {
         $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml');
     }
     // Worksheets
     $sheetCount = $pPHPExcel->getSheetCount();
     for ($i = 0; $i < $sheetCount; ++$i) {
         $this->writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml');
     }
     // Shared strings
     $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml');
     // Add worksheet relationship content types
     $chart = 1;
     for ($i = 0; $i < $sheetCount; ++$i) {
         $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection();
         $drawingCount = count($drawings);
         $chartCount = $includeCharts ? $pPHPExcel->getSheet($i)->getChartCount() : 0;
         //    We need a drawing relationship for the worksheet if we have either drawings or charts
         if ($drawingCount > 0 || $chartCount > 0) {
             $this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml');
         }
         //    If we have charts, then we need a chart relationship for every individual chart
         if ($chartCount > 0) {
             for ($c = 0; $c < $chartCount; ++$c) {
                 $this->writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
             }
         }
     }
     // Comments
     for ($i = 0; $i < $sheetCount; ++$i) {
         if (count($pPHPExcel->getSheet($i)->getComments()) > 0) {
             $this->writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml');
         }
     }
     // Add media content-types
     $aMediaContentTypes = array();
     $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count();
     for ($i = 0; $i < $mediaCount; ++$i) {
         $extension = '';
         $mimeType = '';
         if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof \PHPExcel\Worksheet\Drawing) {
             $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension());
             $mimeType = $this->getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath());
         } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof \PHPExcel\Worksheet\MemoryDrawing) {
             $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType());
             $extension = explode('/', $extension);
             $extension = $extension[1];
             $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType();
         }
         if (!isset($aMediaContentTypes[$extension])) {
             $aMediaContentTypes[$extension] = $mimeType;
             $this->writeDefaultContentType($objWriter, $extension, $mimeType);
         }
     }
     if ($pPHPExcel->hasRibbonBinObjects()) {
         // Some additional objects in the ribbon ?
         // we need to write "Extension" but not already write for media content
         $tabRibbonTypes = array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes));
         foreach ($tabRibbonTypes as $aRibbonType) {
             $mimeType = 'image/.' . $aRibbonType;
             //we wrote $mimeType like customUI Editor
             $this->writeDefaultContentType($objWriter, $aRibbonType, $mimeType);
         }
     }
     $sheetCount = $pPHPExcel->getSheetCount();
     for ($i = 0; $i < $sheetCount; ++$i) {
         if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) {
             foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) {
                 if (!isset($aMediaContentTypes[strtolower($image->getExtension())])) {
                     $aMediaContentTypes[strtolower($image->getExtension())] = $this->getImageMimeType($image->getPath());
                     $this->writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]);
                 }
             }
         }
     }
     $objWriter->endElement();
     // Return
     return $objWriter->getData();
 }
Exemple #5
0
 /**
  * Loads PHPExcel from file into PHPExcel instance
  *
  * @param     string         $pFilename
  * @param     \PHPExcel\Spreadsheet    $objPHPExcel
  * @return    \PHPExcel\Spreadsheet
  * @throws    Exception
  */
 public function loadIntoExisting($pFilename, \PHPExcel\Spreadsheet $objPHPExcel)
 {
     // Open file
     $this->openFile($pFilename);
     if (!$this->isValidFormat()) {
         fclose($this->fileHandle);
         throw new Exception($pFilename . " is an Invalid Spreadsheet file.");
     }
     $fileHandle = $this->fileHandle;
     rewind($fileHandle);
     // Create new Worksheets
     while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) {
         $objPHPExcel->createSheet();
     }
     $objPHPExcel->setActiveSheetIndex($this->sheetIndex);
     $fromFormats = array('\\-', '\\ ');
     $toFormats = array('-', ' ');
     // Loop through file
     $rowData = array();
     $column = $row = '';
     // loop through one row (line) at a time in the file
     while (($rowData = fgets($fileHandle)) !== false) {
         // convert SYLK encoded $rowData to UTF-8
         $rowData = \PHPExcel\Shared\StringHelper::SYLKtoUTF8($rowData);
         // explode each row at semicolons while taking into account that literal semicolon (;)
         // is escaped like this (;;)
         $rowData = explode("\t", str_replace('¤', ';', str_replace(';', "\t", str_replace(';;', '¤', rtrim($rowData)))));
         $dataType = array_shift($rowData);
         //    Read shared styles
         if ($dataType == 'P') {
             $formatArray = array();
             foreach ($rowData as $rowDatum) {
                 switch ($rowDatum[0]) {
                     case 'P':
                         $formatArray['numberformat']['code'] = str_replace($fromFormats, $toFormats, substr($rowDatum, 1));
                         break;
                     case 'E':
                     case 'F':
                         $formatArray['font']['name'] = substr($rowDatum, 1);
                         break;
                     case 'L':
                         $formatArray['font']['size'] = substr($rowDatum, 1);
                         break;
                     case 'S':
                         $styleSettings = substr($rowDatum, 1);
                         for ($i = 0; $i < strlen($styleSettings); ++$i) {
                             switch ($styleSettings[$i]) {
                                 case 'I':
                                     $formatArray['font']['italic'] = true;
                                     break;
                                 case 'D':
                                     $formatArray['font']['bold'] = true;
                                     break;
                                 case 'T':
                                     $formatArray['borders']['top']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                                 case 'B':
                                     $formatArray['borders']['bottom']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                                 case 'L':
                                     $formatArray['borders']['left']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                                 case 'R':
                                     $formatArray['borders']['right']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                             }
                         }
                         break;
                 }
             }
             $this->formats['P' . $this->format++] = $formatArray;
             //    Read cell value data
         } elseif ($dataType == 'C') {
             $hasCalculatedValue = false;
             $cellData = $cellDataFormula = '';
             foreach ($rowData as $rowDatum) {
                 switch ($rowDatum[0]) {
                     case 'C':
                     case 'X':
                         $column = substr($rowDatum, 1);
                         break;
                     case 'R':
                     case 'Y':
                         $row = substr($rowDatum, 1);
                         break;
                     case 'K':
                         $cellData = substr($rowDatum, 1);
                         break;
                     case 'E':
                         $cellDataFormula = '=' . substr($rowDatum, 1);
                         //    Convert R1C1 style references to A1 style references (but only when not quoted)
                         $temp = explode('"', $cellDataFormula);
                         $key = false;
                         foreach ($temp as &$value) {
                             //    Only count/replace in alternate array entries
                             if ($key = !$key) {
                                 preg_match_all('/(R(\\[?-?\\d*\\]?))(C(\\[?-?\\d*\\]?))/', $value, $cellReferences, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
                                 //    Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way
                                 //        through the formula from left to right. Reversing means that we work right to left.through
                                 //        the formula
                                 $cellReferences = array_reverse($cellReferences);
                                 //    Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent,
                                 //        then modify the formula to use that new reference
                                 foreach ($cellReferences as $cellReference) {
                                     $rowReference = $cellReference[2][0];
                                     //    Empty R reference is the current row
                                     if ($rowReference == '') {
                                         $rowReference = $row;
                                     }
                                     //    Bracketed R references are relative to the current row
                                     if ($rowReference[0] == '[') {
                                         $rowReference = $row + trim($rowReference, '[]');
                                     }
                                     $columnReference = $cellReference[4][0];
                                     //    Empty C reference is the current column
                                     if ($columnReference == '') {
                                         $columnReference = $column;
                                     }
                                     //    Bracketed C references are relative to the current column
                                     if ($columnReference[0] == '[') {
                                         $columnReference = $column + trim($columnReference, '[]');
                                     }
                                     $A1CellReference = \PHPExcel\Cell::stringFromColumnIndex($columnReference - 1) . $rowReference;
                                     $value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0]));
                                 }
                             }
                         }
                         unset($value);
                         //    Then rebuild the formula string
                         $cellDataFormula = implode('"', $temp);
                         $hasCalculatedValue = true;
                         break;
                 }
             }
             $columnLetter = \PHPExcel\Cell::stringFromColumnIndex($column - 1);
             $cellData = \PHPExcel\Calculation::unwrapResult($cellData);
             // Set cell value
             $objPHPExcel->getActiveSheet()->getCell($columnLetter . $row)->setValue($hasCalculatedValue ? $cellDataFormula : $cellData);
             if ($hasCalculatedValue) {
                 $cellData = \PHPExcel\Calculation::unwrapResult($cellData);
                 $objPHPExcel->getActiveSheet()->getCell($columnLetter . $row)->setCalculatedValue($cellData);
             }
             //    Read cell formatting
         } elseif ($dataType == 'F') {
             $formatStyle = $columnWidth = $styleSettings = '';
             $styleData = array();
             foreach ($rowData as $rowDatum) {
                 switch ($rowDatum[0]) {
                     case 'C':
                     case 'X':
                         $column = substr($rowDatum, 1);
                         break;
                     case 'R':
                     case 'Y':
                         $row = substr($rowDatum, 1);
                         break;
                     case 'P':
                         $formatStyle = $rowDatum;
                         break;
                     case 'W':
                         list($startCol, $endCol, $columnWidth) = explode(' ', substr($rowDatum, 1));
                         break;
                     case 'S':
                         $styleSettings = substr($rowDatum, 1);
                         for ($i = 0; $i < strlen($styleSettings); ++$i) {
                             switch ($styleSettings[$i]) {
                                 case 'I':
                                     $styleData['font']['italic'] = true;
                                     break;
                                 case 'D':
                                     $styleData['font']['bold'] = true;
                                     break;
                                 case 'T':
                                     $styleData['borders']['top']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                                 case 'B':
                                     $styleData['borders']['bottom']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                                 case 'L':
                                     $styleData['borders']['left']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                                 case 'R':
                                     $styleData['borders']['right']['style'] = \PHPExcel\Style\Border::BORDER_THIN;
                                     break;
                             }
                         }
                         break;
                 }
             }
             if ($formatStyle > '' && $column > '' && $row > '') {
                 $columnLetter = \PHPExcel\Cell::stringFromColumnIndex($column - 1);
                 if (isset($this->formats[$formatStyle])) {
                     $objPHPExcel->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($this->formats[$formatStyle]);
                 }
             }
             if (!empty($styleData) && $column > '' && $row > '') {
                 $columnLetter = \PHPExcel\Cell::stringFromColumnIndex($column - 1);
                 $objPHPExcel->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($styleData);
             }
             if ($columnWidth > '') {
                 if ($startCol == $endCol) {
                     $startCol = \PHPExcel\Cell::stringFromColumnIndex($startCol - 1);
                     $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
                 } else {
                     $startCol = \PHPExcel\Cell::stringFromColumnIndex($startCol - 1);
                     $endCol = \PHPExcel\Cell::stringFromColumnIndex($endCol - 1);
                     $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
                     do {
                         $objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth);
                     } while ($startCol != $endCol);
                 }
             }
         } else {
             foreach ($rowData as $rowDatum) {
                 switch ($rowDatum[0]) {
                     case 'C':
                     case 'X':
                         $column = substr($rowDatum, 1);
                         break;
                     case 'R':
                     case 'Y':
                         $row = substr($rowDatum, 1);
                         break;
                 }
             }
         }
     }
     // Close file
     fclose($fileHandle);
     // Return
     return $objPHPExcel;
 }
Exemple #6
0
 /**
  * Calculate information about HTML colspan and rowspan which is not always the same as Excel's
  */
 private function calculateSpans()
 {
     // Identify all cells that should be omitted in HTML due to cell merge.
     // In HTML only the upper-left cell should be written and it should have
     //   appropriate rowspan / colspan attribute
     $sheetIndexes = $this->sheetIndex !== null ? array($this->sheetIndex) : range(0, $this->phpExcel->getSheetCount() - 1);
     foreach ($sheetIndexes as $sheetIndex) {
         $sheet = $this->phpExcel->getSheet($sheetIndex);
         $candidateSpannedRow = array();
         // loop through all Excel merged cells
         foreach ($sheet->getMergeCells() as $cells) {
             list($cells, ) = \PHPExcel\Cell::splitRange($cells);
             $first = $cells[0];
             $last = $cells[1];
             list($fc, $fr) = \PHPExcel\Cell::coordinateFromString($first);
             $fc = \PHPExcel\Cell::columnIndexFromString($fc) - 1;
             list($lc, $lr) = \PHPExcel\Cell::coordinateFromString($last);
             $lc = \PHPExcel\Cell::columnIndexFromString($lc) - 1;
             // loop through the individual cells in the individual merge
             $r = $fr - 1;
             while ($r++ < $lr) {
                 // also, flag this row as a HTML row that is candidate to be omitted
                 $candidateSpannedRow[$r] = $r;
                 $c = $fc - 1;
                 while ($c++ < $lc) {
                     if (!($c == $fc && $r == $fr)) {
                         // not the upper-left cell (should not be written in HTML)
                         $this->isSpannedCell[$sheetIndex][$r][$c] = array('baseCell' => array($fr, $fc));
                     } else {
                         // upper-left is the base cell that should hold the colspan/rowspan attribute
                         $this->isBaseCell[$sheetIndex][$r][$c] = array('xlrowspan' => $lr - $fr + 1, 'rowspan' => $lr - $fr + 1, 'xlcolspan' => $lc - $fc + 1, 'colspan' => $lc - $fc + 1);
                     }
                 }
             }
         }
         // Identify which rows should be omitted in HTML. These are the rows where all the cells
         //   participate in a merge and the where base cells are somewhere above.
         $countColumns = \PHPExcel\Cell::columnIndexFromString($sheet->getHighestColumn());
         foreach ($candidateSpannedRow as $rowIndex) {
             if (isset($this->isSpannedCell[$sheetIndex][$rowIndex])) {
                 if (count($this->isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) {
                     $this->isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex;
                 }
             }
         }
         // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1
         if (isset($this->isSpannedRow[$sheetIndex])) {
             foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) {
                 $adjustedBaseCells = array();
                 $c = -1;
                 $e = $countColumns - 1;
                 while ($c++ < $e) {
                     $baseCell = $this->isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell'];
                     if (!in_array($baseCell, $adjustedBaseCells)) {
                         // subtract rowspan by 1
                         --$this->isBaseCell[$sheetIndex][$baseCell[0]][$baseCell[1]]['rowspan'];
                         $adjustedBaseCells[] = $baseCell;
                     }
                 }
             }
         }
         // TODO: Same for columns
     }
     // We have calculated the spans
     $this->spansAreCalculated = true;
 }