Column dimensions are read by Reader\Xlsx

Fixes #596
Fixes #616
This commit is contained in:
Julian Kern 2018-07-26 00:11:32 +02:00 committed by Adrien Crivelli
parent 98c55b0f88
commit c04b92198e
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
2 changed files with 132 additions and 67 deletions

View File

@ -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;
}
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Functional;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class ColumnWidthTest extends AbstractFunctional
{
public function providerFormats()
{
return [
['Xlsx'],
];
}
/**
* @dataProvider providerFormats
*
* @param $format
*/
public function testReadColumnWidth($format)
{
// create new sheet with column width
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->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());
}
}