Skip to content

Commit 6a2e0ce

Browse files
Robert DoeringPowerKiKi
authored andcommitted
Read xlsx files with exotic workbook names like "workbook2.xml"
Some auto generated xlsx files are using other names as workbook than "workbook.xml". This is fixed by supporting names of workbooks by regex `/workbook.*\.xml/`. Closes #1183
1 parent e5409f0 commit 6a2e0ce

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2828
- Fix ODS Reader when no DC namespace are defined [#1182](https://github.com/PHPOffice/PhpSpreadsheet/pull/1182)
2929
- Fixed Functions->ifCondition for allowing <> and empty condition [#1206](https://github.com/PHPOffice/PhpSpreadsheet/pull/1206)
3030
- Validate XIRR inputs and return correct error values [#1120](https://github.com/PHPOffice/PhpSpreadsheet/issues/1120)
31+
- Allow to read xlsx files with exotic workbook names like "workbook2.xml" [#1183](https://github.com/PHPOffice/PhpSpreadsheet/pull/1183)
3132

3233
## [1.9.0] - 2019-08-17
3334

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,34 +77,17 @@ public function canRead($pFilename)
7777
{
7878
File::assertFile($pFilename);
7979

80-
$xl = false;
81-
// Load file
80+
$result = false;
8281
$zip = new ZipArchive();
82+
8383
if ($zip->open($pFilename) === true) {
84-
// check if it is an OOXML archive
85-
$rels = simplexml_load_string(
86-
$this->securityScanner->scan(
87-
$this->getFromZipArchive($zip, '_rels/.rels')
88-
),
89-
'SimpleXMLElement',
90-
Settings::getLibXmlLoaderOptions()
91-
);
92-
if ($rels !== false) {
93-
foreach ($rels->Relationship as $rel) {
94-
switch ($rel['Type']) {
95-
case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
96-
if (basename($rel['Target']) == 'workbook.xml') {
97-
$xl = true;
98-
}
84+
$workbookBasename = $this->getWorkbookBaseName($zip);
85+
$result = !empty($workbookBasename);
9986

100-
break;
101-
}
102-
}
103-
}
10487
$zip->close();
10588
}
10689

107-
return $xl;
90+
return $result;
10891
}
10992

11093
/**
@@ -357,8 +340,9 @@ public function load($pFilename)
357340

358341
// Read the theme first, because we need the colour scheme when reading the styles
359342
//~ http://schemas.openxmlformats.org/package/2006/relationships"
343+
$workbookBasename = $this->getWorkbookBaseName($zip);
360344
$wbRels = simplexml_load_string(
361-
$this->securityScanner->scan($this->getFromZipArchive($zip, 'xl/_rels/workbook.xml.rels')),
345+
$this->securityScanner->scan($this->getFromZipArchive($zip, "xl/_rels/${workbookBasename}.rels")),
362346
'SimpleXMLElement',
363347
Settings::getLibXmlLoaderOptions()
364348
);
@@ -2026,4 +2010,38 @@ private function castXsdBooleanToBool($xsdBoolean)
20262010

20272011
return (bool) $xsdBoolean;
20282012
}
2013+
2014+
/**
2015+
* @param ZipArchive $zip Opened zip archive
2016+
*
2017+
* @return string basename of the used excel workbook
2018+
*/
2019+
private function getWorkbookBaseName(ZipArchive $zip)
2020+
{
2021+
$workbookBasename = '';
2022+
2023+
// check if it is an OOXML archive
2024+
$rels = simplexml_load_string(
2025+
$this->securityScanner->scan(
2026+
$this->getFromZipArchive($zip, '_rels/.rels')
2027+
),
2028+
'SimpleXMLElement',
2029+
Settings::getLibXmlLoaderOptions()
2030+
);
2031+
if ($rels !== false) {
2032+
foreach ($rels->Relationship as $rel) {
2033+
switch ($rel['Type']) {
2034+
case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
2035+
$basename = basename($rel['Target']);
2036+
if (preg_match('/workbook.*\.xml/', $basename)) {
2037+
$workbookBasename = $basename;
2038+
}
2039+
2040+
break;
2041+
}
2042+
}
2043+
}
2044+
2045+
return $workbookBasename;
2046+
}
20292047
}

0 commit comments

Comments
 (0)