From 6a2e0cef4390c62e9847eaa09b1a2b48297d5651 Mon Sep 17 00:00:00 2001 From: Robert Doering Date: Tue, 1 Oct 2019 15:52:15 +0200 Subject: [PATCH] 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 --- CHANGELOG.md | 1 + src/PhpSpreadsheet/Reader/Xlsx.php | 66 +++++++++++++++++++----------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1675fab3..3605f1a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Fix ODS Reader when no DC namespace are defined [#1182](https://github.com/PHPOffice/PhpSpreadsheet/pull/1182) - Fixed Functions->ifCondition for allowing <> and empty condition [#1206](https://github.com/PHPOffice/PhpSpreadsheet/pull/1206) - Validate XIRR inputs and return correct error values [#1120](https://github.com/PHPOffice/PhpSpreadsheet/issues/1120) +- Allow to read xlsx files with exotic workbook names like "workbook2.xml" [#1183](https://github.com/PHPOffice/PhpSpreadsheet/pull/1183) ## [1.9.0] - 2019-08-17 diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 1c1351f7..4c107505 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -77,34 +77,17 @@ class Xlsx extends BaseReader { File::assertFile($pFilename); - $xl = false; - // Load file + $result = false; $zip = new ZipArchive(); - if ($zip->open($pFilename) === true) { - // check if it is an OOXML archive - $rels = simplexml_load_string( - $this->securityScanner->scan( - $this->getFromZipArchive($zip, '_rels/.rels') - ), - 'SimpleXMLElement', - Settings::getLibXmlLoaderOptions() - ); - if ($rels !== false) { - foreach ($rels->Relationship as $rel) { - switch ($rel['Type']) { - case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument': - if (basename($rel['Target']) == 'workbook.xml') { - $xl = true; - } - break; - } - } - } + if ($zip->open($pFilename) === true) { + $workbookBasename = $this->getWorkbookBaseName($zip); + $result = !empty($workbookBasename); + $zip->close(); } - return $xl; + return $result; } /** @@ -357,8 +340,9 @@ class Xlsx extends BaseReader // Read the theme first, because we need the colour scheme when reading the styles //~ http://schemas.openxmlformats.org/package/2006/relationships" + $workbookBasename = $this->getWorkbookBaseName($zip); $wbRels = simplexml_load_string( - $this->securityScanner->scan($this->getFromZipArchive($zip, 'xl/_rels/workbook.xml.rels')), + $this->securityScanner->scan($this->getFromZipArchive($zip, "xl/_rels/${workbookBasename}.rels")), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() ); @@ -2026,4 +2010,38 @@ class Xlsx extends BaseReader return (bool) $xsdBoolean; } + + /** + * @param ZipArchive $zip Opened zip archive + * + * @return string basename of the used excel workbook + */ + private function getWorkbookBaseName(ZipArchive $zip) + { + $workbookBasename = ''; + + // check if it is an OOXML archive + $rels = simplexml_load_string( + $this->securityScanner->scan( + $this->getFromZipArchive($zip, '_rels/.rels') + ), + 'SimpleXMLElement', + Settings::getLibXmlLoaderOptions() + ); + if ($rels !== false) { + foreach ($rels->Relationship as $rel) { + switch ($rel['Type']) { + case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument': + $basename = basename($rel['Target']); + if (preg_match('/workbook.*\.xml/', $basename)) { + $workbookBasename = $basename; + } + + break; + } + } + } + + return $workbookBasename; + } }