Вход Регистрация
Файл: protected/extensions/PHPExcel/Classes/PHPExcel/Writer/Excel5.php
Строк: 1148
<?php

/**
 * PHPExcel_Writer_Excel5
 *
 * Copyright (c) 2006 - 2015 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
 *
 * @category   PHPExcel
 * @package    PHPExcel_Writer_Excel5
 * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
 * @version    ##VERSION##, ##DATE##
 */
class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter
{
    
/**
     * PHPExcel object
     *
     * @var PHPExcel
     */
    
private $phpExcel;

    
/**
     * Total number of shared strings in workbook
     *
     * @var int
     */
    
private $strTotal 0;

    
/**
     * Number of unique shared strings in workbook
     *
     * @var int
     */
    
private $strUnique 0;

    
/**
     * Array of unique shared strings in workbook
     *
     * @var array
     */
    
private $strTable = array();

    
/**
     * Color cache. Mapping between RGB value and color index.
     *
     * @var array
     */
    
private $colors;

    
/**
     * Formula parser
     *
     * @var PHPExcel_Writer_Excel5_Parser
     */
    
private $parser;

    
/**
     * Identifier clusters for drawings. Used in MSODRAWINGGROUP record.
     *
     * @var array
     */
    
private $IDCLs;

    
/**
     * Basic OLE object summary information
     *
     * @var array
     */
    
private $summaryInformation;

    
/**
     * Extended OLE object document summary information
     *
     * @var array
     */
    
private $documentSummaryInformation;

    
/**
     * Create a new PHPExcel_Writer_Excel5
     *
     * @param    PHPExcel    $phpExcel    PHPExcel object
     */
    
public function __construct(PHPExcel $phpExcel)
    {
        
$this->phpExcel    $phpExcel;

        
$this->parser        = new PHPExcel_Writer_Excel5_Parser();
    }

    
/**
     * Save PHPExcel to file
     *
     * @param    string        $pFilename
     * @throws    PHPExcel_Writer_Exception
     */
    
public function save($pFilename null)
    {

        
// garbage collect
        
$this->phpExcel->garbageCollect();

        
$saveDebugLog PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog();
        
PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false);
        
$saveDateReturnType PHPExcel_Calculation_Functions::getReturnDateType();
        
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);

        
// initialize colors array
        
$this->colors = array();

        
// Initialise workbook writer
        
$this->writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->phpExcel$this->strTotal$this->strUnique$this->strTable$this->colors$this->parser);

        
// Initialise worksheet writers
        
$countSheets $this->phpExcel->getSheetCount();
        for (
$i 0$i $countSheets; ++$i) {
            
$this->writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal$this->strUnique$this->strTable$this->colors$this->parser$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);
        }

        
// add all the cell Xfs
        
foreach ($this->phpExcel->getCellXfCollection() as $style) {
            
$this->writerWorkbook->addXfWriter($stylefalse);
        }

        
// add fonts from rich text eleemnts
        
for ($i 0$i $countSheets; ++$i) {
            foreach (
$this->writerWorksheets[$i]->phpSheet->getCellCollection() as $cellID) {
                
$cell $this->writerWorksheets[$i]->phpSheet->getCell($cellID);
                
$cVal $cell->getValue();
                if (
$cVal instanceof PHPExcel_RichText) {
                    
$elements $cVal->getRichTextElements();
                    foreach (
$elements as $element) {
                        if (
$element instanceof PHPExcel_RichText_Run) {
                            
$font $element->getFont();
                            
$this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font);
                        }
                    }
                }
            }
        }

        
// initialize OLE file
        
$workbookStreamName 'Workbook';
        
$OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName));

        
// 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());
        }

        
$this->documentSummaryInformation $this->writeDocumentSummaryInformation();
        
// initialize OLE Document Summary Information
        
if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) {
            
$OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation'));
            
$OLE_DocumentSummaryInformation->append($this->documentSummaryInformation);
        }

        
$this->summaryInformation $this->writeSummaryInformation();
        
// initialize OLE Summary Information
        
if (isset($this->summaryInformation) && !empty($this->summaryInformation)) {
            
$OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation'));
            
$OLE_SummaryInformation->append($this->summaryInformation);
        }

        
// define OLE Parts
        
$arrRootData = array($OLE);
        
// initialize OLE Properties file
        
if (isset($OLE_SummaryInformation)) {
            
$arrRootData[] = $OLE_SummaryInformation;
        }
        
// initialize OLE Extended Properties file
        
if (isset($OLE_DocumentSummaryInformation)) {
            
$arrRootData[] = $OLE_DocumentSummaryInformation;
        }

        
$root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData);
        
// save the OLE file
        
$res $root->save($pFilename);

        
PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
        
PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
    }

    
/**
     * Set temporary storage directory
     *
     * @deprecated
     * @param    string    $pValue        Temporary storage directory
     * @throws    PHPExcel_Writer_Exception    when directory does not exist
     * @return PHPExcel_Writer_Excel5
     */
    
public function setTempDir($pValue '')
    {
        return 
$this;
    }

    
/**
     * Build the Worksheet Escher objects
     *
     */
    
private function buildWorksheetEschers()
    {
        
// 1-based index to BstoreContainer
        
$blipIndex 0;
        
$lastReducedSpId 0;
        
$lastSpId 0;

        foreach (
$this->phpExcel->getAllsheets() as $sheet) {
            
// sheet index
            
$sheetIndex $sheet->getParent()->getIndex($sheet);

            
$escher null;

            
// check if there are any shapes for this sheet
            
$filterRange $sheet->getAutoFilter()->getRange();
            if (
count($sheet->getDrawingCollection()) == && empty($filterRange)) {
                continue;
            }

            
// create intermediate Escher object
            
$escher = new PHPExcel_Shared_Escher();

            
// dgContainer
            
$dgContainer = new PHPExcel_Shared_Escher_DgContainer();

            
// set the drawing index (we use sheet index + 1)
            
$dgId $sheet->getParent()->getIndex($sheet) + 1;
            
$dgContainer->setDgId($dgId);
            
$escher->setDgContainer($dgContainer);

            
// spgrContainer
            
$spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer();
            
$dgContainer->setSpgrContainer($spgrContainer);

            
// add one shape which is the group shape
            
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
            
$spContainer->setSpgr(true);
            
$spContainer->setSpType(0);
            
$spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);
            
$spgrContainer->addChild($spContainer);

            
// add the shapes

            
$countShapes[$sheetIndex] = 0// count number of shapes (minus group shape), in sheet

            
foreach ($sheet->getDrawingCollection() as $drawing) {
                ++
$blipIndex;

                ++
$countShapes[$sheetIndex];

                
// add the shape
                
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();

                
// set the shape type
                
$spContainer->setSpType(0x004B);
                
// set the shape flag
                
$spContainer->setSpFlag(0x02);

                
// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
                
$reducedSpId $countShapes[$sheetIndex];
                
$spId $reducedSpId
                    
| ($sheet->getParent()->getIndex($sheet) + 1) << 10;
                
$spContainer->setSpId($spId);

                
// keep track of last reducedSpId
                
$lastReducedSpId $reducedSpId;

                
// keep track of last spId
                
$lastSpId $spId;

                
// set the BLIP index
                
$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();

                
$twoAnchor PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet$coordinates$offsetX$offsetY$width$height);

                
$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);
            }

            
// AutoFilters
            
if (!empty($filterRange)) {
                
$rangeBounds PHPExcel_Cell::rangeBoundaries($filterRange);
                
$iNumColStart $rangeBounds[0][0];
                
$iNumColEnd $rangeBounds[1][0];

                
$iInc $iNumColStart;
                while (
$iInc <= $iNumColEnd) {
                    ++
$countShapes[$sheetIndex];

                    
// create an Drawing Object for the dropdown
                    
$oDrawing  = new PHPExcel_Worksheet_BaseDrawing();
                    
// get the coordinates of drawing
                    
$cDrawing   PHPExcel_Cell::stringFromColumnIndex($iInc 1) . $rangeBounds[0][1];
                    
$oDrawing->setCoordinates($cDrawing);
                    
$oDrawing->setWorksheet($sheet);

                    
// add the shape
                    
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
                    
// set the shape type
                    
$spContainer->setSpType(0x00C9);
                    
// set the shape flag
                    
$spContainer->setSpFlag(0x01);

                    
// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
                    
$reducedSpId $countShapes[$sheetIndex];
                    
$spId $reducedSpId
                        
| ($sheet->getParent()->getIndex($sheet) + 1) << 10;
                    
$spContainer->setSpId($spId);

                    
// keep track of last reducedSpId
                    
$lastReducedSpId $reducedSpId;

                    
// keep track of last spId
                    
$lastSpId $spId;

                    
$spContainer->setOPT(0x007F0x01040104); // Protection -> fLockAgainstGrouping
                    
$spContainer->setOPT(0x00BF0x00080008); // Text -> fFitTextToShape
                    
$spContainer->setOPT(0x01BF0x00010000); // Fill Style -> fNoFillHitTest
                    
$spContainer->setOPT(0x01FF0x00080000); // Line Style -> fNoLineDrawDash
                    
$spContainer->setOPT(0x03BF0x000A0000); // Group Shape -> fPrint

                    // set coordinates and offsets, client anchor
                    
$endCoordinates PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc 1));
                    
$endCoordinates .= $rangeBounds[0][1] + 1;

                    
$spContainer->setStartCoordinates($cDrawing);
                    
$spContainer->setStartOffsetX(0);
                    
$spContainer->setStartOffsetY(0);
                    
$spContainer->setEndCoordinates($endCoordinates);
                    
$spContainer->setEndOffsetX(0);
                    
$spContainer->setEndOffsetY(0);

                    
$spgrContainer->addChild($spContainer);
                    
$iInc++;
                }
            }

            
// identifier clusters, used for workbook Escher object
            
$this->IDCLs[$dgId] = $lastReducedSpId;

            
// set last shape index
            
$dgContainer->setLastSpId($lastSpId);

            
// set the Escher object
            
$this->writerWorksheets[$sheetIndex]->setEscher($escher);
        }
    }

    
/**
     * Build the Escher object corresponding to the MSODRAWINGGROUP record
     */
    
private function buildWorkbookEscher()
    {
        
$escher null;

        
// any drawings in this workbook?
        
$found false;
        foreach (
$this->phpExcel->getAllSheets() as $sheet) {
            if (
count($sheet->getDrawingCollection()) > 0) {
                
$found true;
                break;
            }
        }

        
// nothing to do if there are no drawings
        
if (!$found) {
            return;
        }

        
// if we reach here, then there are drawings in the workbook
        
$escher = new PHPExcel_Shared_Escher();

        
// dggContainer
        
$dggContainer = new PHPExcel_Shared_Escher_DggContainer();
        
$escher->setDggContainer($dggContainer);

        
// set IDCLs (identifier clusters)
        
$dggContainer->setIDCLs($this->IDCLs);

        
// this loop is for determining maximum shape identifier of all drawing
        
$spIdMax 0;
        
$totalCountShapes 0;
        
$countDrawings 0;

        foreach (
$this->phpExcel->getAllsheets() as $sheet) {
            
$sheetCountShapes 0// count number of shapes (minus group shape), in sheet

            
if (count($sheet->getDrawingCollection()) > 0) {
                ++
$countDrawings;

                foreach (
$sheet->getDrawingCollection() as $drawing) {
                    ++
$sheetCountShapes;
                    ++
$totalCountShapes;

                    
$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

        // bstoreContainer
        
$bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer();
        
$dggContainer->setBstoreContainer($bstoreContainer);

        
// the BSE's (all the images)
        
foreach ($this->phpExcel->getAllsheets() as $sheet) {
            foreach (
$sheet->getDrawingCollection() as $drawing) {
                if (
$drawing instanceof PHPExcel_Worksheet_Drawing) {
                    
$filename $drawing->getPath();

                    list(
$imagesx$imagesy$imageFormat) = getimagesize($filename);

                    switch (
$imageFormat) {
                        case 
1// GIF, not supported by BIFF8, we convert to PNG
                            
$blipType PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
                            
ob_start();
                            
imagepng(imagecreatefromgif($filename));
                            
$blipData ob_get_contents();
                            
ob_end_clean();
                            break;
                        case 
2// JPEG
                            
$blipType PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG;
                            
$blipData file_get_contents($filename);
                            break;
                        case 
3// PNG
                            
$blipType PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
                            
$blipData file_get_contents($filename);
                            break;
                        case 
6// Windows DIB (BMP), we convert to PNG
                            
$blipType PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
                            
ob_start();
                            
imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename));
                            
$blipData ob_get_contents();
                            
ob_end_clean();
                            break;
                        default:
                            continue 
2;
                    }

                    
$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();
                    
$blip->setData($blipData);

                    
$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();
                    
$BSE->setBlipType($blipType);
                    
$BSE->setBlip($blip);

                    
$bstoreContainer->addBSE($BSE);
                } elseif (
$drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {
                    switch (
$drawing->getRenderingFunction()) {
                        case 
PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG:
                            
$blipType PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG;
                            
$renderingFunction 'imagejpeg';
                            break;
                        case 
PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF:
                        case 
PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG:
                        case 
PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT:
                            
$blipType PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;
                            
$renderingFunction 'imagepng';
                            break;
                    }

                    
ob_start();
                    
call_user_func($renderingFunction$drawing->getImageResource());
                    
$blipData ob_get_contents();
                    
ob_end_clean();

                    
$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();
                    
$blip->setData($blipData);

                    
$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();
                    
$BSE->setBlipType($blipType);
                    
$BSE->setBlip($blip);

                    
$bstoreContainer->addBSE($BSE);
                }
            }
        }

        
// Set the Escher object
        
$this->writerWorkbook->setEscher($escher);
    }

    
/**
     * Build the OLE Part for DocumentSummary Information
     * @return string
     */
    
private function writeDocumentSummaryInformation()
    {
        
// offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
        
$data pack('v'0xFFFE);
        
// offset: 2; size: 2;
        
$data .= pack('v'0x0000);
        
// offset: 4; size: 2; OS version
        
$data .= pack('v'0x0106);
        
// offset: 6; size: 2; OS indicator
        
$data .= pack('v'0x0002);
        
// offset: 8; size: 16
        
$data .= pack('VVVV'0x000x000x000x00);
        
// offset: 24; size: 4; section count
        
$data .= pack('V'0x0001);

        
// offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae
        
$data .= pack('vvvvvvvv'0xD5020xD5CD0x2E9C0x101B0x97930x00080x2C2B0xAEF9);
        
// offset: 44; size: 4; offset of the start
        
$data .= pack('V'0x30);

        
// SECTION
        
$dataSection = array();
        
$dataSection_NumProps 0;
        
$dataSection_Summary '';
        
$dataSection_Content '';

        
// GKPIDDSI_CODEPAGE: CodePage
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x01),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x02), // 2 byte signed integer
                               
'data'    => array('data' => 1252));
        
$dataSection_NumProps++;

        
// GKPIDDSI_CATEGORY : Category
        
if ($this->phpExcel->getProperties()->getCategory()) {
            
$dataProp $this->phpExcel->getProperties()->getCategory();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x02),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E),
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
// GKPIDDSI_VERSION :Version of the application that wrote the property storage
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x17),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x03),
                               
'data'    => array('pack' => 'V''data' => 0x000C0000));
        
$dataSection_NumProps++;
        
// GKPIDDSI_SCALE : FALSE
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x0B),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x0B),
                               
'data'    => array('data' => false));
        
$dataSection_NumProps++;
        
// GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x10),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x0B),
                               
'data'    => array('data' => false));
        
$dataSection_NumProps++;
        
// GKPIDDSI_SHAREDOC : FALSE
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x13),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x0B),
                               
'data'    => array('data' => false));
        
$dataSection_NumProps++;
        
// GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x16),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x0B),
                               
'data'    => array('data' => false));
        
$dataSection_NumProps++;

        
// GKPIDDSI_DOCSPARTS
        // MS-OSHARED p75 (2.3.3.2.2.1)
        // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9)
        // cElements
        
$dataProp pack('v'0x0001);
        
$dataProp .= pack('v'0x0000);
        
// array of UnalignedLpstr
          // cch
          
$dataProp .= pack('v'0x000A);
          
$dataProp .= pack('v'0x0000);
          
// value
          
$dataProp .= 'Worksheet'.chr(0);

        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x0D),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x101E),
                               
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
        
$dataSection_NumProps++;

        
// GKPIDDSI_HEADINGPAIR
        // VtVecHeadingPairValue
          // cElements
          
$dataProp pack('v'0x0002);
          
$dataProp .= pack('v'0x0000);
          
// Array of vtHeadingPair
            // vtUnalignedString - headingString
              // stringType
              
$dataProp .= pack('v'0x001E);
              
// padding
              
$dataProp .= pack('v'0x0000);
              
// UnalignedLpstr
                // cch
                
$dataProp .= pack('v'0x0013);
                
$dataProp .= pack('v'0x0000);
                
// value
                
$dataProp .= 'Feuilles de calcul';
            
// vtUnalignedString - headingParts
              // wType : 0x0003 = 32 bit signed integer
              
$dataProp .= pack('v'0x0300);
              
// padding
              
$dataProp .= pack('v'0x0000);
              
// value
              
$dataProp .= pack('v'0x0100);
              
$dataProp .= pack('v'0x0000);
              
$dataProp .= pack('v'0x0000);
              
$dataProp .= pack('v'0x0000);

        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x0C),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x100C),
                               
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
        
$dataSection_NumProps++;

        
//         4     Section Length
        //        4     Property count
        //        8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))
        
$dataSection_Content_Offset $dataSection_NumProps 8;
        foreach (
$dataSection as $dataProp) {
            
// Summary
            
$dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
            
// Offset
            
$dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
            
// DataType
            
$dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
            
// Data
            
if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
                
$dataSection_Content .= pack('V'$dataProp['data']['data']);

                
$dataSection_Content_Offset += 4;
            } elseif (
$dataProp['type']['data'] == 0x03) { // 4 byte signed integer
                
$dataSection_Content .= pack('V'$dataProp['data']['data']);

                
$dataSection_Content_Offset += 4;
            } elseif (
$dataProp['type']['data'] == 0x0B) { // Boolean
                
if ($dataProp['data']['data'] == false) {
                    
$dataSection_Content .= pack('V'0x0000);
                } else {
                    
$dataSection_Content .= pack('V'0x0001);
                }
                
$dataSection_Content_Offset += 4;
            } elseif (
$dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
                // Null-terminated string
                
$dataProp['data']['data'] .= chr(0);
                
$dataProp['data']['length'] += 1;
                
// Complete the string with null string for being a %4
                
$dataProp['data']['length'] = $dataProp['data']['length'] + (($dataProp['data']['length'] % 4)==: ($dataProp['data']['length'] % 4));
                
$dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);

                
$dataSection_Content .= pack('V'$dataProp['data']['length']);
                
$dataSection_Content .= $dataProp['data']['data'];

                
$dataSection_Content_Offset += strlen($dataProp['data']['data']);
            } elseif (
$dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
                
$dataSection_Content .= $dataProp['data']['data'];

                
$dataSection_Content_Offset += 8;
            } else {
                
// Data Type Not Used at the moment
                
$dataSection_Content .= $dataProp['data']['data'];

                
$dataSection_Content_Offset += $dataProp['data']['length'];
            }
        }
        
// Now $dataSection_Content_Offset contains the size of the content

        // section header
        // offset: $secOffset; size: 4; section length
        //         + x  Size of the content (summary + content)
        
$data .= pack('V'$dataSection_Content_Offset);
        
// offset: $secOffset+4; size: 4; property count
        
$data .= pack('V'$dataSection_NumProps);
        
// Section Summary
        
$data .= $dataSection_Summary;
        
// Section Content
        
$data .= $dataSection_Content;

        return 
$data;
    }

    
/**
     * Build the OLE Part for Summary Information
     * @return string
     */
    
private function writeSummaryInformation()
    {
        
// offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
        
$data pack('v'0xFFFE);
        
// offset: 2; size: 2;
        
$data .= pack('v'0x0000);
        
// offset: 4; size: 2; OS version
        
$data .= pack('v'0x0106);
        
// offset: 6; size: 2; OS indicator
        
$data .= pack('v'0x0002);
        
// offset: 8; size: 16
        
$data .= pack('VVVV'0x000x000x000x00);
        
// offset: 24; size: 4; section count
        
$data .= pack('V'0x0001);

        
// offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9
        
$data .= pack('vvvvvvvv'0x85E00xF29F0x4FF90x10680x91AB0x00080x272B0xD9B3);
        
// offset: 44; size: 4; offset of the start
        
$data .= pack('V'0x30);

        
// SECTION
        
$dataSection = array();
        
$dataSection_NumProps 0;
        
$dataSection_Summary '';
        
$dataSection_Content '';

        
// CodePage : CP-1252
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x01),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x02), // 2 byte signed integer
                               
'data'    => array('data' => 1252));
        
$dataSection_NumProps++;

        
//    Title
        
if ($this->phpExcel->getProperties()->getTitle()) {
            
$dataProp $this->phpExcel->getProperties()->getTitle();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x02),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E), // null-terminated string prepended by dword string length
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Subject
        
if ($this->phpExcel->getProperties()->getSubject()) {
            
$dataProp $this->phpExcel->getProperties()->getSubject();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x03),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E), // null-terminated string prepended by dword string length
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Author (Creator)
        
if ($this->phpExcel->getProperties()->getCreator()) {
            
$dataProp $this->phpExcel->getProperties()->getCreator();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x04),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E), // null-terminated string prepended by dword string length
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Keywords
        
if ($this->phpExcel->getProperties()->getKeywords()) {
            
$dataProp $this->phpExcel->getProperties()->getKeywords();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x05),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E), // null-terminated string prepended by dword string length
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Comments (Description)
        
if ($this->phpExcel->getProperties()->getDescription()) {
            
$dataProp $this->phpExcel->getProperties()->getDescription();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x06),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E), // null-terminated string prepended by dword string length
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Last Saved By (LastModifiedBy)
        
if ($this->phpExcel->getProperties()->getLastModifiedBy()) {
            
$dataProp $this->phpExcel->getProperties()->getLastModifiedBy();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x08),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x1E), // null-terminated string prepended by dword string length
                                   
'data'    => array('data' => $dataProp'length' => strlen($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Created Date/Time
        
if ($this->phpExcel->getProperties()->getCreated()) {
            
$dataProp $this->phpExcel->getProperties()->getCreated();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x0C),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
                                   
'data'    => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Modified Date/Time
        
if ($this->phpExcel->getProperties()->getModified()) {
            
$dataProp $this->phpExcel->getProperties()->getModified();
            
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x0D),
                                   
'offset' => array('pack' => 'V'),
                                   
'type'     => array('pack' => 'V''data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
                                   
'data'    => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp)));
            
$dataSection_NumProps++;
        }
        
//    Security
        
$dataSection[] = array('summary'=> array('pack' => 'V''data' => 0x13),
                               
'offset' => array('pack' => 'V'),
                               
'type'     => array('pack' => 'V''data' => 0x03), // 4 byte signed integer
                               
'data'    => array('data' => 0x00));
        
$dataSection_NumProps++;


        
//         4     Section Length
        //        4     Property count
        //        8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))
        
$dataSection_Content_Offset $dataSection_NumProps 8;
        foreach (
$dataSection as $dataProp) {
            
// Summary
            
$dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
            
// Offset
            
$dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
            
// DataType
            
$dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
            
// Data
            
if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
                
$dataSection_Content .= pack('V'$dataProp['data']['data']);

                
$dataSection_Content_Offset += 4;
            } elseif (
$dataProp['type']['data'] == 0x03) { // 4 byte signed integer
                
$dataSection_Content .= pack('V'$dataProp['data']['data']);

                
$dataSection_Content_Offset += 4;
            } elseif (
$dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
                // Null-terminated string
                
$dataProp['data']['data'] .= chr(0);
                
$dataProp['data']['length'] += 1;
                
// Complete the string with null string for being a %4
                
$dataProp['data']['length'] = $dataProp['data']['length'] + (($dataProp['data']['length'] % 4)==: ($dataProp['data']['length'] % 4));
                
$dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);

                
$dataSection_Content .= pack('V'$dataProp['data']['length']);
                
$dataSection_Content .= $dataProp['data']['data'];

                
$dataSection_Content_Offset += strlen($dataProp['data']['data']);
            } elseif (
$dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
                
$dataSection_Content .= $dataProp['data']['data'];

                
$dataSection_Content_Offset += 8;
            } else {
                
// Data Type Not Used at the moment
            
}
        }
        
// Now $dataSection_Content_Offset contains the size of the content

        // section header
        // offset: $secOffset; size: 4; section length
        //         + x  Size of the content (summary + content)
        
$data .= pack('V'$dataSection_Content_Offset);
        
// offset: $secOffset+4; size: 4; property count
        
$data .= pack('V'$dataSection_NumProps);
        
// Section Summary
        
$data .= $dataSection_Summary;
        
// Section Content
        
$data .= $dataSection_Content;

        return 
$data;
    }
}
Онлайн: 0
Реклама