Merge branch 'master' into Xls-Reader-Conditional-Formatting

This commit is contained in:
Mark Baker 2022-03-19 16:21:14 +01:00 committed by GitHub
commit 23e2d702ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 686 additions and 113 deletions

View File

@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added
- Implementation of the ISREF() information function.
- Implementation of the UNIQUE() Lookup/Reference (array) function
- Implementation of the ISREF() Information function.
- Added support for reading "formatted" numeric values from Csv files; although default behaviour of reading these values as strings is preserved.
(i.e a value of "12,345.67" can be read as numeric `1235.67`, not simply as a string `"12,345.67"`, if the `castFormattedNumberToNumeric()` setting is enabled.
@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
This is determined by the Calculation Engine locale setting.
(i.e. `"Vrai"` wil be converted to a boolean `true` if the Locale is set to `fr`.)
- Allow `psr/simple-cache` 2.x
### Deprecated

View File

@ -75,7 +75,7 @@
"markbaker/matrix": "^3.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0"
"psr/simple-cache": "^1.0 || ^2.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",

2
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9dadb265f548dd4ddbfd2ee97d5a6aa6",
"content-hash": "ed42c40a4281d97171980367f24d0a25",
"packages": [
{
"name": "ezyang/htmlpurifier",

View File

@ -2300,16 +2300,6 @@ parameters:
count: 2
path: src/PhpSpreadsheet/Reader/Xls.php
-
message: "#^Parameter \\#1 \\$errorStyle of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setErrorStyle\\(\\) expects string, int\\|string given\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls.php
-
message: "#^Parameter \\#1 \\$operator of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setOperator\\(\\) expects string, int\\|string given\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls.php
-
message: "#^Parameter \\#1 \\$showSummaryBelow of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:setShowSummaryBelow\\(\\) expects bool, int given\\.$#"
count: 1
@ -2320,11 +2310,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Reader/Xls.php
-
message: "#^Parameter \\#1 \\$type of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setType\\(\\) expects string, int\\|string given\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls.php
-
message: "#^Parameter \\#2 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter\\:\\:readCell\\(\\) expects int, string given\\.$#"
count: 1
@ -5484,3 +5469,4 @@ parameters:
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Xlfn\\:\\:addXlfn\\(\\) should return string but returns string\\|null\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php

View File

@ -2583,7 +2583,7 @@ class Calculation
],
'UNIQUE' => [
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
'functionCall' => [Functions::class, 'DUMMY'],
'functionCall' => [LookupRef\Unique::class, 'unique'],
'argumentCount' => '1+',
],
'UPPER' => [

View File

@ -47,7 +47,7 @@ class ErrorValue
return false;
}
return in_array($value, ExcelError::$errorCodes);
return in_array($value, ExcelError::$errorCodes) || $value === ExcelError::CALC();
}
/**

View File

@ -22,6 +22,7 @@ class ExcelError
'num' => '#NUM!',
'na' => '#N/A',
'gettingdata' => '#GETTING_DATA',
'spill' => '#SPILL!',
];
/**
@ -45,6 +46,10 @@ class ExcelError
++$i;
}
if ($value === self::CALC()) {
return 14;
}
return self::NA();
}
@ -127,10 +132,20 @@ class ExcelError
/**
* DIV0.
*
* @return string #Not Yet Implemented
* @return string #DIV/0!
*/
public static function DIV0()
{
return self::$errorCodes['divisionbyzero'];
}
/**
* CALC.
*
* @return string #Not Yet Implemented
*/
public static function CALC()
{
return '#CALC!';
}
}

View File

@ -0,0 +1,141 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
class Unique
{
/**
* UNIQUE
* The UNIQUE function searches for value either from a one-row or one-column range or from an array.
*
* @param mixed $lookupVector The range of cells being searched
* @param mixed $byColumn Whether the uniqueness should be determined by row (the default) or by column
* @param mixed $exactlyOnce Whether the function should return only entries that occur just once in the list
*
* @return mixed The unique values from the search range
*/
public static function unique($lookupVector, $byColumn = false, $exactlyOnce = false)
{
if (!is_array($lookupVector)) {
// Scalars are always returned "as is"
return $lookupVector;
}
$byColumn = (bool) $byColumn;
$exactlyOnce = (bool) $exactlyOnce;
return ($byColumn === true)
? self::uniqueByColumn($lookupVector, $exactlyOnce)
: self::uniqueByRow($lookupVector, $exactlyOnce);
}
/**
* @return mixed
*/
private static function uniqueByRow(array $lookupVector, bool $exactlyOnce)
{
// When not $byColumn, we count whole rows or values, not individual values
// so implode each row into a single string value
array_walk(
$lookupVector,
function (array &$value): void {
$value = implode(chr(0x00), $value);
}
);
$result = self::countValuesCaseInsensitive($lookupVector);
if ($exactlyOnce === true) {
$result = self::exactlyOnceFilter($result);
}
if (count($result) === 0) {
return ExcelError::CALC();
}
$result = array_keys($result);
// restore rows from their strings
array_walk(
$result,
function (string &$value): void {
$value = explode(chr(0x00), $value);
}
);
return (count($result) === 1) ? array_pop($result) : $result;
}
/**
* @return mixed
*/
private static function uniqueByColumn(array $lookupVector, bool $exactlyOnce)
{
$flattenedLookupVector = Functions::flattenArray($lookupVector);
if (count($lookupVector, COUNT_RECURSIVE) > count($flattenedLookupVector, COUNT_RECURSIVE) + 1) {
// We're looking at a full column check (multiple rows)
$transpose = Matrix::transpose($lookupVector);
$result = self::uniqueByRow($transpose, $exactlyOnce);
return (is_array($result)) ? Matrix::transpose($result) : $result;
}
$result = self::countValuesCaseInsensitive($flattenedLookupVector);
if ($exactlyOnce === true) {
$result = self::exactlyOnceFilter($result);
}
if (count($result) === 0) {
return ExcelError::CALC();
}
$result = array_keys($result);
return $result;
}
private static function countValuesCaseInsensitive(array $caseSensitiveLookupValues): array
{
$caseInsensitiveCounts = array_count_values(
array_map(
function (string $value) {
return StringHelper::strToUpper($value);
},
$caseSensitiveLookupValues
)
);
$caseSensitiveCounts = [];
foreach ($caseInsensitiveCounts as $caseInsensitiveKey => $count) {
if (is_numeric($caseInsensitiveKey)) {
$caseSensitiveCounts[$caseInsensitiveKey] = $count;
} else {
foreach ($caseSensitiveLookupValues as $caseSensitiveValue) {
if ($caseInsensitiveKey === StringHelper::strToUpper($caseSensitiveValue)) {
$caseSensitiveCounts[$caseSensitiveValue] = $count;
break;
}
}
}
}
return $caseSensitiveCounts;
}
private static function exactlyOnceFilter(array $values): array
{
return array_filter(
$values,
function ($value) {
return $value === 1;
}
);
}
}

View File

@ -4788,57 +4788,11 @@ class Xls extends BaseReader
// bit: 0-3; mask: 0x0000000F; type
$type = (0x0000000F & $options) >> 0;
switch ($type) {
case 0x00:
$type = DataValidation::TYPE_NONE;
break;
case 0x01:
$type = DataValidation::TYPE_WHOLE;
break;
case 0x02:
$type = DataValidation::TYPE_DECIMAL;
break;
case 0x03:
$type = DataValidation::TYPE_LIST;
break;
case 0x04:
$type = DataValidation::TYPE_DATE;
break;
case 0x05:
$type = DataValidation::TYPE_TIME;
break;
case 0x06:
$type = DataValidation::TYPE_TEXTLENGTH;
break;
case 0x07:
$type = DataValidation::TYPE_CUSTOM;
break;
}
$type = Xls\DataValidationHelper::type($type);
// bit: 4-6; mask: 0x00000070; error type
$errorStyle = (0x00000070 & $options) >> 4;
switch ($errorStyle) {
case 0x00:
$errorStyle = DataValidation::STYLE_STOP;
break;
case 0x01:
$errorStyle = DataValidation::STYLE_WARNING;
break;
case 0x02:
$errorStyle = DataValidation::STYLE_INFORMATION;
break;
}
$errorStyle = Xls\DataValidationHelper::errorStyle($errorStyle);
// bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list)
// I have only seen cases where this is 1
@ -4858,39 +4812,10 @@ class Xls extends BaseReader
// bit: 20-23; mask: 0x00F00000; condition operator
$operator = (0x00F00000 & $options) >> 20;
switch ($operator) {
case 0x00:
$operator = DataValidation::OPERATOR_BETWEEN;
$operator = Xls\DataValidationHelper::operator($operator);
break;
case 0x01:
$operator = DataValidation::OPERATOR_NOTBETWEEN;
break;
case 0x02:
$operator = DataValidation::OPERATOR_EQUAL;
break;
case 0x03:
$operator = DataValidation::OPERATOR_NOTEQUAL;
break;
case 0x04:
$operator = DataValidation::OPERATOR_GREATERTHAN;
break;
case 0x05:
$operator = DataValidation::OPERATOR_LESSTHAN;
break;
case 0x06:
$operator = DataValidation::OPERATOR_GREATERTHANOREQUAL;
break;
case 0x07:
$operator = DataValidation::OPERATOR_LESSTHANOREQUAL;
break;
if ($type === null || $errorStyle === null || $operator === null) {
return;
}
// offset: 4; size: var; title of the prompt box

View File

@ -0,0 +1,72 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
class DataValidationHelper
{
/**
* @var array<int, string>
*/
private static $types = [
0x00 => DataValidation::TYPE_NONE,
0x01 => DataValidation::TYPE_WHOLE,
0x02 => DataValidation::TYPE_DECIMAL,
0x03 => DataValidation::TYPE_LIST,
0x04 => DataValidation::TYPE_DATE,
0x05 => DataValidation::TYPE_TIME,
0x06 => DataValidation::TYPE_TEXTLENGTH,
0x07 => DataValidation::TYPE_CUSTOM,
];
/**
* @var array<int, string>
*/
private static $errorStyles = [
0x00 => DataValidation::STYLE_STOP,
0x01 => DataValidation::STYLE_WARNING,
0x02 => DataValidation::STYLE_INFORMATION,
];
/**
* @var array<int, string>
*/
private static $operators = [
0x00 => DataValidation::OPERATOR_BETWEEN,
0x01 => DataValidation::OPERATOR_NOTBETWEEN,
0x02 => DataValidation::OPERATOR_EQUAL,
0x03 => DataValidation::OPERATOR_NOTEQUAL,
0x04 => DataValidation::OPERATOR_GREATERTHAN,
0x05 => DataValidation::OPERATOR_LESSTHAN,
0x06 => DataValidation::OPERATOR_GREATERTHANOREQUAL,
0x07 => DataValidation::OPERATOR_LESSTHANOREQUAL,
];
public static function type(int $type): ?string
{
if (isset(self::$types[$type])) {
return self::$types[$type];
}
return null;
}
public static function errorStyle(int $errorStyle): ?string
{
if (isset(self::$errorStyles[$errorStyle])) {
return self::$errorStyles[$errorStyle];
}
return null;
}
public static function operator(int $operator): ?string
{
if (isset(self::$operators[$operator])) {
return self::$operators[$operator];
}
return null;
}
}

View File

@ -0,0 +1,157 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PHPUnit\Framework\TestCase;
class UniqueTest extends TestCase
{
/**
* @dataProvider uniqueTestProvider
*/
public function testUnique(array $expectedResult, array $lookupRef, bool $byColumn = false, bool $exactlyOnce = false): void
{
$result = LookupRef\Unique::unique($lookupRef, $byColumn, $exactlyOnce);
self::assertEquals($expectedResult, $result);
}
public function testUniqueException(): void
{
$rowLookupData = [
['Andrew', 'Brown'],
['Betty', 'Johnson'],
['Betty', 'Johnson'],
['Andrew', 'Brown'],
['David', 'White'],
['Andrew', 'Brown'],
['David', 'White'],
];
$columnLookupData = [
['PHP', 'Rocks', 'php', 'rocks'],
];
$result = LookupRef\Unique::unique($rowLookupData, false, true);
self::assertEquals(ExcelError::CALC(), $result);
$result = LookupRef\Unique::unique($columnLookupData, true, true);
self::assertEquals(ExcelError::CALC(), $result);
}
public function testUniqueWithScalar(): void
{
$lookupData = 123;
$result = LookupRef\Unique::unique($lookupData);
self::assertSame($lookupData, $result);
}
public function uniqueTestProvider(): array
{
return [
[
[['Red'], ['Green'], ['Blue'], ['Orange']],
[
['Red'],
['Green'],
['Green'],
['Blue'],
['Blue'],
['Orange'],
['Green'],
['Blue'],
['Red'],
],
],
[
[['Red'], ['Green'], ['Blue'], ['Orange']],
[
['Red'],
['Green'],
['GrEEn'],
['Blue'],
['BLUE'],
['Orange'],
['GReeN'],
['blue'],
['RED'],
],
],
[
['Orange'],
[
['Red'],
['Green'],
['Green'],
['Blue'],
['Blue'],
['Orange'],
['Green'],
['Blue'],
['Red'],
],
false,
true,
],
[
['Andrew', 'Betty', 'Robert', 'David'],
[['Andrew', 'Betty', 'Robert', 'Andrew', 'Betty', 'Robert', 'David', 'Andrew']],
true,
],
[
['David'],
[['Andrew', 'Betty', 'Robert', 'Andrew', 'Betty', 'Robert', 'David', 'Andrew']],
true,
true,
],
[
[1, 1, 2, 2, 3],
[[1, 1, 2, 2, 3]],
],
[
[1, 2, 3],
[[1, 1, 2, 2, 3]],
true,
],
[
[
[1, 1, 2, 3],
[1, 2, 2, 3],
],
[
[1, 1, 2, 2, 3],
[1, 2, 2, 2, 3],
],
true,
],
[
[
['Andrew', 'Brown'],
['Betty', 'Johnson'],
['David', 'White'],
],
[
['Andrew', 'Brown'],
['Betty', 'Johnson'],
['Betty', 'Johnson'],
['Andrew', 'Brown'],
['David', 'White'],
['Andrew', 'Brown'],
['David', 'White'],
],
],
[
[[1.2], [2.1], [2.2], [3.0]],
[
[1.2],
[1.2],
[2.1],
[2.2],
[3.0],
],
],
];
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PHPUnit\Framework\TestCase;
class DataValidationTest extends TestCase
{
/**
* @var Worksheet
*/
protected $sheet;
protected function setUp(): void
{
$filename = 'tests/data/Reader/XLS/DataValidation.xls';
$reader = new Xls();
$spreadsheet = $reader->load($filename);
$this->sheet = $spreadsheet->getActiveSheet();
}
/**
* @dataProvider dataValidationProvider
*/
public function testDataValidation(string $expectedRange, array $expectedRule): void
{
$hasDataValidation = $this->sheet->dataValidationExists($expectedRange);
self::assertTrue($hasDataValidation);
$dataValidation = $this->sheet->getDataValidation($expectedRange);
self::assertSame($expectedRule['type'], $dataValidation->getType());
self::assertSame($expectedRule['operator'], $dataValidation->getOperator());
self::assertSame($expectedRule['formula'], $dataValidation->getFormula1());
}
public function dataValidationProvider(): array
{
return [
[
'B2',
[
'type' => DataValidation::TYPE_WHOLE,
'operator' => DataValidation::OPERATOR_GREATERTHANOREQUAL,
'formula' => '18',
],
],
[
'B3',
[
'type' => DataValidation::TYPE_LIST,
'operator' => DataValidation::OPERATOR_BETWEEN,
'formula' => '"Blocked,Pending,Approved"',
],
],
];
}
}

View File

@ -298,6 +298,83 @@ class ReferenceHelperTest extends TestCase
self::assertSame(['A3' => 'https://phpspreadsheet.readthedocs.io/en/latest/'], $hyperlinks);
}
public function testInsertRowsWithDataValidation(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
$cellAddress = 'E5';
$this->setDataValidation($sheet, $cellAddress);
$sheet->insertNewRowBefore(2, 2);
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
self::assertTrue($sheet->getCell('E7')->hasDataValidation());
}
public function testDeleteRowsWithDataValidation(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
$cellAddress = 'E5';
$this->setDataValidation($sheet, $cellAddress);
$sheet->removeRow(2, 2);
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
self::assertTrue($sheet->getCell('E3')->hasDataValidation());
}
public function testDeleteColumnsWithDataValidation(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
$cellAddress = 'E5';
$this->setDataValidation($sheet, $cellAddress);
$sheet->removeColumn('B', 2);
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
self::assertTrue($sheet->getCell('C5')->hasDataValidation());
}
public function testInsertColumnsWithDataValidation(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
$cellAddress = 'E5';
$this->setDataValidation($sheet, $cellAddress);
$sheet->insertNewColumnBefore('C', 2);
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
self::assertTrue($sheet->getCell('G5')->hasDataValidation());
}
private function setDataValidation(Worksheet $sheet, string $cellAddress): void
{
$validation = $sheet->getCell($cellAddress)
->getDataValidation();
$validation->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST);
$validation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION);
$validation->setAllowBlank(false);
$validation->setShowInputMessage(true);
$validation->setShowErrorMessage(true);
$validation->setShowDropDown(true);
$validation->setErrorTitle('Input error');
$validation->setError('Value is not in list.');
$validation->setPromptTitle('Pick from list');
$validation->setPrompt('Please pick a value from the drop-down list.');
$validation->setFormula1('$A5:$A8');
}
public function testInsertRowsWithConditionalFormatting(): void
{
$spreadsheet = new Spreadsheet();
@ -306,6 +383,92 @@ class ReferenceHelperTest extends TestCase
$sheet->getCell('H5')->setValue(5);
$cellRange = 'C3:F7';
$this->setConditionalFormatting($sheet, $cellRange);
$sheet->insertNewRowBefore(4, 2);
$styles = $sheet->getConditionalStylesCollection();
// verify that the conditional range has been updated
self::assertSame('C3:F9', array_keys($styles)[0]);
// verify that the conditions have been updated
foreach ($styles as $style) {
foreach ($style as $conditions) {
self::assertSame('$H$7', $conditions->getConditions()[0]);
}
}
}
public function testInsertColumnssWithConditionalFormatting(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
$sheet->getCell('H5')->setValue(5);
$cellRange = 'C3:F7';
$this->setConditionalFormatting($sheet, $cellRange);
$sheet->insertNewColumnBefore('C', 2);
$styles = $sheet->getConditionalStylesCollection();
// verify that the conditional range has been updated
self::assertSame('E3:H7', array_keys($styles)[0]);
// verify that the conditions have been updated
foreach ($styles as $style) {
foreach ($style as $conditions) {
self::assertSame('$J$5', $conditions->getConditions()[0]);
}
}
}
public function testDeleteRowsWithConditionalFormatting(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
$sheet->getCell('H5')->setValue(5);
$cellRange = 'C3:F7';
$this->setConditionalFormatting($sheet, $cellRange);
$sheet->removeRow(4, 2);
$styles = $sheet->getConditionalStylesCollection();
// verify that the conditional range has been updated
self::assertSame('C3:F5', array_keys($styles)[0]);
// verify that the conditions have been updated
foreach ($styles as $style) {
foreach ($style as $conditions) {
self::assertSame('$H$5', $conditions->getConditions()[0]);
}
}
}
public function testDeleteColumnsWithConditionalFormatting(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
$sheet->getCell('H5')->setValue(5);
$cellRange = 'C3:F7';
$this->setConditionalFormatting($sheet, $cellRange);
$sheet->removeColumn('D', 2);
$styles = $sheet->getConditionalStylesCollection();
// verify that the conditional range has been updated
self::assertSame('C3:D7', array_keys($styles)[0]);
// verify that the conditions have been updated
foreach ($styles as $style) {
foreach ($style as $conditions) {
self::assertSame('$F$5', $conditions->getConditions()[0]);
}
}
}
private function setConditionalFormatting(Worksheet $sheet, string $cellRange): void
{
$conditionalStyles = [];
$wizardFactory = new Wizard($cellRange);
/** @var Wizard\CellValue $cellWizard */
@ -320,19 +483,55 @@ class ReferenceHelperTest extends TestCase
$cellWizard->lessThan('$H$5', Wizard::VALUE_TYPE_CELL);
$conditionalStyles[] = $cellWizard->getConditional();
$spreadsheet->getActiveSheet()
->getStyle($cellWizard->getCellRange())
$sheet->getStyle($cellWizard->getCellRange())
->setConditionalStyles($conditionalStyles);
$sheet->insertNewRowBefore(4, 2);
}
$styles = $sheet->getConditionalStylesCollection();
// verify that the conditional range has been updated
self::assertSame('C3:F9', array_keys($styles)[0]);
// verify that the conditions have been updated
foreach ($styles as $style) {
foreach ($style as $conditions) {
self::assertSame('$H$7', $conditions->getConditions()[0]);
}
}
public function testInsertRowsWithPrintArea(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getPageSetup()->setPrintArea('A1:J10');
$sheet->insertNewRowBefore(2, 2);
$printArea = $sheet->getPageSetup()->getPrintArea();
self::assertSame('A1:J12', $printArea);
}
public function testInsertColumnsWithPrintArea(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getPageSetup()->setPrintArea('A1:J10');
$sheet->insertNewColumnBefore('B', 2);
$printArea = $sheet->getPageSetup()->getPrintArea();
self::assertSame('A1:L10', $printArea);
}
public function testDeleteRowsWithPrintArea(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getPageSetup()->setPrintArea('A1:J10');
$sheet->removeRow(2, 2);
$printArea = $sheet->getPageSetup()->getPrintArea();
self::assertSame('A1:J8', $printArea);
}
public function testDeleteColumnsWithPrintArea(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getPageSetup()->setPrintArea('A1:J10');
$sheet->removeColumn('B', 2);
$printArea = $sheet->getPageSetup()->getPrintArea();
self::assertSame('A1:H10', $printArea);
}
}

View File

@ -53,4 +53,12 @@ return [
7,
'#N/A',
],
[
9,
'#SPILL!',
],
[
14,
'#CALC!',
],
];

View File

@ -49,6 +49,14 @@ return [
true,
'#N/A',
],
[
true,
'#SPILL!',
],
[
true,
'#CALC!',
],
[
false,
'TRUE',

Binary file not shown.