Vendor/phpspreadsheet/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php
private function writeMsoDrawing()
    {
        // write the Escher stream if necessary
        if (isset($this->escher)) {
            $writer = new 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);
            }
        }
    }
private function writeMsoDrawing()
    {
        // write the Escher stream if necessary
        if (isset($this->escher)) {
            $writer = new 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);
            }
        }
    }
Write MSODRAWING record.