Source for file Excel5.php
Documentation is available at Excel5.php
* Copyright (c) 2006 - 2011 PHPExcel
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* @package PHPExcel_Writer_Excel5
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version 1.7.6, 2011-02-27
* @package PHPExcel_Writer_Excel5
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
private $_preCalculateFormulas = true;
* The BIFF version of the written Excel file, BIFF5 = 0x0500, BIFF8 = 0x0600
private $_BIFF_version = 0x0600;
* Total number of shared strings in workbook
* Number of unique shared strings in workbook
private $_str_unique = 0;
* Array of unique shared strings in workbook
private $_str_table = array();
* Color cache. Mapping between RGB value and color index.
* @var PHPExcel_Writer_Excel5_Parser
* Identifier clusters for drawings. Used in MSODRAWINGGROUP record.
* Create a new PHPExcel_Writer_Excel5
* @param PHPExcel $phpExcel PHPExcel object
$this->_phpExcel = $phpExcel;
* @param string $pFileName
public function save($pFilename = null) {
$this->_phpExcel->garbageCollect();
// initialize colors array
$this->_colors = array();
// Initialise workbook writer
$this->_str_total, $this->_str_unique, $this->_str_table, $this->_colors, $this->_parser);
// Initialise worksheet writers
$countSheets = $this->_phpExcel->getSheetCount();
for ($i = 0; $i < $countSheets; ++ $i) {
$this->_str_total, $this->_str_unique,
$this->_str_table, $this->_colors,
$this->_preCalculateFormulas,
$this->_phpExcel->getSheet($i));
// build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook.
$this->_buildWorksheetEschers();
$this->_buildWorkbookEscher();
// add 15 identical cell style Xfs
// for now, we use the first cellXf instead of cellStyleXf
$cellXfCollection = $this->_phpExcel->getCellXfCollection();
for ($i = 0; $i < 15; ++ $i) {
$this->_writerWorkbook->addXfWriter($cellXfCollection[0], true);
foreach ($this->_phpExcel->getCellXfCollection() as $style) {
$this->_writerWorkbook->addXfWriter($style, false);
$workbookStreamName = ($this->_BIFF_version == 0x0600) ? 'Workbook' : 'Book';
// Write the worksheet streams before the global workbook stream,
// because the byte sizes of these are needed in the global workbook stream
$worksheetSizes = array();
for ($i = 0; $i < $countSheets; ++ $i) {
$this->_writerWorksheets[$i]->close();
$worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize;
// add binary data for global workbook stream
$OLE->append( $this->_writerWorkbook->writeWorkbook($worksheetSizes) );
// add binary data for sheet streams
for ($i = 0; $i < $countSheets; ++ $i) {
$OLE->append($this->_writerWorksheets[$i]->getData());
$res = $root->save($pFilename);
* Set temporary storage directory
* @param string $pValue Temporary storage directory
* @throws Exception Exception when directory does not exist
* @return PHPExcel_Writer_Excel5
* Get Pre-Calculate Formulas
return $this->_preCalculateFormulas;
* Set Pre-Calculate Formulas
* @param boolean $pValue Pre-Calculate Formulas?
$this->_preCalculateFormulas = $pValue;
private function _buildWorksheetEschers()
// 1-based index to BstoreContainer
foreach ($this->_phpExcel->getAllsheets() as $sheet) {
$sheetIndex = $sheet->getParent()->getIndex($sheet);
// check if there are any shapes for this sheet
if (count($sheet->getDrawingCollection()) == 0) {
// create intermediate Escher object
// set the drawing index (we use sheet index + 1)
$dgId = $sheet->getParent()->getIndex($sheet) + 1;
$dgContainer->setDgId($dgId);
$escher->setDgContainer($dgContainer);
$dgContainer->setSpgrContainer($spgrContainer);
// add one shape which is the group shape
$spContainer->setSpgr(true);
$spContainer->setSpType(0);
$spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);
$spgrContainer->addChild($spContainer);
$countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet
foreach ($sheet->getDrawingCollection() as $drawing) {
++ $countShapes[$sheetIndex];
$spContainer->setSpType(0x004B);
// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
$reducedSpId = $countShapes[$sheetIndex];
| ($sheet->getParent()->getIndex($sheet) + 1) << 10;
$spContainer->setSpId($spId);
// keep track of last reducedSpId
$lastReducedSpId = $reducedSpId;
// keep track of last spId
$spContainer->setOPT(0x4104, $blipIndex);
// set coordinates and offsets, client anchor
$coordinates = $drawing->getCoordinates();
$offsetX = $drawing->getOffsetX();
$offsetY = $drawing->getOffsetY();
$width = $drawing->getWidth();
$height = $drawing->getHeight();
$spContainer->setStartCoordinates($twoAnchor['startCoordinates']);
$spContainer->setStartOffsetX($twoAnchor['startOffsetX']);
$spContainer->setStartOffsetY($twoAnchor['startOffsetY']);
$spContainer->setEndCoordinates($twoAnchor['endCoordinates']);
$spContainer->setEndOffsetX($twoAnchor['endOffsetX']);
$spContainer->setEndOffsetY($twoAnchor['endOffsetY']);
$spgrContainer->addChild($spContainer);
// identifier clusters, used for workbook Escher object
$this->_IDCLs[$dgId] = $lastReducedSpId;
$dgContainer->setLastSpId($lastSpId);
$this->_writerWorksheets[$sheetIndex]->setEscher($escher);
* Build the Escher object corresponding to the MSODRAWINGGROUP record
private function _buildWorkbookEscher()
// any drawings in this workbook?
foreach ($this->_phpExcel->getAllSheets() as $sheet) {
if (count($sheet->getDrawingCollection()) > 0) {
// nothing to do if there are no drawings
// if we reach here, then there are drawings in the workbook
$escher->setDggContainer($dggContainer);
// set IDCLs (identifier clusters)
$dggContainer->setIDCLs($this->_IDCLs);
// this loop is for determining maximum shape identifier of all drawing
foreach ($this->_phpExcel->getAllsheets() as $sheet) {
$sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet
if (count($sheet->getDrawingCollection()) > 0) {
foreach ($sheet->getDrawingCollection() as $drawing) {
$spId = $sheetCountShapes
| ($this->_phpExcel->getIndex($sheet) + 1) << 10;
$spIdMax = max($spId, $spIdMax);
$dggContainer->setSpIdMax($spIdMax + 1);
$dggContainer->setCDgSaved($countDrawings);
$dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing
$dggContainer->setBstoreContainer($bstoreContainer);
// the BSE's (all the images)
foreach ($this->_phpExcel->getAllsheets() as $sheet) {
foreach ($sheet->getDrawingCollection() as $drawing) {
$filename = $drawing->getPath();
list ($imagesx, $imagesy, $imageFormat) = getimagesize($filename);
case 1: // GIF, not supported by BIFF8, we convert to PNG
case 6: // Windows DIB (BMP), we convert to PNG
$blip->setData($blipData);
$BSE->setBlipType($blipType);
$bstoreContainer->addBSE($BSE);
switch ($drawing->getRenderingFunction()) {
$renderingFunction = 'imagejpeg';
$renderingFunction = 'imagepng';
$blip->setData($blipData);
$BSE->setBlipType($blipType);
$bstoreContainer->addBSE($BSE);
$this->_writerWorkbook->setEscher($escher);
|