Fix Reading XLSX files without styles.xml throws an exception. (#2247)

* Fix Reading XLSX files without styles.xml throws an exception.

* Bugfix, debugging code removed

* Fix Reading XLSX files without styles.xml throws an exception (rethinked)

* Fix Reading XLSX files without styles.xml throws an exception (rethinked)

* Style fixes

* Fix Spreadsheet loaded without styles cannot be written

* Replaced test files for empty styles.xml testing
This commit is contained in:
Alayn Gortazar 2021-08-16 14:05:32 +02:00 committed by GitHub
parent d7ac7021c6
commit d0076343c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 8 deletions

View File

@ -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

View File

@ -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));
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);

View File

@ -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';

Binary file not shown.

Binary file not shown.