diff --git a/CHANGELOG.md b/CHANGELOG.md index 29d794ba..32f3e5bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Xls Reader changing grey background to black in Excel template [Issue #2147](Changing grey background to black in Excel template) [PR #2156](https://github.com/PHPOffice/PhpSpreadsheet/pull/2156) - Column width and Row height styles in the Html Reader when the value includes a unit of measure. [Issue #2145](https://github.com/PHPOffice/PhpSpreadsheet/issues/2145). - Data Validation flags not set correctly when reading XLSX files. [Issue #2224](https://github.com/PHPOffice/PhpSpreadsheet/issues/2224) [PR #2225](https://github.com/PHPOffice/PhpSpreadsheet/pull/2225) +- Reading XLSX files without styles.xml throws an exception. [Issue #2246](https://github.com/PHPOffice/PhpSpreadsheet/issues/2246) ## 1.18.0 - 2021-05-31 diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 5d379daf..2bff7e1e 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -395,10 +395,9 @@ class Xlsx extends BaseReader // Initialisations $excel = new Spreadsheet(); $excel->removeSheetByIndex(0); - if (!$this->readDataOnly) { - $excel->removeCellStyleXfByIndex(0); // remove the default style - $excel->removeCellXfByIndex(0); // remove the default style - } + $addingFirstCellStyleXf = true; + $addingFirstCellXf = true; + $unparsedLoadedData = []; $this->zip = $zip = new ZipArchive(); @@ -534,8 +533,14 @@ class Xlsx extends BaseReader . "$xmlNamespaceBase/styles" . "']"; $xpath = self::getArrayItem(self::xpathNoFalse($relsWorkbook, $relType)); - // I think Nonamespace is okay because I'm using xpath. - $xmlStyles = $this->loadZipNonamespace("$dir/$xpath[Target]", $mainNS); + + if ($xpath === null) { + $xmlStyles = self::testSimpleXml(null); + } else { + // I think Nonamespace is okay because I'm using xpath. + $xmlStyles = $this->loadZipNonamespace("$dir/$xpath[Target]", $mainNS); + } + $xmlStyles->registerXPathNamespace('smm', Namespaces::MAIN); $fills = self::xpathNoFalse($xmlStyles, 'smm:fills/smm:fill'); $fonts = self::xpathNoFalse($xmlStyles, 'smm:fonts/smm:font'); @@ -593,6 +598,10 @@ class Xlsx extends BaseReader // add style to cellXf collection $objStyle = new Style(); self::readStyle($objStyle, $style); + if ($addingFirstCellXf) { + $excel->removeCellXfByIndex(0); // remove the default style + $addingFirstCellXf = false; + } $excel->addCellXf($objStyle); } @@ -624,10 +633,13 @@ class Xlsx extends BaseReader // add style to cellStyleXf collection $objStyle = new Style(); self::readStyle($objStyle, $cellStyle); + if ($addingFirstCellStyleXf) { + $excel->removeCellStyleXfByIndex(0); // remove the default style + $addingFirstCellStyleXf = false; + } $excel->addCellStyleXf($objStyle); } } - $styleReader = new Styles($xmlStyles); $styleReader->setStyleBaseData(self::$theme, $styles, $cellStyles); $dxfs = $styleReader->dxfs($this->readDataOnly); diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php index a3776eb4..e1271b9a 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php @@ -4,7 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataValidation; -use PhpOffice\PhpSpreadsheet\Document\Properties; +use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Style\Conditional; @@ -63,6 +63,49 @@ class XlsxTest extends TestCase } } + /** + * Test load Xlsx file without styles.xml. + */ + public function testLoadXlsxWithoutStyles(): void + { + $filename = 'tests/data/Reader/XLSX/issue.2246a.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($filename); + + $tempFilename = File::temporaryFilename(); + $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); + $writer->save($tempFilename); + + $reader = new Xlsx(); + $reloadedSpreadsheet = $reader->load($tempFilename); + unlink($tempFilename); + + $reloadedWorksheet = $reloadedSpreadsheet->getActiveSheet(); + + self::assertEquals('TipoDato', $reloadedWorksheet->getCell('A1')->getValue()); + } + + /** + * Test load Xlsx file with empty styles.xml. + */ + public function testLoadXlsxWithEmptyStyles(): void + { + $filename = 'tests/data/Reader/XLSX/issue.2246b.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($filename); + + $tempFilename = File::temporaryFilename(); + $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); + $writer->save($tempFilename); + + $reader = new Xlsx(); + $reloadedSpreadsheet = $reader->load($tempFilename); + unlink($tempFilename); + + $reloadedWorksheet = $reloadedSpreadsheet->getActiveSheet(); + self::assertEquals('TipoDato', $reloadedWorksheet->getCell('A1')->getValue()); + } + public function testLoadXlsxAutofilter(): void { $filename = 'tests/data/Reader/XLSX/autofilterTest.xlsx'; diff --git a/tests/data/Reader/XLSX/issue.2246a.xlsx b/tests/data/Reader/XLSX/issue.2246a.xlsx new file mode 100644 index 00000000..b1612208 Binary files /dev/null and b/tests/data/Reader/XLSX/issue.2246a.xlsx differ diff --git a/tests/data/Reader/XLSX/issue.2246b.xlsx b/tests/data/Reader/XLSX/issue.2246b.xlsx new file mode 100644 index 00000000..f33cbedc Binary files /dev/null and b/tests/data/Reader/XLSX/issue.2246b.xlsx differ