From c04b92198e1c5a0b649bae0903f77d0c7b334e37 Mon Sep 17 00:00:00 2001 From: Julian Kern Date: Thu, 26 Jul 2018 00:11:32 +0200 Subject: [PATCH] Column dimensions are read by Reader\Xlsx Fixes #596 Fixes #616 --- src/PhpSpreadsheet/Reader/Xlsx.php | 156 ++++++++++-------- .../Functional/ColumnWidthTest.php | 43 +++++ 2 files changed, 132 insertions(+), 67 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index e36a5a57..c6e8512d 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -889,73 +889,7 @@ class Xlsx extends BaseReader } } - $columnsAttributes = []; - $rowsAttributes = []; - if (isset($xmlSheet->cols) && !$this->readDataOnly) { - foreach ($xmlSheet->cols->col as $col) { - for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) { - if ($col['style'] && !$this->readDataOnly) { - $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['xfIndex'] = (int) $col['style']; - } - if (self::boolean($col['hidden'])) { - $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['visible'] = false; - } - if (self::boolean($col['collapsed'])) { - $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['collapsed'] = true; - } - if ($col['outlineLevel'] > 0) { - $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['outlineLevel'] = (int) $col['outlineLevel']; - } - $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['width'] = (float) $col['width']; - - if ((int) ($col['max']) == 16384) { - break; - } - } - } - } - - if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { - foreach ($xmlSheet->sheetData->row as $row) { - if ($row['ht'] && !$this->readDataOnly) { - $rowsAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht']; - } - if (self::boolean($row['hidden']) && !$this->readDataOnly) { - $rowsAttributes[(int) $row['r']]['visible'] = false; - } - if (self::boolean($row['collapsed'])) { - $rowsAttributes[(int) $row['r']]['collapsed'] = true; - } - if ($row['outlineLevel'] > 0) { - $rowsAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel']; - } - if ($row['s'] && !$this->readDataOnly) { - $rowsAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s']; - } - } - } - - // set columns/rows attributes - $columnsAttributesSet = []; - $rowsAttributesSet = []; - foreach ($columnsAttributes as $coordColumn => $columnAttributes) { - foreach ($rowsAttributes as $coordRow => $rowAttributes) { - if ($this->getReadFilter() !== null) { - if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { - continue; - } - } - - if (!isset($columnsAttributesSet[$coordColumn])) { - $this->setColumnAttributes($docSheet, $coordColumn, $columnAttributes); - $columnsAttributesSet[$coordColumn] = true; - } - if (!isset($rowsAttributesSet[$coordRow])) { - $this->setRowAttributes($docSheet, $coordRow, $rowAttributes); - $rowsAttributesSet[$coordRow] = true; - } - } - } + $this->readColumnsAndRowsAttributes($xmlSheet, $docSheet); if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { $cIndex = 1; // Cell Start from 1 @@ -2575,4 +2509,92 @@ class Xlsx extends BaseReader return (bool) $xsdBoolean; } + + /** + * Read columns and rows attributes from XML and set them on the worksheet. + * + * @param SimpleXMLElement $xmlSheet + * @param Worksheet $docSheet + */ + private function readColumnsAndRowsAttributes(SimpleXMLElement $xmlSheet, Worksheet $docSheet) + { + $columnsAttributes = []; + $rowsAttributes = []; + if (isset($xmlSheet->cols) && !$this->readDataOnly) { + foreach ($xmlSheet->cols->col as $col) { + for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) { + if ($col['style'] && !$this->readDataOnly) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['xfIndex'] = (int) $col['style']; + } + if (self::boolean($col['hidden'])) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['visible'] = false; + } + if (self::boolean($col['collapsed'])) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['collapsed'] = true; + } + if ($col['outlineLevel'] > 0) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['outlineLevel'] = (int) $col['outlineLevel']; + } + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['width'] = (float) $col['width']; + + if ((int) ($col['max']) == 16384) { + break; + } + } + } + } + + if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { + foreach ($xmlSheet->sheetData->row as $row) { + if ($row['ht'] && !$this->readDataOnly) { + $rowsAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht']; + } + if (self::boolean($row['hidden']) && !$this->readDataOnly) { + $rowsAttributes[(int) $row['r']]['visible'] = false; + } + if (self::boolean($row['collapsed'])) { + $rowsAttributes[(int) $row['r']]['collapsed'] = true; + } + if ($row['outlineLevel'] > 0) { + $rowsAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel']; + } + if ($row['s'] && !$this->readDataOnly) { + $rowsAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s']; + } + } + } + + // set columns/rows attributes + $columnsAttributesSet = []; + $rowsAttributesSet = []; + foreach ($columnsAttributes as $coordColumn => $columnAttributes) { + foreach ($rowsAttributes as $coordRow => $rowAttributes) { + if ($this->getReadFilter() !== null) { + if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { + continue 2; + } + } + } + + if (!isset($columnsAttributesSet[$coordColumn])) { + $this->setColumnAttributes($docSheet, $coordColumn, $columnAttributes); + $columnsAttributesSet[$coordColumn] = true; + } + } + + foreach ($rowsAttributes as $coordRow => $rowAttributes) { + foreach ($columnsAttributes as $coordColumn => $columnAttributes) { + if ($this->getReadFilter() !== null) { + if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { + continue 2; + } + } + } + + if (!isset($rowsAttributesSet[$coordRow])) { + $this->setRowAttributes($docSheet, $coordRow, $rowAttributes); + $rowsAttributesSet[$coordRow] = true; + } + } + } } diff --git a/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php b/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php new file mode 100644 index 00000000..6d4fc2ca --- /dev/null +++ b/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php @@ -0,0 +1,43 @@ +getActiveSheet(); + $sheet->setCellValue('A1', 'Hello World !'); + $sheet->getColumnDimension('A')->setWidth(20); + $this->assertColumn($spreadsheet); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + $this->assertColumn($reloadedSpreadsheet); + } + + private function assertColumn(Spreadsheet $spreadsheet) + { + $sheet = $spreadsheet->getActiveSheet(); + $columnDimensions = $sheet->getColumnDimensions(); + + self::assertArrayHasKey('A', $columnDimensions); + $column = array_shift($columnDimensions); + self::assertEquals(20, $column->getWidth()); + } +}