Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; 4 5 use PhpOffice\PhpSpreadsheet\Cell\Coordinate; 6 use PhpOffice\PhpSpreadsheet\Reader\IReadFilter; 7 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; 8 use SimpleXMLElement; 9 10 class ColumnAndRowAttributes extends BaseParserClass 11 { 12 private $worksheet; 13 14 private $worksheetXml; 15 16 public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null) 17 { 18 $this->worksheet = $workSheet; 19 $this->worksheetXml = $worksheetXml; 20 } 21 22 /** 23 * Set Worksheet column attributes by attributes array passed. 24 * 25 * @param string $columnAddress A, B, ... DX, ... 26 * @param array $columnAttributes array of attributes (indexes are attribute name, values are value) 27 * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ? 28 */ 29 private function setColumnAttributes($columnAddress, array $columnAttributes): void 30 { 31 if (isset($columnAttributes['xfIndex'])) { 32 $this->worksheet->getColumnDimension($columnAddress)->setXfIndex($columnAttributes['xfIndex']); 33 } 34 if (isset($columnAttributes['visible'])) { 35 $this->worksheet->getColumnDimension($columnAddress)->setVisible($columnAttributes['visible']); 36 } 37 if (isset($columnAttributes['collapsed'])) { 38 $this->worksheet->getColumnDimension($columnAddress)->setCollapsed($columnAttributes['collapsed']); 39 } 40 if (isset($columnAttributes['outlineLevel'])) { 41 $this->worksheet->getColumnDimension($columnAddress)->setOutlineLevel($columnAttributes['outlineLevel']); 42 } 43 if (isset($columnAttributes['width'])) { 44 $this->worksheet->getColumnDimension($columnAddress)->setWidth($columnAttributes['width']); 45 } 46 } 47 48 /** 49 * Set Worksheet row attributes by attributes array passed. 50 * 51 * @param int $rowNumber 1, 2, 3, ... 99, ... 52 * @param array $rowAttributes array of attributes (indexes are attribute name, values are value) 53 * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ? 54 */ 55 private function setRowAttributes($rowNumber, array $rowAttributes): void 56 { 57 if (isset($rowAttributes['xfIndex'])) { 58 $this->worksheet->getRowDimension($rowNumber)->setXfIndex($rowAttributes['xfIndex']); 59 } 60 if (isset($rowAttributes['visible'])) { 61 $this->worksheet->getRowDimension($rowNumber)->setVisible($rowAttributes['visible']); 62 } 63 if (isset($rowAttributes['collapsed'])) { 64 $this->worksheet->getRowDimension($rowNumber)->setCollapsed($rowAttributes['collapsed']); 65 } 66 if (isset($rowAttributes['outlineLevel'])) { 67 $this->worksheet->getRowDimension($rowNumber)->setOutlineLevel($rowAttributes['outlineLevel']); 68 } 69 if (isset($rowAttributes['rowHeight'])) { 70 $this->worksheet->getRowDimension($rowNumber)->setRowHeight($rowAttributes['rowHeight']); 71 } 72 } 73 74 /** 75 * @param IReadFilter $readFilter 76 * @param bool $readDataOnly 77 */ 78 public function load(?IReadFilter $readFilter = null, $readDataOnly = false): void 79 { 80 if ($this->worksheetXml === null) { 81 return; 82 } 83 84 $columnsAttributes = []; 85 $rowsAttributes = []; 86 if (isset($this->worksheetXml->cols)) { 87 $columnsAttributes = $this->readColumnAttributes($this->worksheetXml->cols, $readDataOnly); 88 } 89 90 if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) { 91 $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly); 92 } 93 94 // set columns/rows attributes 95 $columnsAttributesAreSet = []; 96 foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) { 97 if ( 98 $readFilter === null || 99 !$this->isFilteredColumn($readFilter, $columnCoordinate, $rowsAttributes) 100 ) { 101 if (!isset($columnsAttributesAreSet[$columnCoordinate])) { 102 $this->setColumnAttributes($columnCoordinate, $columnAttributes); 103 $columnsAttributesAreSet[$columnCoordinate] = true; 104 } 105 } 106 } 107 108 $rowsAttributesAreSet = []; 109 foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) { 110 if ( 111 $readFilter === null || 112 !$this->isFilteredRow($readFilter, $rowCoordinate, $columnsAttributes) 113 ) { 114 if (!isset($rowsAttributesAreSet[$rowCoordinate])) { 115 $this->setRowAttributes($rowCoordinate, $rowAttributes); 116 $rowsAttributesAreSet[$rowCoordinate] = true; 117 } 118 } 119 } 120 } 121 122 private function isFilteredColumn(IReadFilter $readFilter, $columnCoordinate, array $rowsAttributes) 123 { 124 foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) { 125 if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { 126 return true; 127 } 128 } 129 130 return false; 131 } 132 133 private function readColumnAttributes(SimpleXMLElement $worksheetCols, $readDataOnly) 134 { 135 $columnAttributes = []; 136 137 foreach ($worksheetCols->col as $column) { 138 $startColumn = Coordinate::stringFromColumnIndex((int) $column['min']); 139 $endColumn = Coordinate::stringFromColumnIndex((int) $column['max']); 140 ++$endColumn; 141 for ($columnAddress = $startColumn; $columnAddress !== $endColumn; ++$columnAddress) { 142 $columnAttributes[$columnAddress] = $this->readColumnRangeAttributes($column, $readDataOnly); 143 144 if ((int) ($column['max']) == 16384) { 145 break; 146 } 147 } 148 } 149 150 return $columnAttributes; 151 } 152 153 private function readColumnRangeAttributes(SimpleXMLElement $column, $readDataOnly) 154 { 155 $columnAttributes = []; 156 157 if ($column['style'] && !$readDataOnly) { 158 $columnAttributes['xfIndex'] = (int) $column['style']; 159 } 160 if (self::boolean($column['hidden'])) { 161 $columnAttributes['visible'] = false; 162 } 163 if (self::boolean($column['collapsed'])) { 164 $columnAttributes['collapsed'] = true; 165 } 166 if (((int) $column['outlineLevel']) > 0) { 167 $columnAttributes['outlineLevel'] = (int) $column['outlineLevel']; 168 } 169 $columnAttributes['width'] = (float) $column['width']; 170 171 return $columnAttributes; 172 } 173 174 private function isFilteredRow(IReadFilter $readFilter, $rowCoordinate, array $columnsAttributes) 175 { 176 foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) { 177 if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { 178 return true; 179 } 180 } 181 182 return false; 183 } 184 185 private function readRowAttributes(SimpleXMLElement $worksheetRow, $readDataOnly) 186 { 187 $rowAttributes = []; 188 189 foreach ($worksheetRow as $row) { 190 if ($row['ht'] && !$readDataOnly) { 191 $rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht']; 192 } 193 if (self::boolean($row['hidden'])) { 194 $rowAttributes[(int) $row['r']]['visible'] = false; 195 } 196 if (self::boolean($row['collapsed'])) { 197 $rowAttributes[(int) $row['r']]['collapsed'] = true; 198 } 199 if ((int) $row['outlineLevel'] > 0) { 200 $rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel']; 201 } 202 if ($row['s'] && !$readDataOnly) { 203 $rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s']; 204 } 205 } 206 207 return $rowAttributes; 208 } 209 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body