/** * Process the object to be written */ public function close() { // initialize $this->_data = ''; switch (get_class($this->_object)) { case 'PHPExcel_Shared_Escher': if ($dggContainer = $this->_object->getDggContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); $this->_data = $writer->close(); } else { if ($dgContainer = $this->_object->getDgContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); $this->_data = $writer->close(); $this->_spOffsets = $writer->getSpOffsets(); $this->_spTypes = $writer->getSpTypes(); } } break; case 'PHPExcel_Shared_Escher_DggContainer': // this is a container record // initialize $innerData = ''; // write the dgg $recVer = 0x0; $recInstance = 0x0; $recType = 0xf006; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; // dgg data $dggData = pack('VVVV', $this->_object->getSpIdMax(), $this->_object->getCDgSaved() + 1, $this->_object->getCSpSaved(), $this->_object->getCDgSaved()); // add file identifier clusters (one per drawing) $IDCLs = $this->_object->getIDCLs(); foreach ($IDCLs as $dgId => $maxReducedSpId) { $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); } $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); $innerData .= $header . $dggData; // write the bstoreContainer if ($bstoreContainer = $this->_object->getBstoreContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); $innerData .= $writer->close(); } // write the record $recVer = 0xf; $recInstance = 0x0; $recType = 0xf000; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': // this is a container record // initialize $innerData = ''; // treat the inner data if ($BSECollection = $this->_object->getBSECollection()) { foreach ($BSECollection as $BSE) { $writer = new PHPExcel_Writer_Excel5_Escher($BSE); $innerData .= $writer->close(); } } // write the record $recVer = 0xf; $recInstance = count($this->_object->getBSECollection()); $recType = 0xf001; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': // this is a semi-container record // initialize $innerData = ''; // here we treat the inner data if ($blip = $this->_object->getBlip()) { $writer = new PHPExcel_Writer_Excel5_Escher($blip); $innerData .= $writer->close(); } // initialize $data = ''; $btWin32 = $this->_object->getBlipType(); $btMacOS = $this->_object->getBlipType(); $data .= pack('CC', $btWin32, $btMacOS); $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo $data .= $rgbUid; $tag = 0; $size = strlen($innerData); $cRef = 1; $foDelay = 0; //todo $unused1 = 0x0; $cbName = 0x0; $unused2 = 0x0; $unused3 = 0x0; $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); $data .= $innerData; // write the record $recVer = 0x2; $recInstance = $this->_object->getBlipType(); $recType = 0xf007; $length = strlen($data); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header; $this->_data .= $data; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': // this is an atom record // write the record switch ($this->_object->getParent()->getBlipType()) { case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: // initialize $innerData = ''; $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo $innerData .= $rgbUid1; $tag = 0xff; // todo $innerData .= pack('C', $tag); $innerData .= $this->_object->getData(); $recVer = 0x0; $recInstance = 0x46a; $recType = 0xf01d; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header; $this->_data .= $innerData; break; case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: // initialize $innerData = ''; $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo $innerData .= $rgbUid1; $tag = 0xff; // todo $innerData .= pack('C', $tag); $innerData .= $this->_object->getData(); $recVer = 0x0; $recInstance = 0x6e0; $recType = 0xf01e; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header; $this->_data .= $innerData; break; } break; case 'PHPExcel_Shared_Escher_DgContainer': // this is a container record // initialize $innerData = ''; // write the dg $recVer = 0x0; $recInstance = $this->_object->getDgId(); $recType = 0xf008; $length = 8; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); // number of shapes in this drawing (including group shape) $countShapes = count($this->_object->getSpgrContainer()->getChildren()); $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); //$innerData .= $header . pack('VV', 0, 0); // write the spgrContainer if ($spgrContainer = $this->_object->getSpgrContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); $innerData .= $writer->close(); // get the shape offsets relative to the spgrContainer record $spOffsets = $writer->getSpOffsets(); $spTypes = $writer->getSpTypes(); // save the shape offsets relative to dgContainer foreach ($spOffsets as &$spOffset) { $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) } $this->_spOffsets = $spOffsets; $this->_spTypes = $spTypes; } // write the record $recVer = 0xf; $recInstance = 0x0; $recType = 0xf002; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': // this is a container record // initialize $innerData = ''; // initialize spape offsets $totalSize = 8; $spOffsets = array(); $spTypes = array(); // treat the inner data foreach ($this->_object->getChildren() as $spContainer) { $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); $spData = $writer->close(); $innerData .= $spData; // save the shape offsets (where new shape records begin) $totalSize += strlen($spData); $spOffsets[] = $totalSize; $spTypes = array_merge($spTypes, $writer->getSpTypes()); } // write the record $recVer = 0xf; $recInstance = 0x0; $recType = 0xf003; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header . $innerData; $this->_spOffsets = $spOffsets; $this->_spTypes = $spTypes; break; case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': // initialize $data = ''; // build the data // write group shape record, if necessary? if ($this->_object->getSpgr()) { $recVer = 0x1; $recInstance = 0x0; $recType = 0xf009; $length = 0x10; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . pack('VVVV', 0, 0, 0, 0); } $this->_spTypes[] = $this->_object->getSpType(); // write the shape record $recVer = 0x2; $recInstance = $this->_object->getSpType(); // shape type $recType = 0xf00a; $length = 0x8; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x5 : 0xa00); // the options if ($this->_object->getOPTCollection()) { $optData = ''; $recVer = 0x3; $recInstance = count($this->_object->getOPTCollection()); $recType = 0xf00b; foreach ($this->_object->getOPTCollection() as $property => $value) { $optData .= pack('vV', $property, $value); } $length = strlen($optData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . $optData; } // the client anchor if ($this->_object->getStartCoordinates()) { $clientAnchorData = ''; $recVer = 0x0; $recInstance = 0x0; $recType = 0xf010; // start coordinates list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; $r1 = $row - 1; // start offsetX $startOffsetX = $this->_object->getStartOffsetX(); // start offsetY $startOffsetY = $this->_object->getStartOffsetY(); // end coordinates list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; $r2 = $row - 1; // end offsetX $endOffsetX = $this->_object->getEndOffsetX(); // end offsetY $endOffsetY = $this->_object->getEndOffsetY(); $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY); $length = strlen($clientAnchorData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . $clientAnchorData; } // the client data, just empty for now if (!$this->_object->getSpgr()) { $clientDataData = ''; $recVer = 0x0; $recInstance = 0x0; $recType = 0xf011; $length = strlen($clientDataData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . $clientDataData; } // write the record $recVer = 0xf; $recInstance = 0x0; $recType = 0xf004; $length = strlen($data); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->_data = $header . $data; break; } return $this->_data; }
/** * Write MSODRAWING record */ private function _writeMsoDrawing() { // write the Escher stream if necessary if (isset($this->_escher)) { $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); $data = $writer->close(); $spOffsets = $writer->getSpOffsets(); $spTypes = $writer->getSpTypes(); // write the neccesary MSODRAWING, OBJ records // split the Escher stream $spOffsets[0] = 0; $nm = count($spOffsets) - 1; // number of shapes excluding first shape for ($i = 1; $i <= $nm; ++$i) { // MSODRAWING record $record = 0xec; // Record identifier // chunk of Escher stream for one shape $dataChunk = substr($data, $spOffsets[$i - 1], $spOffsets[$i] - $spOffsets[$i - 1]); $length = strlen($dataChunk); $header = pack("vv", $record, $length); $this->_append($header . $dataChunk); // OBJ record $record = 0x5d; // record identifier $objData = ''; // ftCmo if ($spTypes[$i] == 0xc9) { // Add ftCmo (common object data) subobject $objData .= pack('vvvvvVVV', 0x15, 0x12, 0x14, $i, 0x2101, 0, 0, 0); // Add ftSbs Scroll bar subobject $objData .= pack('vv', 0xc, 0x14); $objData .= pack('H*', '0000000000000000640001000A00000010000100'); // Add ftLbsData (List box data) subobject $objData .= pack('vv', 0x13, 0x1fee); $objData .= pack('H*', '00000000010001030000020008005700'); } else { // Add ftCmo (common object data) subobject $objData .= pack('vvvvvVVV', 0x15, 0x12, 0x8, $i, 0x6011, 0, 0, 0); } // ftEnd $objData .= pack('vv', 0x0, 0x0); $length = strlen($objData); $header = pack('vv', $record, $length); $this->_append($header . $objData); } } }
/** * Write MSODRAWING record */ private function _writeMsoDrawing() { // write the Escher stream if necessary if (isset($this->_escher)) { $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); $data = $writer->close(); $spOffsets = $writer->getSpOffsets(); $spTypes = $writer->getSpTypes(); // write the neccesary MSODRAWING, OBJ records // split the Escher stream $spOffsets[0] = 0; $nm = count($spOffsets) - 1; // number of shapes excluding first shape for ($i = 1; $i <= $nm; ++ $i) { // MSODRAWING record $record = 0x00EC; // Record identifier // chunk of Escher stream for one shape $dataChunk = substr($data, $spOffsets[$i - 1], $spOffsets[$i] - $spOffsets[$i - 1]); $length = strlen($dataChunk); $header = pack("vv", $record, $length); $this->_append($header . $dataChunk); // OBJ record $record = 0x005D; // record identifier $objData = ''; // ftCmo if ($spTypes[$i] == 0x00C9) { // Add ftCmo (common object data) subobject $objData .= pack('vvvvvVVV', 0x0015, // 0x0015 = ftCmo 0x0012, // length of ftCmo data 0x0014, // object type, 0x0014 = filter $i, // object id number, Excel seems to use 1-based index, local for the sheet 0x2101, // option flags, 0x2001 is what OpenOffice.org uses 0, // reserved 0, // reserved 0) // reserved ; // Add ftSbs Scroll bar subobject $objData .= pack('vv', 0x00C, 0x0014); $objData .= pack('H*', '0000000000000000640001000A00000010000100'); // Add ftLbsData (List box data) subobject $objData .= pack('vv', 0x0013, 0x1FEE); $objData .= pack('H*', '00000000010001030000020008005700'); } else { // Add ftCmo (common object data) subobject $objData .= pack('vvvvvVVV', 0x0015, // 0x0015 = ftCmo 0x0012, // length of ftCmo data 0x0008, // object type, 0x0008 = picture $i, // object id number, Excel seems to use 1-based index, local for the sheet 0x6011, // option flags, 0x6011 is what OpenOffice.org uses 0, // reserved 0, // reserved 0) // reserved ; } // ftEnd $objData .= pack('vv', 0x0000, // 0x0000 = ftEnd 0x0000) // length of ftEnd data ; $length = strlen($objData); $header = pack('vv', $record, $length); $this->_append($header . $objData); } } }