Skip to content

Commit c0ea894

Browse files
author
Mark Baker
authored
Merge pull request #2669 from PHPOffice/Issue-2666_Active-Sheet-Index-from-Google-Sheets
Fix for setting Active Sheet to the first loaded worksheet when `bookViews` element isn't defined
2 parents 1801f58 + b208c52 commit c0ea894

File tree

3 files changed

+156
-79
lines changed

3 files changed

+156
-79
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3939

4040
### Fixed
4141

42+
- Fix for setting Active Sheet to the first loaded worksheet when bookViews element isn't defined [Issue #2666](https://github.com/PHPOffice/PhpSpreadsheet/issues/2666) [PR #2669](https://github.com/PHPOffice/PhpSpreadsheet/pull/2669)
4243
- Fixed behaviour of XLSX font style vertical align settings.
4344
- Resolved formula translations to handle separators (row and column) for array functions as well as for function argument separators; and cleanly handle nesting levels.
4445

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\SheetViews;
2121
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Styles;
2222
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Theme;
23+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\WorkbookView;
2324
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
2425
use PhpOffice\PhpSpreadsheet\RichText\RichText;
2526
use PhpOffice\PhpSpreadsheet\Settings;
@@ -1564,62 +1565,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
15641565
}
15651566
}
15661567

1567-
$workbookView = $xmlWorkbook->children($mainNS)->bookViews->workbookView;
1568-
if ((!$this->readDataOnly || !empty($this->loadSheetsOnly)) && !empty($workbookView)) {
1569-
$workbookViewAttributes = self::testSimpleXml(self::getAttributes($workbookView));
1570-
// active sheet index
1571-
$activeTab = (int) $workbookViewAttributes->activeTab; // refers to old sheet index
1572-
1573-
// keep active sheet index if sheet is still loaded, else first sheet is set as the active
1574-
if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {
1575-
$excel->setActiveSheetIndex($mapSheetId[$activeTab]);
1576-
} else {
1577-
if ($excel->getSheetCount() == 0) {
1578-
$excel->createSheet();
1579-
}
1580-
$excel->setActiveSheetIndex(0);
1581-
}
1582-
1583-
if (isset($workbookViewAttributes->showHorizontalScroll)) {
1584-
$showHorizontalScroll = (string) $workbookViewAttributes->showHorizontalScroll;
1585-
$excel->setShowHorizontalScroll($this->castXsdBooleanToBool($showHorizontalScroll));
1586-
}
1587-
1588-
if (isset($workbookViewAttributes->showVerticalScroll)) {
1589-
$showVerticalScroll = (string) $workbookViewAttributes->showVerticalScroll;
1590-
$excel->setShowVerticalScroll($this->castXsdBooleanToBool($showVerticalScroll));
1591-
}
1592-
1593-
if (isset($workbookViewAttributes->showSheetTabs)) {
1594-
$showSheetTabs = (string) $workbookViewAttributes->showSheetTabs;
1595-
$excel->setShowSheetTabs($this->castXsdBooleanToBool($showSheetTabs));
1596-
}
1597-
1598-
if (isset($workbookViewAttributes->minimized)) {
1599-
$minimized = (string) $workbookViewAttributes->minimized;
1600-
$excel->setMinimized($this->castXsdBooleanToBool($minimized));
1601-
}
1602-
1603-
if (isset($workbookViewAttributes->autoFilterDateGrouping)) {
1604-
$autoFilterDateGrouping = (string) $workbookViewAttributes->autoFilterDateGrouping;
1605-
$excel->setAutoFilterDateGrouping($this->castXsdBooleanToBool($autoFilterDateGrouping));
1606-
}
1607-
1608-
if (isset($workbookViewAttributes->firstSheet)) {
1609-
$firstSheet = (string) $workbookViewAttributes->firstSheet;
1610-
$excel->setFirstSheetIndex((int) $firstSheet);
1611-
}
1612-
1613-
if (isset($workbookViewAttributes->visibility)) {
1614-
$visibility = (string) $workbookViewAttributes->visibility;
1615-
$excel->setVisibility($visibility);
1616-
}
1617-
1618-
if (isset($workbookViewAttributes->tabRatio)) {
1619-
$tabRatio = (string) $workbookViewAttributes->tabRatio;
1620-
$excel->setTabRatio((int) $tabRatio);
1621-
}
1622-
}
1568+
(new WorkbookView($excel))->viewSettings($xmlWorkbook, $mainNS, $mapSheetId, $this->readDataOnly);
16231569

16241570
break;
16251571
}
@@ -1978,29 +1924,6 @@ private function readPrinterSettings(Spreadsheet $excel, $dir, $fileWorksheet, $
19781924
unset($unparsedPrinterSettings);
19791925
}
19801926

1981-
/**
1982-
* Convert an 'xsd:boolean' XML value to a PHP boolean value.
1983-
* A valid 'xsd:boolean' XML value can be one of the following
1984-
* four values: 'true', 'false', '1', '0'. It is case sensitive.
1985-
*
1986-
* Note that just doing '(bool) $xsdBoolean' is not safe,
1987-
* since '(bool) "false"' returns true.
1988-
*
1989-
* @see https://www.w3.org/TR/xmlschema11-2/#boolean
1990-
*
1991-
* @param string $xsdBoolean An XML string value of type 'xsd:boolean'
1992-
*
1993-
* @return bool Boolean value
1994-
*/
1995-
private function castXsdBooleanToBool($xsdBoolean)
1996-
{
1997-
if ($xsdBoolean === 'false') {
1998-
return false;
1999-
}
2000-
2001-
return (bool) $xsdBoolean;
2002-
}
2003-
20041927
private function getWorkbookBaseName(): array
20051928
{
20061929
$workbookBasename = '';
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4+
5+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
6+
use SimpleXMLElement;
7+
8+
class WorkbookView
9+
{
10+
/**
11+
* @var Spreadsheet
12+
*/
13+
private $spreadsheet;
14+
15+
public function __construct(Spreadsheet $spreadsheet)
16+
{
17+
$this->spreadsheet = $spreadsheet;
18+
}
19+
20+
/**
21+
* @param mixed $mainNS
22+
*/
23+
public function viewSettings(SimpleXMLElement $xmlWorkbook, $mainNS, array $mapSheetId, bool $readDataOnly): void
24+
{
25+
if ($this->spreadsheet->getSheetCount() == 0) {
26+
$this->spreadsheet->createSheet();
27+
}
28+
// Default active sheet index to the first loaded worksheet from the file
29+
$this->spreadsheet->setActiveSheetIndex(0);
30+
31+
$workbookView = $xmlWorkbook->children($mainNS)->bookViews->workbookView;
32+
if (($readDataOnly !== true || !empty($this->loadSheetsOnly)) && !empty($workbookView)) {
33+
$workbookViewAttributes = self::testSimpleXml(self::getAttributes($workbookView));
34+
// active sheet index
35+
$activeTab = (int) $workbookViewAttributes->activeTab; // refers to old sheet index
36+
// keep active sheet index if sheet is still loaded, else first sheet is set as the active worksheet
37+
if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {
38+
$this->spreadsheet->setActiveSheetIndex($mapSheetId[$activeTab]);
39+
}
40+
41+
$this->horizontalScroll($workbookViewAttributes);
42+
$this->verticalScroll($workbookViewAttributes);
43+
$this->sheetTabs($workbookViewAttributes);
44+
$this->minimized($workbookViewAttributes);
45+
$this->autoFilterDateGrouping($workbookViewAttributes);
46+
$this->firstSheet($workbookViewAttributes);
47+
$this->visibility($workbookViewAttributes);
48+
$this->tabRatio($workbookViewAttributes);
49+
}
50+
}
51+
52+
/**
53+
* @param mixed $value
54+
*/
55+
public static function testSimpleXml($value): SimpleXMLElement
56+
{
57+
return ($value instanceof SimpleXMLElement)
58+
? $value
59+
: new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><root></root>');
60+
}
61+
62+
public static function getAttributes(?SimpleXMLElement $value, string $ns = ''): SimpleXMLElement
63+
{
64+
return self::testSimpleXml($value === null ? $value : $value->attributes($ns));
65+
}
66+
67+
/**
68+
* Convert an 'xsd:boolean' XML value to a PHP boolean value.
69+
* A valid 'xsd:boolean' XML value can be one of the following
70+
* four values: 'true', 'false', '1', '0'. It is case sensitive.
71+
*
72+
* Note that just doing '(bool) $xsdBoolean' is not safe,
73+
* since '(bool) "false"' returns true.
74+
*
75+
* @see https://www.w3.org/TR/xmlschema11-2/#boolean
76+
*
77+
* @param string $xsdBoolean An XML string value of type 'xsd:boolean'
78+
*
79+
* @return bool Boolean value
80+
*/
81+
private function castXsdBooleanToBool(string $xsdBoolean): bool
82+
{
83+
if ($xsdBoolean === 'false') {
84+
return false;
85+
}
86+
87+
return (bool) $xsdBoolean;
88+
}
89+
90+
private function horizontalScroll(SimpleXMLElement $workbookViewAttributes): void
91+
{
92+
if (isset($workbookViewAttributes->showHorizontalScroll)) {
93+
$showHorizontalScroll = (string) $workbookViewAttributes->showHorizontalScroll;
94+
$this->spreadsheet->setShowHorizontalScroll($this->castXsdBooleanToBool($showHorizontalScroll));
95+
}
96+
}
97+
98+
private function verticalScroll(SimpleXMLElement $workbookViewAttributes): void
99+
{
100+
if (isset($workbookViewAttributes->showVerticalScroll)) {
101+
$showVerticalScroll = (string) $workbookViewAttributes->showVerticalScroll;
102+
$this->spreadsheet->setShowVerticalScroll($this->castXsdBooleanToBool($showVerticalScroll));
103+
}
104+
}
105+
106+
private function sheetTabs(SimpleXMLElement $workbookViewAttributes): void
107+
{
108+
if (isset($workbookViewAttributes->showSheetTabs)) {
109+
$showSheetTabs = (string) $workbookViewAttributes->showSheetTabs;
110+
$this->spreadsheet->setShowSheetTabs($this->castXsdBooleanToBool($showSheetTabs));
111+
}
112+
}
113+
114+
private function minimized(SimpleXMLElement $workbookViewAttributes): void
115+
{
116+
if (isset($workbookViewAttributes->minimized)) {
117+
$minimized = (string) $workbookViewAttributes->minimized;
118+
$this->spreadsheet->setMinimized($this->castXsdBooleanToBool($minimized));
119+
}
120+
}
121+
122+
private function autoFilterDateGrouping(SimpleXMLElement $workbookViewAttributes): void
123+
{
124+
if (isset($workbookViewAttributes->autoFilterDateGrouping)) {
125+
$autoFilterDateGrouping = (string) $workbookViewAttributes->autoFilterDateGrouping;
126+
$this->spreadsheet->setAutoFilterDateGrouping($this->castXsdBooleanToBool($autoFilterDateGrouping));
127+
}
128+
}
129+
130+
private function firstSheet(SimpleXMLElement $workbookViewAttributes): void
131+
{
132+
if (isset($workbookViewAttributes->firstSheet)) {
133+
$firstSheet = (string) $workbookViewAttributes->firstSheet;
134+
$this->spreadsheet->setFirstSheetIndex((int) $firstSheet);
135+
}
136+
}
137+
138+
private function visibility(SimpleXMLElement $workbookViewAttributes): void
139+
{
140+
if (isset($workbookViewAttributes->visibility)) {
141+
$visibility = (string) $workbookViewAttributes->visibility;
142+
$this->spreadsheet->setVisibility($visibility);
143+
}
144+
}
145+
146+
private function tabRatio(SimpleXMLElement $workbookViewAttributes): void
147+
{
148+
if (isset($workbookViewAttributes->tabRatio)) {
149+
$tabRatio = (string) $workbookViewAttributes->tabRatio;
150+
$this->spreadsheet->setTabRatio((int) $tabRatio);
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)