Merge pull request #2049 from xandros15/#984
#984 Add support notContainsText for conditional styles in xlsx
This commit is contained in:
commit
6fb3d840c2
|
|
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
- Implemented URLENCODE() Web Function
|
||||
- Implemented the CHITEST(), CHISQ.DIST() and CHISQ.INV() and equivalent Statistical functions, for both left- and right-tailed distributions.
|
||||
- Support for ActiveSheet and SelectedCells in the ODS Reader and Writer. [PR #1908](https://github.com/PHPOffice/PhpSpreadsheet/pull/1908)
|
||||
- Support for notContainsText Conditional Style in xlsx [Issue #984](https://github.com/PHPOffice/PhpSpreadsheet/issues/984)
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
|
||||
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension;
|
||||
|
|
@ -39,15 +38,7 @@ class ConditionalStyles
|
|||
$conditionals = [];
|
||||
foreach ($xmlSheet->conditionalFormatting as $conditional) {
|
||||
foreach ($conditional->cfRule as $cfRule) {
|
||||
if (
|
||||
((string) $cfRule['type'] == Conditional::CONDITION_NONE
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_CELLIS
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSTEXT
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSBLANKS
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_NOTCONTAINSBLANKS
|
||||
|| (string) $cfRule['type'] == Conditional::CONDITION_EXPRESSION)
|
||||
&& isset($this->dxfs[(int) ($cfRule['dxfId'])])
|
||||
) {
|
||||
if (Conditional::isValidConditionType((string) $cfRule['type']) && isset($this->dxfs[(int) ($cfRule['dxfId'])])) {
|
||||
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
|
||||
} elseif ((string) $cfRule['type'] == Conditional::CONDITION_DATABAR) {
|
||||
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ class Conditional implements IComparable
|
|||
const CONDITION_CONTAINSBLANKS = 'containsBlanks';
|
||||
const CONDITION_NOTCONTAINSBLANKS = 'notContainsBlanks';
|
||||
const CONDITION_DATABAR = 'dataBar';
|
||||
const CONDITION_NOTCONTAINSTEXT = 'notContainsText';
|
||||
|
||||
private const CONDITION_TYPES = [
|
||||
self::CONDITION_CELLIS,
|
||||
self::CONDITION_CONTAINSBLANKS,
|
||||
self::CONDITION_CONTAINSTEXT,
|
||||
self::CONDITION_DATABAR,
|
||||
self::CONDITION_EXPRESSION,
|
||||
self::CONDITION_NONE,
|
||||
self::CONDITION_NOTCONTAINSBLANKS,
|
||||
self::CONDITION_NOTCONTAINSTEXT,
|
||||
];
|
||||
|
||||
// Operator types
|
||||
const OPERATOR_NONE = '';
|
||||
|
|
@ -300,4 +312,12 @@ class Conditional implements IComparable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if param is valid condition type.
|
||||
*/
|
||||
public static function isValidConditionType(string $type): bool
|
||||
{
|
||||
return in_array($type, self::CONDITION_TYPES);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -634,15 +634,21 @@ class Worksheet extends WriterPart
|
|||
|
||||
self::writeAttributeif(
|
||||
$objWriter,
|
||||
($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
|
||||
&& $conditional->getOperatorType() != Conditional::OPERATOR_NONE,
|
||||
(
|
||||
$conditional->getConditionType() === Conditional::CONDITION_CELLIS
|
||||
|| $conditional->getConditionType() === Conditional::CONDITION_CONTAINSTEXT
|
||||
|| $conditional->getConditionType() === Conditional::CONDITION_NOTCONTAINSTEXT
|
||||
) && $conditional->getOperatorType() !== Conditional::OPERATOR_NONE,
|
||||
'operator',
|
||||
$conditional->getOperatorType()
|
||||
);
|
||||
|
||||
self::writeAttributeIf($objWriter, $conditional->getStopIfTrue(), 'stopIfTrue', '1');
|
||||
|
||||
if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT) {
|
||||
if (
|
||||
$conditional->getConditionType() === Conditional::CONDITION_CONTAINSTEXT
|
||||
|| $conditional->getConditionType() === Conditional::CONDITION_NOTCONTAINSTEXT
|
||||
) {
|
||||
self::writeTextCondElements($objWriter, $conditional, $cellCoordinate);
|
||||
} else {
|
||||
self::writeOtherCondElements($objWriter, $conditional, $cellCoordinate);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class ConditionalTest extends AbstractFunctional
|
||||
{
|
||||
/**
|
||||
* Test check if conditional style with type 'notContainsText' works on xlsx.
|
||||
*/
|
||||
public function testConditionalNotContainsText(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLSX/conditionalFormatting3Test.xlsx';
|
||||
$reader = IOFactory::createReader('Xlsx');
|
||||
$spreadsheet = $reader->load($filename);
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$styles = $worksheet->getConditionalStyles('A1:A5');
|
||||
|
||||
self::assertCount(1, $styles);
|
||||
|
||||
/** @var Conditional $notContainsTextStyle */
|
||||
$notContainsTextStyle = $styles[0];
|
||||
self::assertEquals('A', $notContainsTextStyle->getText());
|
||||
self::assertEquals(Conditional::CONDITION_NOTCONTAINSTEXT, $notContainsTextStyle->getConditionType());
|
||||
self::assertEquals(Conditional::OPERATOR_NOTCONTAINS, $notContainsTextStyle->getOperatorType());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class ConditionalTest extends AbstractFunctional
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $prevValue;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->prevValue = Settings::getLibXmlLoaderOptions();
|
||||
|
||||
// Disable validating XML with the DTD
|
||||
Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLibXmlLoaderOptions($this->prevValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test check if conditional style with type 'notContainsText' works on xlsx.
|
||||
*/
|
||||
public function testConditionalNotContainsText(): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
$condition = new Conditional();
|
||||
$condition->setConditionType(Conditional::CONDITION_NOTCONTAINSTEXT);
|
||||
$condition->setOperatorType(Conditional::OPERATOR_NOTCONTAINS);
|
||||
$condition->setText('C');
|
||||
$condition->getStyle()->applyFromArray([
|
||||
'fill' => [
|
||||
'color' => ['argb' => 'FFFFC000'],
|
||||
'fillType' => Fill::FILL_SOLID,
|
||||
],
|
||||
]);
|
||||
$worksheet->setConditionalStyles('A1:A5', [$condition]);
|
||||
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
$writerWorksheet = new Xlsx\Worksheet($writer);
|
||||
$data = $writerWorksheet->writeWorksheet($worksheet, []);
|
||||
$needle = <<<xml
|
||||
<conditionalFormatting sqref="A1:A5"><cfRule type="notContainsText" dxfId="" priority="1" operator="notContains" text="C"><formula>ISERROR(SEARCH("C",A1:A5))</formula></cfRule></conditionalFormatting>
|
||||
xml;
|
||||
self::assertStringContainsString($needle, $data);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Loading…
Reference in New Issue