PluginProbe
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin / 6.5.1.7
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin v6.5.1.7
6.5.1.7 6.5.1.6 6.5.1.5 6.5.1.4 6.5.1.3 6.5.1.2 6.5.1.1 6.5.0.9 6.5.0.8 6.5.0.7 6.5.0.6 trunk 3.4.2.40 3.4.2.41 3.4.2.42 3.4.2.43 3.4.2.44 3.4.2.45 3.4.2.46 3.4.2.47 3.4.2.48 3.4.2.49 3.4.2.50 6.3.2 6.3.3.1 All 47 releases
wpdatatables / lib / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Writer / Xlsx / DefinedNames.php

DefinedNames.php in wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin 6.5.1.7, at lib/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php

245 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5 use Exception;
6 use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
7 use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
8 use PhpOffice\PhpSpreadsheet\DefinedName;
9 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
10 use PhpOffice\PhpSpreadsheet\Spreadsheet;
11 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as ActualWorksheet;
12
13 class DefinedNames
14 {
15 /** @var XMLWriter */
16 private $objWriter;
17
18 /** @var Spreadsheet */
19 private $spreadsheet;
20
21 public function __construct(XMLWriter $objWriter, Spreadsheet $spreadsheet)
22 {
23 $this->objWriter = $objWriter;
24 $this->spreadsheet = $spreadsheet;
25 }
26
27 public function write(): void
28 {
29 // Write defined names
30 $this->objWriter->startElement('definedNames');
31
32 // Named ranges
33 if (count($this->spreadsheet->getDefinedNames()) > 0) {
34 // Named ranges
35 $this->writeNamedRangesAndFormulae();
36 }
37
38 // Other defined names
39 $sheetCount = $this->spreadsheet->getSheetCount();
40 for ($i = 0; $i < $sheetCount; ++$i) {
41 // NamedRange for autoFilter
42 $this->writeNamedRangeForAutofilter($this->spreadsheet->getSheet($i), $i);
43
44 // NamedRange for Print_Titles
45 $this->writeNamedRangeForPrintTitles($this->spreadsheet->getSheet($i), $i);
46
47 // NamedRange for Print_Area
48 $this->writeNamedRangeForPrintArea($this->spreadsheet->getSheet($i), $i);
49 }
50
51 $this->objWriter->endElement();
52 }
53
54 /**
55 * Write defined names.
56 */
57 private function writeNamedRangesAndFormulae(): void
58 {
59 // Loop named ranges
60 $definedNames = $this->spreadsheet->getDefinedNames();
61 foreach ($definedNames as $definedName) {
62 $this->writeDefinedName($definedName);
63 }
64 }
65
66 /**
67 * Write Defined Name for named range.
68 */
69 private function writeDefinedName(DefinedName $definedName): void
70 {
71 // definedName for named range
72 $local = -1;
73 if ($definedName->getLocalOnly() && $definedName->getScope() !== null) {
74 try {
75 $local = $definedName->getScope()->getParentOrThrow()->getIndex($definedName->getScope());
76 } catch (Exception $e) {
77 // See issue 2266 - deleting sheet which contains
78 // defined names will cause Exception above.
79 return;
80 }
81 }
82 $this->objWriter->startElement('definedName');
83 $this->objWriter->writeAttribute('name', $definedName->getName());
84 if ($local >= 0) {
85 $this->objWriter->writeAttribute(
86 'localSheetId',
87 "$local"
88 );
89 }
90
91 $definedRange = $this->getDefinedRange($definedName);
92
93 $this->objWriter->writeRawData($definedRange);
94
95 $this->objWriter->endElement();
96 }
97
98 /**
99 * Write Defined Name for autoFilter.
100 */
101 private function writeNamedRangeForAutofilter(ActualWorksheet $worksheet, int $worksheetId = 0): void
102 {
103 // NamedRange for autoFilter
104 $autoFilterRange = $worksheet->getAutoFilter()->getRange();
105 if (!empty($autoFilterRange)) {
106 $this->objWriter->startElement('definedName');
107 $this->objWriter->writeAttribute('name', '_xlnm._FilterDatabase');
108 $this->objWriter->writeAttribute('localSheetId', "$worksheetId");
109 $this->objWriter->writeAttribute('hidden', '1');
110
111 // Create absolute coordinate and write as raw text
112 $range = Coordinate::splitRange($autoFilterRange);
113 $range = $range[0];
114 // Strip any worksheet ref so we can make the cell ref absolute
115 [, $range[0]] = ActualWorksheet::extractSheetTitle($range[0], true);
116
117 $range[0] = Coordinate::absoluteCoordinate($range[0]);
118 if (count($range) > 1) {
119 $range[1] = Coordinate::absoluteCoordinate($range[1]);
120 }
121 $range = implode(':', $range);
122
123 $this->objWriter->writeRawData('\'' . str_replace("'", "''", $worksheet->getTitle()) . '\'!' . $range);
124
125 $this->objWriter->endElement();
126 }
127 }
128
129 /**
130 * Write Defined Name for PrintTitles.
131 */
132 private function writeNamedRangeForPrintTitles(ActualWorksheet $worksheet, int $worksheetId = 0): void
133 {
134 // NamedRange for PrintTitles
135 if ($worksheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $worksheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
136 $this->objWriter->startElement('definedName');
137 $this->objWriter->writeAttribute('name', '_xlnm.Print_Titles');
138 $this->objWriter->writeAttribute('localSheetId', "$worksheetId");
139
140 // Setting string
141 $settingString = '';
142
143 // Columns to repeat
144 if ($worksheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
145 $repeat = $worksheet->getPageSetup()->getColumnsToRepeatAtLeft();
146
147 $settingString .= '\'' . str_replace("'", "''", $worksheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
148 }
149
150 // Rows to repeat
151 if ($worksheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
152 if ($worksheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
153 $settingString .= ',';
154 }
155
156 $repeat = $worksheet->getPageSetup()->getRowsToRepeatAtTop();
157
158 $settingString .= '\'' . str_replace("'", "''", $worksheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
159 }
160
161 $this->objWriter->writeRawData($settingString);
162
163 $this->objWriter->endElement();
164 }
165 }
166
167 /**
168 * Write Defined Name for PrintTitles.
169 */
170 private function writeNamedRangeForPrintArea(ActualWorksheet $worksheet, int $worksheetId = 0): void
171 {
172 // NamedRange for PrintArea
173 if ($worksheet->getPageSetup()->isPrintAreaSet()) {
174 $this->objWriter->startElement('definedName');
175 $this->objWriter->writeAttribute('name', '_xlnm.Print_Area');
176 $this->objWriter->writeAttribute('localSheetId', "$worksheetId");
177
178 // Print area
179 $printArea = Coordinate::splitRange($worksheet->getPageSetup()->getPrintArea());
180
181 $chunks = [];
182 foreach ($printArea as $printAreaRect) {
183 $printAreaRect[0] = Coordinate::absoluteReference($printAreaRect[0]);
184 $printAreaRect[1] = Coordinate::absoluteReference($printAreaRect[1]);
185 $chunks[] = '\'' . str_replace("'", "''", $worksheet->getTitle()) . '\'!' . implode(':', $printAreaRect);
186 }
187
188 $this->objWriter->writeRawData(implode(',', $chunks));
189
190 $this->objWriter->endElement();
191 }
192 }
193
194 private function getDefinedRange(DefinedName $definedName): string
195 {
196 $definedRange = $definedName->getValue();
197 $splitCount = preg_match_all(
198 '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
199 $definedRange,
200 $splitRanges,
201 PREG_OFFSET_CAPTURE
202 );
203
204 $lengths = array_map('strlen', array_column($splitRanges[0], 0));
205 $offsets = array_column($splitRanges[0], 1);
206
207 $worksheets = $splitRanges[2];
208 $columns = $splitRanges[6];
209 $rows = $splitRanges[7];
210
211 while ($splitCount > 0) {
212 --$splitCount;
213 $length = $lengths[$splitCount];
214 $offset = $offsets[$splitCount];
215 $worksheet = $worksheets[$splitCount][0];
216 $column = $columns[$splitCount][0];
217 $row = $rows[$splitCount][0];
218
219 $newRange = '';
220 if (empty($worksheet)) {
221 if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
222 // We should have a worksheet
223 $ws = $definedName->getWorksheet();
224 $worksheet = ($ws === null) ? null : $ws->getTitle();
225 }
226 } else {
227 $worksheet = str_replace("''", "'", trim($worksheet, "'"));
228 }
229
230 if (!empty($worksheet)) {
231 $newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
232 }
233 $newRange = "{$newRange}{$column}{$row}";
234
235 $definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
236 }
237
238 if (substr($definedRange, 0, 1) === '=') {
239 $definedRange = substr($definedRange, 1);
240 }
241
242 return $definedRange;
243 }
244 }
245