PhpSpreadsheet/tests/PhpSpreadsheetTests/Writer/Xlsx/ConditionalTest.php

566 lines
22 KiB
PHP

<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Style;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class ConditionalTest extends AbstractFunctional
{
/**
* @var string
*/
protected $cellRange;
/**
* @var Style
*/
protected $style;
protected function setUp(): void
{
parent::setUp();
$this->cellRange = 'C3:E5';
$this->style = new Style();
$this->style->applyFromArray([
'fill' => [
'color' => ['argb' => 'FFFFC000'],
'fillType' => Fill::FILL_SOLID,
],
]);
}
public function testWriteSimpleCellConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\CellValue($this->cellRange);
$wizard->greaterThan(5);
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="cellIs" dxfId="" priority="1" operator="greaterThan"><formula>5</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
public function testWriteBetweenCellConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\CellValue($this->cellRange);
$wizard->between(-5)->and(5);
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="cellIs" dxfId="" priority="1" operator="between"><formula>-5</formula><formula>5</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
public function testWriteTextConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\TextValue($this->cellRange);
$wizard->contains('PHP');
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="containsText" dxfId="" priority="1" operator="containsText" text="PHP"><formula>NOT(ISERROR(SEARCH(&quot;PHP&quot;,C3)))</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
/**
* @dataProvider textConditionalsProvider
*/
public function testWriteTextConditionals(string $conditionType, string $operatorType, string $expected): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$condition = new Conditional();
$condition->setConditionType($conditionType);
$condition->setOperatorType($operatorType);
$condition->setText('PHP');
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
self::assertStringContainsString($expected, $data);
}
public function textConditionalsProvider(): array
{
return [
'Contains' => [
Conditional::CONDITION_CONTAINSTEXT,
Conditional::OPERATOR_CONTAINSTEXT,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="containsText" dxfId="" priority="1" operator="containsText" text="PHP"><formula>NOT(ISERROR(SEARCH(&quot;PHP&quot;,C3)))</formula></cfRule></conditionalFormatting>
XML
],
'Not Contains' => [
Conditional::CONDITION_NOTCONTAINSTEXT,
Conditional::OPERATOR_NOTCONTAINS,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="notContainsText" dxfId="" priority="1" operator="notContains" text="PHP"><formula>ISERROR(SEARCH(&quot;PHP&quot;,C3))</formula></cfRule></conditionalFormatting>
XML
],
'Begins With' => [
Conditional::CONDITION_BEGINSWITH,
Conditional::OPERATOR_BEGINSWITH,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="beginsWith" dxfId="" priority="1" operator="beginsWith" text="PHP"><formula>LEFT(C3,LEN(&quot;PHP&quot;))=&quot;PHP&quot;</formula></cfRule></conditionalFormatting>
XML
],
'Ends With' => [
Conditional::CONDITION_ENDSWITH,
Conditional::OPERATOR_ENDSWITH,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="endsWith" dxfId="" priority="1" operator="endsWith" text="PHP"><formula>RIGHT(C3,LEN(&quot;PHP&quot;))=&quot;PHP&quot;</formula></cfRule></conditionalFormatting>
XML
],
];
}
public function testWriteDateConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\DateValue($this->cellRange);
$wizard->today();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="today"><formula>FLOOR(C3,1)=TODAY()</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
/**
* @dataProvider dateConditionalsProvider
*/
public function testWriteDateConditionals(string $timePeriod, string $expected): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$condition = new Conditional();
$condition->setConditionType(Conditional::CONDITION_TIMEPERIOD);
$condition->setOperatorType($timePeriod);
$condition->setText($timePeriod);
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
self::assertStringContainsString($expected, $data);
}
public function dateConditionalsProvider(): array
{
return [
'Yesterday' => [
Conditional::TIMEPERIOD_YESTERDAY,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="yesterday"><formula>FLOOR(C3)=TODAY()-1</formula></cfRule></conditionalFormatting>
XML
],
'Today' => [
Conditional::TIMEPERIOD_TODAY,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="today"><formula>FLOOR(C3)=TODAY()</formula></cfRule></conditionalFormatting>
XML
],
'Tomorrow' => [
Conditional::TIMEPERIOD_TOMORROW,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="tomorrow"><formula>FLOOR(C3)=TODAY()+1</formula></cfRule></conditionalFormatting>
XML
],
'Last 7 Days' => [
Conditional::TIMEPERIOD_LAST_7_DAYS,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="last7Days"><formula>AND(TODAY()-FLOOR(C3,1)&lt;=6,FLOOR(C3,1)&lt;=TODAY())</formula></cfRule></conditionalFormatting>
XML
],
'Last Week' => [
Conditional::TIMEPERIOD_LAST_WEEK,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="lastWeek"><formula>AND(TODAY()-ROUNDDOWN(C3,0)&gt;=(WEEKDAY(TODAY())),TODAY()-ROUNDDOWN(C3,0)&lt;(WEEKDAY(TODAY())+7))</formula></cfRule></conditionalFormatting>
XML
],
'This Week' => [
Conditional::TIMEPERIOD_THIS_WEEK,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="thisWeek"><formula>AND(TODAY()-ROUNDDOWN(C3,0)&lt;=WEEKDAY(TODAY())-1,ROUNDDOWN(C3,0)-TODAY()&lt;=7-WEEKDAY(TODAY()))</formula></cfRule></conditionalFormatting>
XML
],
'Next Week' => [
Conditional::TIMEPERIOD_NEXT_WEEK,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="nextWeek"><formula>AND(ROUNDDOWN(C3,0)-TODAY()&gt;(7-WEEKDAY(TODAY())),ROUNDDOWN(C3,0)-TODAY()&lt;(15-WEEKDAY(TODAY())))</formula></cfRule></conditionalFormatting>
XML
],
'Last Month' => [
Conditional::TIMEPERIOD_LAST_MONTH,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="lastMonth"><formula>AND(MONTH(C3)=MONTH(EDATE(TODAY(),0-1)),YEAR(C3)=YEAR(EDATE(TODAY(),0-1)))</formula></cfRule></conditionalFormatting>
XML
],
'This Month' => [
Conditional::TIMEPERIOD_THIS_MONTH,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="thisMonth"><formula>AND(MONTH(C3)=MONTH(TODAY()),YEAR(C3)=YEAR(TODAY()))</formula></cfRule></conditionalFormatting>
XML
],
'Next Month' => [
Conditional::TIMEPERIOD_NEXT_MONTH,
<<<XML
><conditionalFormatting sqref="C3:E5"><cfRule type="timePeriod" dxfId="" priority="1" timePeriod="nextMonth"><formula>AND(MONTH(C3)=MONTH(EDATE(TODAY(),0+1)),YEAR(C3)=YEAR(EDATE(TODAY(),0+1)))</formula></cfRule></conditionalFormatting>
XML
],
];
}
public function testWriteBlankConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Blanks($this->cellRange);
$wizard->isBlank();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="containsBlanks" dxfId="" priority="1"><formula>LEN(TRIM(C3))=0</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
public function testWriteNonBlankConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Blanks($this->cellRange);
$wizard->notBlank();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="notContainsBlanks" dxfId="" priority="1"><formula>LEN(TRIM(C3))&gt;0</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
/**
* @dataProvider blanksConditionalsProvider
*/
public function testWriteBlanksConditionals(string $conditionalType, string $expected): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$condition = new Conditional();
$condition->setConditionType($conditionalType);
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
self::assertStringContainsString($expected, $data);
}
public function blanksConditionalsProvider(): array
{
return [
'Blanks' => [
Conditional::CONDITION_CONTAINSBLANKS,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="containsBlanks" dxfId="" priority="1"><formula>LEN(TRIM(C3))=0</formula></cfRule></conditionalFormatting>
XML
],
'Not Blanks' => [
Conditional::CONDITION_NOTCONTAINSBLANKS,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="notContainsBlanks" dxfId="" priority="1"><formula>LEN(TRIM(C3))&gt;0</formula></cfRule></conditionalFormatting>
XML
],
];
}
public function testWriteNonErrorConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Errors($this->cellRange);
$wizard->notError();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="notContainsErrors" dxfId="" priority="1"><formula>NOT(ISERROR(C3))</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
public function testWriteErrorConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Errors($this->cellRange);
$wizard->isError();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="containsErrors" dxfId="" priority="1"><formula>ISERROR(C3)</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
/**
* @dataProvider errorsConditionalsProvider
*/
public function testWriteErrorsConditionals(string $conditionalType, string $expected): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$condition = new Conditional();
$condition->setConditionType($conditionalType);
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
self::assertStringContainsString($expected, $data);
}
public function errorsConditionalsProvider(): array
{
return [
'Errors' => [
Conditional::CONDITION_CONTAINSERRORS,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="containsErrors" dxfId="" priority="1"><formula>ISERROR(C3)</formula></cfRule></conditionalFormatting>
XML
],
'Not Errors' => [
Conditional::CONDITION_NOTCONTAINSERRORS,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="notContainsErrors" dxfId="" priority="1"><formula>NOT(ISERROR(C3))</formula></cfRule></conditionalFormatting>
XML
],
];
}
public function testWriteUniqueConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Duplicates($this->cellRange);
$wizard->unique();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="uniqueValues" dxfId="" priority="1"/></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
public function testWriteDuplicateConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Duplicates($this->cellRange);
$wizard->duplicates();
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="duplicateValues" dxfId="" priority="1"/></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
/**
* @dataProvider duplicatesConditionalsProvider
*/
public function testWriteDuplicatesConditionals(string $conditionalType, string $expected): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$condition = new Conditional();
$condition->setConditionType($conditionalType);
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
self::assertStringContainsString($expected, $data);
}
public function duplicatesConditionalsProvider(): array
{
return [
'Duplicates' => [
Conditional::CONDITION_DUPLICATES,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="duplicateValues" dxfId="" priority="1"/></conditionalFormatting>
XML
],
'Unique' => [
Conditional::CONDITION_UNIQUE,
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="uniqueValues" dxfId="" priority="1"/></conditionalFormatting>
XML
],
];
}
public function testWriteExpressionConditionalFromWizard(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$wizard = new Wizard\Expression($this->cellRange);
$wizard->expression('=ISODD(A1)');
$condition = $wizard->getConditional();
$condition->setStyle($this->style);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
$expected = <<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="expression" dxfId="" priority="1"><formula>ISODD(C3)</formula></cfRule></conditionalFormatting>
XML;
self::assertStringContainsString($expected, $data);
}
/**
* @dataProvider expressionsConditionalsProvider
*/
public function testWriteExpressionConditionals(string $expression, string $expected): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$condition = new Conditional();
$condition->setConditionType(Conditional::CONDITION_EXPRESSION);
$condition->setStyle($this->style);
$condition->setConditions([$expression]);
$worksheet->setConditionalStyles($this->cellRange, [$condition]);
$writer = new Xlsx($spreadsheet);
$writerWorksheet = new Xlsx\Worksheet($writer);
$data = $writerWorksheet->writeWorksheet($worksheet, []);
self::assertStringContainsString($expected, $data);
}
public function expressionsConditionalsProvider(): array
{
return [
'Odd' => [
'ISODD(C3)',
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="expression" dxfId="" priority="1"><formula>ISODD(C3)</formula></cfRule></conditionalFormatting>
XML
],
'Even' => [
'ISEVEN(C3)',
<<<XML
<conditionalFormatting sqref="C3:E5"><cfRule type="expression" dxfId="" priority="1"><formula>ISEVEN(C3)</formula></cfRule></conditionalFormatting>
XML
],
];
}
}