Completed
Push — master ( c2a964...f9b1b7 )
by
unknown
36s queued 26s
created

ListFunctions::listWorksheetNames2()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 20
c 0
b 0
f 0
dl 0
loc 40
ccs 20
cts 20
cp 1
rs 9.2888
cc 5
nc 9
nop 2
crap 5
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Xls;
4
5
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6
use PhpOffice\PhpSpreadsheet\Reader\Xls;
7
use PhpOffice\PhpSpreadsheet\Shared\File;
8
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
9
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
10
11
class ListFunctions extends Xls
12
{
13
    /**
14
     * Reads names of the worksheets from a file, without parsing the whole file to a PhpSpreadsheet object.
15
     *
16
     * @return string[]
17
     */
18 6
    protected function listWorksheetNames2(string $filename, Xls $xls): array
19
    {
20 6
        File::assertFile($filename);
21
22 6
        $worksheetNames = [];
23
24
        // Read the OLE file
25 6
        $xls->loadOLE($filename);
26
27
        // total byte size of Excel data (workbook global substream + sheet substreams)
28 6
        $xls->dataSize = strlen($xls->data);
29
30 6
        $xls->pos = 0;
31 6
        $xls->sheets = [];
32
33
        // Parse Workbook Global Substream
34 6
        while ($xls->pos < $xls->dataSize) {
35 6
            $code = self::getUInt2d($xls->data, $xls->pos);
36
37
            match ($code) {
38 6
                self::XLS_TYPE_BOF => $xls->readBof(),
39 6
                self::XLS_TYPE_SHEET => $xls->readSheet(),
40 6
                self::XLS_TYPE_EOF => $xls->readDefault(),
41 6
                self::XLS_TYPE_CODEPAGE => $xls->readCodepage(),
42 6
                default => $xls->readDefault(),
43
            };
44
45 6
            if ($code === self::XLS_TYPE_EOF) {
46 6
                break;
47
            }
48
        }
49
50 6
        foreach ($xls->sheets as $sheet) {
51 6
            if ($sheet['sheetType'] === 0x00) {
52
                // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module
53 6
                $worksheetNames[] = $sheet['name'];
54
            }
55
        }
56
57 6
        return $worksheetNames;
58
    }
59
60
    /**
61
     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns).
62
     *
63
     * @return array<int, array{worksheetName: string, lastColumnLetter: string, lastColumnIndex: int, totalRows: int, totalColumns: int, sheetState: string}>
64
     */
65 5
    protected function listWorksheetInfo2(string $filename, Xls $xls): array
66
    {
67 5
        File::assertFile($filename);
68
69 5
        $worksheetInfo = [];
70
71
        // Read the OLE file
72 5
        $xls->loadOLE($filename);
73
74
        // total byte size of Excel data (workbook global substream + sheet substreams)
75 5
        $xls->dataSize = strlen($xls->data);
76
77
        // initialize
78 5
        $xls->pos = 0;
79 5
        $xls->sheets = [];
80
81
        // Parse Workbook Global Substream
82 5
        while ($xls->pos < $xls->dataSize) {
83 5
            $code = self::getUInt2d($xls->data, $xls->pos);
84
85
            match ($code) {
86 5
                self::XLS_TYPE_BOF => $xls->readBof(),
87 5
                self::XLS_TYPE_SHEET => $xls->readSheet(),
88 5
                self::XLS_TYPE_EOF => $xls->readDefault(),
89 5
                self::XLS_TYPE_CODEPAGE => $xls->readCodepage(),
90 5
                default => $xls->readDefault(),
91
            };
92
93 5
            if ($code === self::XLS_TYPE_EOF) {
94 5
                break;
95
            }
96
        }
97
98
        // Parse the individual sheets
99 5
        foreach ($xls->sheets as $sheet) {
100 5
            if ($sheet['sheetType'] !== 0x00) {
101
                // 0x00: Worksheet
102
                // 0x02: Chart
103
                // 0x06: Visual Basic module
104
                continue;
105
            }
106
107 5
            $tmpInfo = [];
108 5
            $tmpInfo['worksheetName'] = StringHelper::convertToString($sheet['name']);
109 5
            $tmpInfo['lastColumnLetter'] = 'A';
110 5
            $tmpInfo['lastColumnIndex'] = 0;
111 5
            $tmpInfo['totalRows'] = 0;
112 5
            $tmpInfo['totalColumns'] = 0;
113 5
            $tmpInfo['sheetState'] = StringHelper::convertToString($sheet['sheetState']);
114
115 5
            $xls->pos = $sheet['offset'];
116
117 5
            while ($xls->pos <= $xls->dataSize - 4) {
118 5
                $code = self::getUInt2d($xls->data, $xls->pos);
119
120
                switch ($code) {
121 5
                    case self::XLS_TYPE_RK:
122 5
                    case self::XLS_TYPE_LABELSST:
123 5
                    case self::XLS_TYPE_NUMBER:
124 5
                    case self::XLS_TYPE_FORMULA:
125 5
                    case self::XLS_TYPE_BOOLERR:
126 5
                    case self::XLS_TYPE_LABEL:
127 5
                        $length = self::getUInt2d($xls->data, $xls->pos + 2);
128 5
                        $recordData = $xls->readRecordData($xls->data, $xls->pos + 4, $length);
129
130
                        // move stream pointer to next record
131 5
                        $xls->pos += 4 + $length;
132
133 5
                        $rowIndex = self::getUInt2d($recordData, 0) + 1;
134 5
                        $columnIndex = self::getUInt2d($recordData, 2);
135
136 5
                        $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
137 5
                        $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
138
139 5
                        break;
140 5
                    case self::XLS_TYPE_BOF:
141 5
                        $xls->readBof();
142
143 5
                        break;
144 5
                    case self::XLS_TYPE_EOF:
145 5
                        $xls->readDefault();
146
147 5
                        break 2;
148
                    default:
149 5
                        $xls->readDefault();
150
151 5
                        break;
152
                }
153
            }
154
155 5
            $tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
156 5
            $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
157
158 5
            $worksheetInfo[] = $tmpInfo;
159
        }
160
161 5
        return $worksheetInfo;
162
    }
163
}
164