diff --git a/src/FastExcelWriter/Conditional/Conditional.php b/src/FastExcelWriter/Conditional/Conditional.php
index 822e243..5621090 100644
--- a/src/FastExcelWriter/Conditional/Conditional.php
+++ b/src/FastExcelWriter/Conditional/Conditional.php
@@ -42,7 +42,12 @@ class Conditional
protected string $operator;
- protected array $style = ['font-color' => '#000000', 'fill-color' => '#ffffff', 'fill-pattern' => 'solid'];
+ protected array $style = [
+ 'font-color' => '#000000',
+ 'fill-color' => '#ffffff',
+ 'fill-pattern' => 'solid',
+ 'color-rgb' => [],
+ ];
protected Sheet $sheet;
protected int $priority;
@@ -52,11 +57,7 @@ class Conditional
protected ?string $text = null;
- /** @var mixed */
- protected $formula1 = null;
-
- /** @var mixed */
- protected $formula2 = null;
+ protected array $formula = [];
protected array $cfvo = [];
@@ -65,12 +66,10 @@ class Conditional
'showValue' => true,
'directionRtl' => null,
];
- protected bool $gradient = true;
-
- protected bool $showValue = true;
- protected ?bool $directionRtl = null;
- protected int $topRank;
- protected ?bool $topPercent = false;
+ protected array $topOptions = [
+ 'rank' => 0,
+ 'percent' => 0,
+ ];
protected static array $operatorTypes = [
self::OPERATOR_NONE,
@@ -108,58 +107,50 @@ class Conditional
/**
* Create a new Conditional
*/
- public function __construct(string $type, string $operator, $formula, $style = null)
+ public function __construct(string $type, string $operator, $options, $style = null)
{
- if (is_array($formula) && count($formula) === 2) {
- $formula = array_values($formula);
- $formula2 = $formula[1];
- $formula1 = $formula[0];
- }
- else {
- $formula2 = null;
- $formula1 = $formula;
- }
-
if (isset($this->aliases[$operator])) {
$operator = $this->aliases[$operator];
}
- if ($type === self::CONDITION_EXPRESSION) {
- if ($formula1 && $formula1[0] !== '=') {
- $formula1 = '=' . $formula1;
- }
- $operator = '';
+ if (!in_array($operator, self::$operatorTypes)) {
+ ExceptionConditionalFormatting::throwNew('Invalid operator for conditional formatting "' . $operator . '"');
+ }
+
+ if (isset($options['formula'])) {
+ $this->formula = (array)$options['formula'];
}
- elseif ($type === self::CONDITION_COLOR_SCALE || $type === self::CONDITION_DATA_BAR) {
- $this->cfvo = $formula1;
- $formula1 = null;
+ if (isset($options['cfvo'])) {
+ $this->cfvo = $options['cfvo'];
}
- elseif ($type === self::CONDITION_TEXT) {
- $this->text = $formula1;
+ if (isset($options['text'])) {
+ $this->text = $options['text'];
}
- else {
- if (!in_array($operator, self::$operatorTypes)) {
- ExceptionConditionalFormatting::throwNew('Invalid operator for conditional formatting "' . $operator . '"');
+
+ if ($type === self::CONDITION_EXPRESSION) {
+ if ($this->formula && $this->formula[0] !== '=') {
+ $this->formula[0] = '=' . $this->formula[0];
}
}
+ elseif ($type === self::CONDITION_TOP10 && isset($options['options'])) {
+ $this->topOptions = ($options['options']);
+ }
+
if ($style) {
$this->setStyle($style);
}
$this->conditionType = $type;
$this->operator = $operator;
- if (($operator === self::OPERATOR_EQUAL || $operator === self::OPERATOR_NOT_EQUAL) && is_string($formula1) && $formula1) {
- if ($formula1[0] === '=') {
- $this->formula1 = $formula1;
- }
- else {
- $this->text = $formula1;
- $this->formula1 = '"' . $formula1 . '"';
+ if (($operator === self::OPERATOR_EQUAL || $operator === self::OPERATOR_NOT_EQUAL) && isset($this->formula[0]) && is_string($this->formula[0])) {
+ if ($this->formula[0][0] !== '=') {
+ $this->text = $this->formula[0];
+ $this->formula[0] = '"' . $this->formula[0] . '"';
}
}
- else {
- $this->formula1 = (string)$formula1;
+
+ foreach ($this->formula as $n => $formula) {
+ $this->formula[$n] = ($formula === null) ? null : (string)$formula;
}
- $this->formula2 = ($formula2 === null) ? null : (string)$formula2;
}
/**
@@ -173,7 +164,7 @@ public function __construct(string $type, string $operator, $formula, $style = n
*/
public static function make(string $operator, $formula, ?array $style = null): Conditional
{
- return new self(self::CONDITION_CELL, $operator, $formula, $style);
+ return new self(self::CONDITION_CELL, $operator, ['formula' => $formula], $style);
}
/**
@@ -290,7 +281,7 @@ public static function notBetween(array $values, ?array $style = null): Conditio
*/
public static function contains(string $text, ?array $style = null): Conditional
{
- return new self(self::CONDITION_TEXT, self::OPERATOR_CONTAINS, $text, $style);
+ return new self(self::CONDITION_TEXT, self::OPERATOR_CONTAINS, ['text' => $text], $style);
}
/**
@@ -303,7 +294,7 @@ public static function contains(string $text, ?array $style = null): Conditional
*/
public static function notContains(string $text, ?array $style = null): Conditional
{
- return new self(self::CONDITION_TEXT, self::OPERATOR_NOT_CONTAINS, $text, $style);
+ return new self(self::CONDITION_TEXT, self::OPERATOR_NOT_CONTAINS, ['text' => $text], $style);
}
/**
@@ -316,7 +307,7 @@ public static function notContains(string $text, ?array $style = null): Conditio
*/
public static function beginsWith(string $text, ?array $style = null): Conditional
{
- return new self(self::CONDITION_TEXT, self::OPERATOR_BEGINS_WITH, $text, $style);
+ return new self(self::CONDITION_TEXT, self::OPERATOR_BEGINS_WITH, ['text' => $text], $style);
}
/**
@@ -329,7 +320,7 @@ public static function beginsWith(string $text, ?array $style = null): Condition
*/
public static function endsWith(string $text, ?array $style = null): Conditional
{
- return new self(self::CONDITION_TEXT, self::OPERATOR_ENDS_WITH, $text, $style);
+ return new self(self::CONDITION_TEXT, self::OPERATOR_ENDS_WITH, ['text' => $text], $style);
}
/**
@@ -342,7 +333,7 @@ public static function endsWith(string $text, ?array $style = null): Conditional
*/
public static function expression(string $formula, ?array $style = null): Conditional
{
- return new self(self::CONDITION_EXPRESSION, '', $formula, $style);
+ return new self(self::CONDITION_EXPRESSION, '', ['formula' => $formula], $style);
}
/**
@@ -370,16 +361,16 @@ public static function isEmpty(?string $cell = null, ?array $style = null): Cond
*/
public static function colorScale(string $color1, string $color2, ?string $color3 = null): Conditional
{
- $formula = [
+ $cfvo = [
['type' => 'min'],
['type' => 'max'],
];
if ($color3) {
- $formula[] = ['type' => 'percentile', 'val' => 50];
+ $cfvo[] = ['type' => 'percentile', 'val' => 50];
}
- $style = ['color1' => $color1, 'color2' => $color2, 'color3' => $color3];
+ $style = ['color-rgb' => [$color1, $color2, $color3]];
- return new self(self::CONDITION_COLOR_SCALE, '', $formula, $style);
+ return new self(self::CONDITION_COLOR_SCALE, '', ['cfvo' => $cfvo], $style);
}
/**
@@ -389,13 +380,13 @@ public static function colorScale(string $color1, string $color2, ?string $color
*/
public static function colorScaleMax(string $color): Conditional
{
- $formula = [
+ $cfvo = [
['type' => 'min'],
['type' => 'max'],
];
- $style = ['color1' => '#ffffff', 'color2' => $color, 'color3' => null];
+ $style = ['color-rgb' => ['#ffffff', $color]];
- return new self(self::CONDITION_COLOR_SCALE, '', $formula, $style);
+ return new self(self::CONDITION_COLOR_SCALE, '', ['cfvo' => $cfvo], $style);
}
/**
@@ -405,13 +396,13 @@ public static function colorScaleMax(string $color): Conditional
*/
public static function colorScaleMin(string $color): Conditional
{
- $formula = [
+ $cfvo = [
['type' => 'min'],
['type' => 'max'],
];
- $style = ['color1' => $color, 'color2' => '#ffffff', 'color3' => null];
+ $style = ['color-rgb' => [$color, '#ffffff']];
- return new self(self::CONDITION_COLOR_SCALE, '', $formula, $style);
+ return new self(self::CONDITION_COLOR_SCALE, '', ['cfvo' => $cfvo], $style);
}
/**
@@ -424,13 +415,13 @@ public static function colorScaleMin(string $color): Conditional
*/
public static function colorScaleNum(array $values, string $color1, string $color2, ?string $color3 = null): Conditional
{
- $formula = [];
+ $cfvo = [];
foreach ($values as $val) {
- $formula[] = ['type' => 'num', 'val' => $val];
+ $cfvo[] = ['type' => 'num', 'val' => $val];
}
- $style = ['color1' => $color1, 'color2' => $color2, 'color3' => $color3];
+ $style = ['color-rgb' => [$color1, $color2, $color3]];
- return new self(self::CONDITION_COLOR_SCALE, '', $formula, $style);
+ return new self(self::CONDITION_COLOR_SCALE, '', ['cfvo' => $cfvo], $style);
}
/**
@@ -442,13 +433,13 @@ public static function colorScaleNum(array $values, string $color1, string $colo
*/
public static function dataBar(string $color): Conditional
{
- $formula = [
+ $cfvo = [
['type' => 'min', 'val' => null], // 0
['type' => 'max', 'val' => null], // 100
];
- $style = ['color1' => $color];
+ $style = ['color-rgb' => [$color]];
- return new self(self::CONDITION_DATA_BAR, '', $formula, $style);
+ return new self(self::CONDITION_DATA_BAR, '', ['cfvo' => $cfvo], $style);
}
/**
@@ -500,7 +491,11 @@ public static function aboveAverage(array $style): Conditional
public static function belowAverage(array $style): Conditional
{
- return new self(self::CONDITION_BELOW_AVERAGE, '', null, $style);
+ $options = [
+ 'aboveAverage' => 0,
+ ];
+
+ return new self(self::CONDITION_BELOW_AVERAGE, '', $options, $style);
}
public static function uniqueValues(array $style): Conditional
@@ -515,19 +510,19 @@ public static function duplicateValues(array $style): Conditional
public static function top(int $rank, array $style): Conditional
{
- $formula = [
+ $options = [
'rank' => $rank,
- 'percent' => false,
+ 'percent' => 0,
];
- return new self(self::CONDITION_TOP10, '', $formula, $style);
+ return new self(self::CONDITION_TOP10, '', ['options' => $options], $style);
}
public static function topPercent(int $rank, array $style): Conditional
{
$formula = [
'rank' => $rank,
- 'percent' => true,
+ 'percent' => 1,
];
return new self(self::CONDITION_TOP10, '', $formula, $style);
@@ -581,8 +576,8 @@ public function setSqref(Sheet $sheet, string $sqref): Conditional
$dxfId = $sheet->excel->addStyleDxfs($this->getStyle());
$this->setDxfId($dxfId);
$this->priority = count($sheet->getConditionalFormatting()) + 1;
- if ($this->directionRtl === null && $sheet->isRightToLeft()) {
- $this->directionRtl = true;
+ if (isset($this->dataBarOptions['directionRtl']) && $sheet->isRightToLeft()) {
+ $this->dataBarOptions['directionRtl'] = true;
}
return $this;
@@ -646,48 +641,56 @@ public function toXml(int $priority, $formulaConverter = null): string
$xml .= '';
}
}
- if (isset($this->style['color1'])) {
- $xml .= '';
- }
- if (isset($this->style['color2'])) {
- $xml .= '';
- }
- if (isset($this->style['color3'])) {
- $xml .= '';
+ foreach ($this->style['color-rgb'] as $color) {
+ if ($color) {
+ $xml .= '';
+ }
}
- $xml .= '';
- $xml .= 'dataBarOptions['showValue']) ? 'true' : 'false') . '"/>';
- if (!empty($this->dataBarOptions['directionRtl'])) {
- $xml .= '';
+ if ($this->conditionType === self::CONDITION_DATA_BAR) {
+ $xml .= '';
+ $xml .= '';
+ if (!empty($this->dataBarOptions['directionRtl'])) {
+ $xml .= '';
+ }
}
$xml .= '' . $this->conditionType . '>';
$xml .= '';
}
+ elseif ($this->conditionType === self::CONDITION_TOP10) {
+ $xml .= '';
+ }
else {
- $xml .= 'text) {
- $xml .= ' text="' . $this->text . '"';
+ if ($this->conditionType === self::CONDITION_BELOW_AVERAGE) {
+ $type = self::CONDITION_ABOVE_AVERAGE;
+ $aboveAverage = 0;
}
- $xml .= '>';
- if ($this->formula1 !== null && $this->formula1 !== '') {
- if ($this->formula1[0] === '=') {
- $formula = ($formulaConverter ? $formulaConverter($this->formula1, $this->sqref) : substr($this->formula1, 1));
- }
- else {
- $formula = $this->formula1;
- }
- $xml .= '' . $formula . '';
+ else {
+ $type = $this->conditionType;
+ $aboveAverage = null;
}
- if ($this->formula2 !== null && $this->formula2 !== '') {
- if ($this->formula2[0] === '=') {
- $formula = ($formulaConverter ? $formulaConverter($this->formula2, $this->sqref) : substr($this->formula2, 1));
- }
- else {
- $formula = $this->formula2;
+ $attributes = [
+ 'type' => $type,
+ 'dxfId' => $this->dxfId,
+ 'priority' => $priority,
+ 'operator' => $this->operator ?: null,
+ 'text' => $this->text ?: null,
+ 'aboveAverage' => $aboveAverage,
+ ];
+ $xml .= ' $value) {
+ $xml .= ' ' . $attribute . '="' . $value . '"';
+ }
+ $xml .= '>';
+
+ foreach ($this->formula as $formula) {
+ if ($formula !== null && $formula !== '') {
+ if ($formula[0] === '=') {
+ $formula = ($formulaConverter ? $formulaConverter($formula, $this->sqref) : substr($formula, 1));
+ }
+ $xml .= '' . $formula . '';
}
- $xml .= '' . $formula . '';
}
$xml .= '';
}
diff --git a/tests/FastExcelWriterTest.php b/tests/FastExcelWriterTest.php
index 1bd4cf2..0d0ed4c 100644
--- a/tests/FastExcelWriterTest.php
+++ b/tests/FastExcelWriterTest.php
@@ -912,7 +912,29 @@ public function testConditional()
$conditional[] = Conditional::beginsWith('Hello', $style);
$conditional[] = Conditional::endsWith('Hello', $style);
- $conditional[] = Conditional::make('=', '=B10+SUM(C3:D8)', $style);
+ $conditional[] = Conditional::expression('=B10+SUM(C3:D8)', $style);
+ $conditional[] = Conditional::isEmpty('B10', $style);
+
+ $conditional[] = Conditional::colorScale('f00', '0f0');
+ $conditional[] = Conditional::colorScale('f00', '0f0', '00f');
+ $conditional[] = Conditional::colorScaleMax('f00');
+ $conditional[] = Conditional::colorScaleMin('f00');
+ $conditional[] = Conditional::colorScaleNum([10, 20], 'f00', '0f0', '00f');
+
+ $conditional[] = Conditional::dataBar('f00')
+ ->setGradient(false)
+ ->setShowValue(false)
+ ->setDirectionRtl(true);
+
+ $conditional[] = Conditional::aboveAverage($style);
+ $conditional[] = Conditional::belowAverage($style);
+
+ $conditional[] = Conditional::uniqueValues($style);
+ $conditional[] = Conditional::duplicateValues($style);
+
+ $conditional[] = Conditional::top(5, $style);
+ $conditional[] = Conditional::topPercent(5, $style);
+
$sheet->addConditionalFormatting('a1:a' . Excel::MAX_ROW, $conditional);
$this->excelReader = $this->saveCheckRead($excel, $testFileName);