Vendor/phpspreadsheet/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php
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', 0x00, 0x00, 0x00, 0x00);
        // 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', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);
        // offset: 44; size: 4; offset of the start
        $data .= pack('V', 0x30);

        // SECTION
        $dataSection = [];
        $dataSection_NumProps = 0;
        $dataSection_Summary = '';
        $dataSection_Content = '';

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

        // GKPIDDSI_CATEGORY : Category
        if ($this->spreadsheet->getProperties()->getCategory()) {
            $dataProp = $this->spreadsheet->getProperties()->getCategory();
            $dataSection[] = [
                'summary' => ['pack' => 'V', 'data' => 0x02],
                'offset' => ['pack' => 'V'],
                'type' => ['pack' => 'V', 'data' => 0x1E],
                'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
            ];
            ++$dataSection_NumProps;
        }
        // GKPIDDSI_VERSION :Version of the application that wrote the property storage
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x17],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x03],
            'data' => ['pack' => 'V', 'data' => 0x000C0000],
        ];
        ++$dataSection_NumProps;
        // GKPIDDSI_SCALE : FALSE
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x0B],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['data' => false],
        ];
        ++$dataSection_NumProps;
        // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x10],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['data' => false],
        ];
        ++$dataSection_NumProps;
        // GKPIDDSI_SHAREDOC : FALSE
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x13],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['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[] = [
            'summary' => ['pack' => 'V', 'data' => 0x16],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['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[] = [
            'summary' => ['pack' => 'V', 'data' => 0x0D],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x101E],
            'data' => ['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[] = [
            'summary' => ['pack' => 'V', 'data' => 0x0C],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x100C],
            'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
        ];
        ++$dataSection_NumProps;

        //         4     Section Length
        //        4     Property count
        //        8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))
        $dataSection_Content_Offset = 8 + $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 + 4;
            } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
                $dataSection_Content .= pack('V', $dataProp['data']['data']);

                $dataSection_Content_Offset += 4 + 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 + 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'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (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 += 4 + 4 + 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 += 4 + 8;
            } else {
                // Data Type Not Used at the moment
                $dataSection_Content .= $dataProp['data']['data'];

                $dataSection_Content_Offset += 4 + $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;
    }
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', 0x00, 0x00, 0x00, 0x00);
        // 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', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);
        // offset: 44; size: 4; offset of the start
        $data .= pack('V', 0x30);

        // SECTION
        $dataSection = [];
        $dataSection_NumProps = 0;
        $dataSection_Summary = '';
        $dataSection_Content = '';

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

        // GKPIDDSI_CATEGORY : Category
        if ($this->spreadsheet->getProperties()->getCategory()) {
            $dataProp = $this->spreadsheet->getProperties()->getCategory();
            $dataSection[] = [
                'summary' => ['pack' => 'V', 'data' => 0x02],
                'offset' => ['pack' => 'V'],
                'type' => ['pack' => 'V', 'data' => 0x1E],
                'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
            ];
            ++$dataSection_NumProps;
        }
        // GKPIDDSI_VERSION :Version of the application that wrote the property storage
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x17],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x03],
            'data' => ['pack' => 'V', 'data' => 0x000C0000],
        ];
        ++$dataSection_NumProps;
        // GKPIDDSI_SCALE : FALSE
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x0B],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['data' => false],
        ];
        ++$dataSection_NumProps;
        // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x10],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['data' => false],
        ];
        ++$dataSection_NumProps;
        // GKPIDDSI_SHAREDOC : FALSE
        $dataSection[] = [
            'summary' => ['pack' => 'V', 'data' => 0x13],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['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[] = [
            'summary' => ['pack' => 'V', 'data' => 0x16],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x0B],
            'data' => ['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[] = [
            'summary' => ['pack' => 'V', 'data' => 0x0D],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x101E],
            'data' => ['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[] = [
            'summary' => ['pack' => 'V', 'data' => 0x0C],
            'offset' => ['pack' => 'V'],
            'type' => ['pack' => 'V', 'data' => 0x100C],
            'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
        ];
        ++$dataSection_NumProps;

        //         4     Section Length
        //        4     Property count
        //        8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))
        $dataSection_Content_Offset = 8 + $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 + 4;
            } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
                $dataSection_Content .= pack('V', $dataProp['data']['data']);

                $dataSection_Content_Offset += 4 + 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 + 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'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (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 += 4 + 4 + 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 += 4 + 8;
            } else {
                // Data Type Not Used at the moment
                $dataSection_Content .= $dataProp['data']['data'];

                $dataSection_Content_Offset += 4 + $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 DocumentSummary Information.

@return string