Vendor/phpspreadsheet/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php
private function readTextObject()
    {
        $length = self::getUInt2d($this->data, $this->pos + 2);
        $recordData = $this->readRecordData($this->data, $this->pos + 4, $length);

        // move stream pointer to next record
        $this->pos += 4 + $length;

        if ($this->readDataOnly) {
            return;
        }

        // recordData consists of an array of subrecords looking like this:
        //    grbit: 2 bytes; Option Flags
        //    rot: 2 bytes; rotation
        //    cchText: 2 bytes; length of the text (in the first continue record)
        //    cbRuns: 2 bytes; length of the formatting (in the second continue record)
        // followed by the continuation records containing the actual text and formatting
        $grbitOpts = self::getUInt2d($recordData, 0);
        $rot = self::getUInt2d($recordData, 2);
        $cchText = self::getUInt2d($recordData, 10);
        $cbRuns = self::getUInt2d($recordData, 12);
        $text = $this->getSplicedRecordData();

        $textByte = $text['spliceOffsets'][1] - $text['spliceOffsets'][0] - 1;
        $textStr = substr($text['recordData'], $text['spliceOffsets'][0] + 1, $textByte);
        // get 1 byte
        $is16Bit = ord($text['recordData'][0]);
        // it is possible to use a compressed format,
        // which omits the high bytes of all characters, if they are all zero
        if (($is16Bit & 0x01) === 0) {
            $textStr = StringHelper::ConvertEncoding($textStr, 'UTF-8', 'ISO-8859-1');
        } else {
            $textStr = $this->decodeCodepage($textStr);
        }

        $this->textObjects[$this->textObjRef] = [
            'text' => $textStr,
            'format' => substr($text['recordData'], $text['spliceOffsets'][1], $cbRuns),
            'alignment' => $grbitOpts,
            'rotation' => $rot,
        ];
    }
private function readTextObject()
    {
        $length = self::getUInt2d($this->data, $this->pos + 2);
        $recordData = $this->readRecordData($this->data, $this->pos + 4, $length);

        // move stream pointer to next record
        $this->pos += 4 + $length;

        if ($this->readDataOnly) {
            return;
        }

        // recordData consists of an array of subrecords looking like this:
        //    grbit: 2 bytes; Option Flags
        //    rot: 2 bytes; rotation
        //    cchText: 2 bytes; length of the text (in the first continue record)
        //    cbRuns: 2 bytes; length of the formatting (in the second continue record)
        // followed by the continuation records containing the actual text and formatting
        $grbitOpts = self::getUInt2d($recordData, 0);
        $rot = self::getUInt2d($recordData, 2);
        $cchText = self::getUInt2d($recordData, 10);
        $cbRuns = self::getUInt2d($recordData, 12);
        $text = $this->getSplicedRecordData();

        $textByte = $text['spliceOffsets'][1] - $text['spliceOffsets'][0] - 1;
        $textStr = substr($text['recordData'], $text['spliceOffsets'][0] + 1, $textByte);
        // get 1 byte
        $is16Bit = ord($text['recordData'][0]);
        // it is possible to use a compressed format,
        // which omits the high bytes of all characters, if they are all zero
        if (($is16Bit & 0x01) === 0) {
            $textStr = StringHelper::ConvertEncoding($textStr, 'UTF-8', 'ISO-8859-1');
        } else {
            $textStr = $this->decodeCodepage($textStr);
        }

        $this->textObjects[$this->textObjRef] = [
            'text' => $textStr,
            'format' => substr($text['recordData'], $text['spliceOffsets'][1], $cbRuns),
            'alignment' => $grbitOpts,
            'rotation' => $rot,
        ];
    }
The TEXT Object record contains the text associated with a cell annotation.