Invert Union and Intersection Between Excel and Xml

I don't know why MS did this. We're stuck with it.
This commit is contained in:
oleibman
2024-05-28 17:01:45 -07:00
parent 33edddf40d
commit c8f5c62e5d
7 changed files with 68 additions and 8 deletions
@@ -188,7 +188,9 @@ class ConditionalStyles
$conditionalStyles = $this->readStyleRules($cfRules, $xmlExtLst);
// Extract all cell references in $cellRangeReference
$cellRangeReference = str_replace('$', '', strtoupper($cellRangeReference));
// N.B. In Excel UI, intersection is space and union is comma.
// But in Xml, intersection is comma and union is space.
$cellRangeReference = str_replace(['$', ' ', ',', '^'], ['', '^', ' ', ','], strtoupper($cellRangeReference));
$worksheet->getStyle($cellRangeReference)->setConditionalStyles($conditionalStyles);
}
}
@@ -60,7 +60,6 @@ class CellMatcher
protected function setReferenceCellForExpressions(string $conditionalRange): void
{
$conditionalRange = str_replace(' ', ',', $conditionalRange);
$conditionalRange = Coordinate::splitRange(str_replace('$', '', strtoupper($conditionalRange)));
[$this->referenceCell] = $conditionalRange[0];
+3 -3
View File
@@ -1422,7 +1422,7 @@ class Worksheet implements IComparable
$cell = $this->getCell($coordinate);
foreach (array_keys($this->conditionalStylesCollection) as $conditionalRange) {
$cellBlocks = explode(' ', $conditionalRange);
$cellBlocks = explode(',', $conditionalRange);
foreach ($cellBlocks as $cellBlock) {
if ($cell->isInRange($cellBlock)) {
return $this->conditionalStylesCollection[$conditionalRange];
@@ -1438,7 +1438,7 @@ class Worksheet implements IComparable
$coordinate = strtoupper($coordinate);
$cell = $this->getCell($coordinate);
foreach (array_keys($this->conditionalStylesCollection) as $conditionalRange) {
$cellBlocks = explode(' ', $conditionalRange);
$cellBlocks = explode(',', $conditionalRange);
foreach ($cellBlocks as $cellBlock) {
if ($cell->isInRange($cellBlock)) {
return $conditionalRange;
@@ -1507,7 +1507,7 @@ class Worksheet implements IComparable
*/
public function setConditionalStyles(string $coordinate, array $styles): static
{
$this->conditionalStylesCollection[trim(strtoupper($coordinate))] = $styles;
$this->conditionalStylesCollection[strtoupper($coordinate)] = $styles;
return $this;
}
+7 -1
View File
@@ -492,7 +492,13 @@ class Worksheet extends BIFFwriter
{
$conditionalFormulaHelper = new ConditionalHelper($this->parser);
$arrConditionalStyles = $this->phpSheet->getConditionalStylesCollection();
$arrConditionalStyles = [];
foreach ($this->phpSheet->getConditionalStylesCollection() as $key => $value) {
$keyExplode = explode(',', $key);
foreach ($keyExplode as $exploded) {
$arrConditionalStyles[$exploded] = $value;
}
}
if (!empty($arrConditionalStyles)) {
// Write ConditionalFormattingTable records
foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) {
+3 -1
View File
@@ -815,7 +815,9 @@ class Worksheet extends WriterPart
// Loop through styles in the current worksheet
foreach ($worksheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
$objWriter->startElement('conditionalFormatting');
$objWriter->writeAttribute('sqref', $cellCoordinate);
// N.B. In Excel UI, intersection is space and union is comma.
// But in Xml, intersection is comma and union is space.
$objWriter->writeAttribute('sqref', str_replace(['$', ' ', ',', '^'], ['', '^', ' ', ','], $cellCoordinate));
foreach ($conditionalStyles as $conditional) {
// WHY was this again?
@@ -16,7 +16,7 @@ class Issue4039Test extends \PHPUnit\Framework\TestCase
$spreadsheet = $reader->load(self::$testbook);
$sheet = $spreadsheet->getSheetByNameOrThrow('cellIs Expression');
$expected = [
'A12:D17 A20', // split range
'A12:D17,A20', // split range
'A22:D27',
'A2:E6',
];
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class ConditionalUnionTest extends AbstractFunctional
{
public function testConditionalUnion(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
]);
$condition1 = new Conditional();
$condition1->setConditionType(Conditional::CONDITION_CELLIS);
$condition1->setOperatorType(Conditional::OPERATOR_BETWEEN);
$condition1->setConditions([2, 4]);
$condition1->getStyle()->getFont()
->setBold(true);
$conditionalStyles = [$condition1];
$sheet->setConditionalStyles('A1:A3,C1:E3', $conditionalStyles);
$robj = $this->writeAndReload($spreadsheet, 'Xls');
$spreadsheet->disconnectWorksheets();
$sheet0 = $robj->getActiveSheet();
$conditionals = $sheet0->getConditionalStylesCollection();
self::assertSame(['A1:A3', 'C1:E3'], array_keys($conditionals));
$cond1 = $conditionals['A1:A3'][0];
self::assertSame(Conditional::CONDITION_CELLIS, $cond1->getConditionType());
self::assertSame(Conditional::OPERATOR_BETWEEN, $cond1->getOperatorType());
self::assertSame([2, 4], $cond1->getConditions());
$font1 = $cond1->getStyle()->getFont();
self::assertTrue($font1->getBold());
$cond2 = $conditionals['C1:E3'][0];
self::assertSame(Conditional::CONDITION_CELLIS, $cond2->getConditionType());
self::assertSame(Conditional::OPERATOR_BETWEEN, $cond2->getOperatorType());
self::assertSame([2, 4], $cond2->getConditions());
$font2 = $cond2->getStyle()->getFont();
self::assertTrue($font2->getBold());
$robj->disconnectWorksheets();
}
}