Skip to content

Commit

Permalink
Merge pull request #4366 from oleibman/visibility
Browse files Browse the repository at this point in the history
Add sheetState to ListWorksheetInfo Data
  • Loading branch information
oleibman authored Feb 19, 2025
2 parents 2e998d6 + 94117dd commit 82ac7ab
Show file tree
Hide file tree
Showing 24 changed files with 225 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).

### Changed

- ListWorksheetInfo will now return sheetState (visible, hidden, veryHidden). [Issue #4345](https://github.com/PHPOffice/PhpSpreadsheet/issues/4345) [PR #4366](https://github.com/PHPOffice/PhpSpreadsheet/pull/4366)
- Start migration to Phpstan 2. [PR #4359](https://github.com/PHPOffice/PhpSpreadsheet/pull/4359)
- IOFactory identify can return, and createReader and CreateWriter can accept, a class name rather than a file type. [Issue #4357](https://github.com/PHPOffice/PhpSpreadsheet/issues/4357) [PR #4361](https://github.com/PHPOffice/PhpSpreadsheet/pull/4361)

Expand Down
1 change: 1 addition & 0 deletions src/PhpSpreadsheet/Reader/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ public function listWorksheetInfo(string $filename): array

$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex'] + 1);
$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
$worksheetInfo[0]['sheetState'] = Worksheet::SHEETSTATE_VISIBLE;

// Close file
fclose($fileHandle);
Expand Down
12 changes: 10 additions & 2 deletions src/PhpSpreadsheet/Reader/Gnumeric.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class Gnumeric extends BaseReader

const NAMESPACE_OOO = 'http://openoffice.org/2004/office';

const GNM_SHEET_VISIBILITY_VISIBLE = 'GNM_SHEET_VISIBILITY_VISIBLE';
const GNM_SHEET_VISIBILITY_HIDDEN = 'GNM_SHEET_VISIBILITY_HIDDEN';

/**
* Shared Expressions.
*/
Expand Down Expand Up @@ -144,7 +147,12 @@ public function listWorksheetInfo(string $filename): array
'lastColumnIndex' => 0,
'totalRows' => 0,
'totalColumns' => 0,
'sheetState' => Worksheet::SHEETSTATE_VISIBLE,
];
$visibility = $xml->getAttribute('Visibility');
if ((string) $visibility === self::GNM_SHEET_VISIBILITY_HIDDEN) {
$tmpInfo['sheetState'] = Worksheet::SHEETSTATE_HIDDEN;
}

while ($xml->read()) {
if (self::matchXml($xml, 'Name')) {
Expand Down Expand Up @@ -271,8 +279,8 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp
// name in line with the formula, not the reverse
$this->spreadsheet->getActiveSheet()->setTitle($worksheetName, false, false);

$visibility = $sheet->attributes()['Visibility'] ?? 'GNM_SHEET_VISIBILITY_VISIBLE';
if ((string) $visibility !== 'GNM_SHEET_VISIBILITY_VISIBLE') {
$visibility = $sheet->attributes()['Visibility'] ?? self::GNM_SHEET_VISIBILITY_VISIBLE;
if ((string) $visibility !== self::GNM_SHEET_VISIBILITY_VISIBLE) {
$this->spreadsheet->getActiveSheet()->setSheetState(Worksheet::SHEETSTATE_HIDDEN);
}

Expand Down
1 change: 1 addition & 0 deletions src/PhpSpreadsheet/Reader/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,7 @@ public function listWorksheetInfo(string $filename): array
$newEntry['lastColumnIndex'] = Coordinate::columnIndexFromString($sheet->getHighestDataColumn()) - 1;
$newEntry['totalRows'] = $sheet->getHighestDataRow();
$newEntry['totalColumns'] = $newEntry['lastColumnIndex'] + 1;
$newEntry['sheetState'] = Worksheet::SHEETSTATE_VISIBLE;
$info[] = $newEntry;
}
$spreadsheet->disconnectWorksheets();
Expand Down
109 changes: 56 additions & 53 deletions src/PhpSpreadsheet/Reader/Ods.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,64 +157,67 @@ public function listWorksheetInfo(string $filename): array

// Step into the first level of content of the XML
$xml->read();
$tableVisibility = [];
$lastTableStyle = '';

while ($xml->read()) {
// Quickly jump through to the office:body node
while (self::getXmlName($xml) !== 'office:body') {
if ($xml->isEmptyElement) {
$xml->read();
} else {
$xml->next();
if (self::getXmlName($xml) === 'style:style') {
$styleType = $xml->getAttribute('style:family');
if ($styleType === 'table') {
$lastTableStyle = $xml->getAttribute('style:name');
}
}
// Now read each node until we find our first table:table node
while ($xml->read()) {
if (self::getXmlName($xml) == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
$worksheetNames[] = $xml->getAttribute('table:name');

$tmpInfo = [
'worksheetName' => $xml->getAttribute('table:name'),
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 0,
'totalColumns' => 0,
];

// Loop through each child node of the table:table element reading
$currCells = 0;
do {
} elseif (self::getXmlName($xml) === 'style:table-properties') {
$visibility = $xml->getAttribute('table:display');
$tableVisibility[$lastTableStyle] = ($visibility === 'false') ? Worksheet::SHEETSTATE_HIDDEN : Worksheet::SHEETSTATE_VISIBLE;
} elseif (self::getXmlName($xml) == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
$worksheetNames[] = $xml->getAttribute('table:name');

$styleName = $xml->getAttribute('table:style-name') ?? '';
$visibility = $tableVisibility[$styleName] ?? '';
$tmpInfo = [
'worksheetName' => $xml->getAttribute('table:name'),
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 0,
'totalColumns' => 0,
'sheetState' => $visibility,
];

// Loop through each child node of the table:table element reading
$currCells = 0;
do {
$xml->read();
if (self::getXmlName($xml) == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
$rowspan = $xml->getAttribute('table:number-rows-repeated');
$rowspan = empty($rowspan) ? 1 : $rowspan;
$tmpInfo['totalRows'] += $rowspan;
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
$currCells = 0;
// Step into the row
$xml->read();
if (self::getXmlName($xml) == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
$rowspan = $xml->getAttribute('table:number-rows-repeated');
$rowspan = empty($rowspan) ? 1 : $rowspan;
$tmpInfo['totalRows'] += $rowspan;
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
$currCells = 0;
// Step into the row
$xml->read();
do {
$doread = true;
if (self::getXmlName($xml) == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
if (!$xml->isEmptyElement) {
++$currCells;
$xml->next();
$doread = false;
}
} elseif (self::getXmlName($xml) == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
$currCells += (int) $mergeSize;
do {
$doread = true;
if (self::getXmlName($xml) == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
if (!$xml->isEmptyElement) {
++$currCells;
$xml->next();
$doread = false;
}
if ($doread) {
$xml->read();
}
} while (self::getXmlName($xml) != 'table:table-row');
}
} while (self::getXmlName($xml) != 'table:table');
} elseif (self::getXmlName($xml) == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
$currCells += (int) $mergeSize;
}
if ($doread) {
$xml->read();
}
} while (self::getXmlName($xml) != 'table:table-row');
}
} while (self::getXmlName($xml) != 'table:table');

$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$worksheetInfo[] = $tmpInfo;
}
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$worksheetInfo[] = $tmpInfo;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/PhpSpreadsheet/Reader/Slk.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public function listWorksheetInfo(string $filename): array
$worksheetInfo[0]['totalRows'] = $rowIndex;
$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex'] + 1);
$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
$worksheetInfo[0]['sheetState'] = Worksheet::SHEETSTATE_VISIBLE;

// Close file
fclose($fileHandle);
Expand Down
2 changes: 2 additions & 0 deletions src/PhpSpreadsheet/Reader/Xls/ListFunctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class ListFunctions extends Xls
{
Expand Down Expand Up @@ -104,6 +105,7 @@ protected function listWorksheetInfo2(string $filename, Xls $xls): array
$tmpInfo['lastColumnIndex'] = 0;
$tmpInfo['totalRows'] = 0;
$tmpInfo['totalColumns'] = 0;
$tmpInfo['sheetState'] = $sheet['sheetState'];

$xls->pos = $sheet['offset'];

Expand Down
4 changes: 3 additions & 1 deletion src/PhpSpreadsheet/Reader/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ public function listWorksheetInfo(string $filename): array
'totalRows' => 0,
'totalColumns' => 0,
];
$sheetState = (string) (self::getAttributes($eleSheet)['state'] ?? Worksheet::SHEETSTATE_VISIBLE);
$tmpInfo['sheetState'] = $sheetState;

$fileWorksheet = (string) $worksheets[self::getArrayItemString(self::getAttributes($eleSheet, $namespace), 'id')];
$fileWorksheetPath = str_starts_with($fileWorksheet, '/') ? substr($fileWorksheet, 1) : "$dir/$fileWorksheet";
Expand All @@ -257,7 +259,7 @@ public function listWorksheetInfo(string $filename): array
$currCells = 0;
while ($xml->read()) {
if ($xml->localName == 'row' && $xml->nodeType == XMLReader::ELEMENT && $xml->namespaceURI === $mainNS) {
$row = $xml->getAttribute('r');
$row = (int) $xml->getAttribute('r');
$tmpInfo['totalRows'] = $row;
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
$currCells = 0;
Expand Down
1 change: 1 addition & 0 deletions src/PhpSpreadsheet/Reader/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ public function listWorksheetInfo(string $filename): array

$tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
$tmpInfo['sheetState'] = Worksheet::SHEETSTATE_VISIBLE;

$worksheetInfo[] = $tmpInfo;
++$worksheetID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ public function testListInfo(): void
'lastColumnIndex' => 13,
'totalRows' => 31,
'totalColumns' => 14,
'sheetState' => 'visible',
],
[
'worksheetName' => 'Report Data',
'lastColumnLetter' => 'K',
'lastColumnIndex' => 10,
'totalRows' => 65535,
'totalColumns' => 11,
'sheetState' => 'visible',
],
];
self::assertEquals($expected, $info);
Expand Down
25 changes: 25 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Gnumeric/HiddenWorksheetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,29 @@ private function worksheetAssertions(): array
],
];
}

public function testListWorksheetInfo(): void
{
$filename = 'tests/data/Reader/Gnumeric/HiddenSheet.gnumeric';
$reader = new Gnumeric();
$expected = [
[
'worksheetName' => 'Sheet1',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'visible',
],
[
'worksheetName' => 'Sheet2',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'hidden',
],
];
self::assertSame($expected, $reader->listWorksheetInfo($filename));
}
}
27 changes: 26 additions & 1 deletion tests/PhpSpreadsheetTests/Reader/Ods/HiddenWorksheetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class HiddenWorksheetTest extends TestCase
{
public function testPageSetup(): void
{
$filename = 'tests/data/Reader/Ods/HiddenSheet.ods';
$filename = 'tests/data/Reader/Ods/HiddenSheet2.ods';
$reader = new Ods();
$spreadsheet = $reader->load($filename);
$assertions = $this->worksheetAssertions();
Expand Down Expand Up @@ -49,4 +49,29 @@ private function worksheetAssertions(): array
],
];
}

public function testListWorksheetInfo(): void
{
$filename = 'tests/data/Reader/Ods/HiddenSheet2.ods';
$reader = new Ods();
$expected = [
[
'worksheetName' => 'Sheet1',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'visible',
],
[
'worksheetName' => 'Sheet2',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'hidden',
],
];
self::assertSame($expected, $reader->listWorksheetInfo($filename));
}
}
2 changes: 2 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Ods/OdsInfoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,15 @@ public function testReadFileInfo(): void
'lastColumnIndex' => 2,
'totalRows' => 12,
'totalColumns' => 3,
'sheetState' => 'visible',
],
[
'worksheetName' => 'Second Sheet',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 2,
'totalColumns' => 1,
'sheetState' => 'visible',
],
], $wsinfo);
}
Expand Down
41 changes: 41 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Xls/HiddenWorksheetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,45 @@ private function worksheetAssertions(): array
],
];
}

public function testListWorksheetInfo(): void
{
$filename = 'tests/data/Reader/XLS/visibility.xls';
$reader = new Xls();
$expected = [
[
'worksheetName' => 'Sheet1',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'visible',
],
[
'worksheetName' => 'Sheet2',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'hidden',
],
[
'worksheetName' => 'Sheet3',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 1,
'totalColumns' => 1,
'sheetState' => 'visible',
],
[
'worksheetName' => 'Sheet4',
'lastColumnLetter' => 'A',
'lastColumnIndex' => 0,
'totalRows' => 2,
'totalColumns' => 1,
'sheetState' => 'veryHidden',
],
];
self::assertSame($expected, $reader->listWorksheetInfo($filename));
}
}
Loading

0 comments on commit 82ac7ab

Please sign in to comment.