From 324e19035f9973de0fe4b5bfe9e9503c2a5b40ac Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Fri, 24 Feb 2023 18:11:38 -0800 Subject: [PATCH] Xls Reader Conditional Styles (#3400) The code currently allocates the style object as a non-conditional style, leading to corruption when the spreadsheet is written out. That being said, Font Color is the only Conditional Formatting I have gotten to work for Xls for read or write. Use of other styles will essentially continue to be ignored, but will at least no longer result in corrupt spreadsheets. --- src/PhpSpreadsheet/Reader/Xls.php | 2 +- .../Xls/ConditionalFormattingBasicTest.php | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php index 7c1793740..f35e8c3b2 100644 --- a/src/PhpSpreadsheet/Reader/Xls.php +++ b/src/PhpSpreadsheet/Reader/Xls.php @@ -7921,7 +7921,7 @@ class Xls extends BaseReader // offset: 6; size: 4; Options $options = self::getInt4d($recordData, 6); - $style = new Style(); + $style = new Style(false, true); // non-supervisor, conditional $this->getCFStyleOptions($options, $style); $hasFontRecord = (bool) ((0x04000000 & $options) >> 26); diff --git a/tests/PhpSpreadsheetTests/Reader/Xls/ConditionalFormattingBasicTest.php b/tests/PhpSpreadsheetTests/Reader/Xls/ConditionalFormattingBasicTest.php index 20f6ed8d5..bf78d7a41 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xls/ConditionalFormattingBasicTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xls/ConditionalFormattingBasicTest.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Xls; use PhpOffice\PhpSpreadsheet\Reader\Xls; +use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PHPUnit\Framework\TestCase; @@ -146,4 +147,59 @@ class ConditionalFormattingBasicTest extends TestCase ], ]; } + + public function testReadConditionalFormattingStyles(): void + { + $filename = 'tests/data/Reader/XLS/CF_Basic_Comparisons.xls'; + $reader = new Xls(); + $spreadsheet = $reader->load($filename); + $sheet = $spreadsheet->getActiveSheet(); + $expectedRange = 'A2:E5'; + $hasConditionalStyles = $sheet->conditionalStylesExists($expectedRange); + self::assertTrue($hasConditionalStyles); + + $conditionalStyles = $sheet->getConditionalStyles($expectedRange); + self::assertCount(3, $conditionalStyles); + + $style = $conditionalStyles[0]->getStyle(); + $font = $style->getFont(); + self::assertSame('FF0000FF', $font->getColor()->getArgb()); + self::assertNull($font->getItalic()); + self::assertNull($font->getStrikethrough()); + // Fill not handled correctly - forget for now + $borders = $style->getBorders(); + self::assertSame(Border::BORDER_OMIT, $borders->getLeft()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getRight()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getTop()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getBottom()->getBorderStyle()); + self::assertNull($style->getNumberFormat()->getFormatCode()); + + $style = $conditionalStyles[1]->getStyle(); + $font = $style->getFont(); + self::assertSame('FF800000', $font->getColor()->getArgb()); + self::assertNull($font->getItalic()); + self::assertNull($font->getStrikethrough()); + // Fill not handled correctly - forget for now + $borders = $style->getBorders(); + self::assertSame(Border::BORDER_OMIT, $borders->getLeft()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getRight()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getTop()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getBottom()->getBorderStyle()); + self::assertNull($style->getNumberFormat()->getFormatCode()); + + $style = $conditionalStyles[2]->getStyle(); + $font = $style->getFont(); + self::assertSame('FF00FF00', $font->getColor()->getArgb()); + self::assertNull($font->getItalic()); + self::assertNull($font->getStrikethrough()); + // Fill not handled correctly - forget for now + $borders = $style->getBorders(); + self::assertSame(Border::BORDER_OMIT, $borders->getLeft()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getRight()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getTop()->getBorderStyle()); + self::assertSame(Border::BORDER_OMIT, $borders->getBottom()->getBorderStyle()); + self::assertNull($style->getNumberFormat()->getFormatCode()); + + $spreadsheet->disconnectWorksheets(); + } }