Skip to content

Commit bbc069e

Browse files
committed
Tweaks to Xml and Xls Readers
1 parent 38c4ce4 commit bbc069e

File tree

5 files changed

+46
-26
lines changed

5 files changed

+46
-26
lines changed

src/PhpSpreadsheet/Reader/Xls/DataValidationHelper.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Reader\Xls;
44

5+
use PhpOffice\PhpSpreadsheet\Cell\AddressRange;
56
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
67
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
78
use PhpOffice\PhpSpreadsheet\Reader\Xls;
9+
use PhpOffice\PhpSpreadsheet\Writer\Xls\Worksheet as XlsWorksheet;
810

911
class DataValidationHelper extends Xls
1012
{
@@ -175,8 +177,27 @@ protected function readDataValidation2(Xls $xls): void
175177
// offset: var; size: var; cell range address list with
176178
$cellRangeAddressList = Biff8::readBIFF8CellRangeAddressList(substr($recordData, $offset));
177179
$cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses'];
180+
$maxRow = (string) AddressRange::MAX_ROW;
181+
$maxCol = AddressRange::MAX_COLUMN;
182+
$maxXlsRow = (string) XlsWorksheet::MAX_XLS_ROW;
183+
$maxXlsColumnString = (string) XlsWorksheet::MAX_XLS_COLUMN_STRING;
178184

179185
foreach ($cellRangeAddresses as $cellRange) {
186+
$cellRange = preg_replace(
187+
[
188+
"/([a-z]+)1:([a-z]+)$maxXlsRow/i",
189+
"/([a-z]+\\d+):([a-z]+)$maxXlsRow/i",
190+
"/A(\\d+):$maxXlsColumnString(\\d+)/i",
191+
"/([a-z]+\\d+):$maxXlsColumnString(\\d+)/i",
192+
],
193+
[
194+
'$1:$2',
195+
'$1:${2}' . $maxRow,
196+
'$1:$2',
197+
'$1:' . $maxCol . '$2',
198+
],
199+
$cellRange
200+
) ?? $cellRange;
180201
$objValidation = new DataValidation();
181202
$objValidation->setType($type);
182203
$objValidation->setErrorStyle($errorStyle);

src/PhpSpreadsheet/Reader/Xml/DataValidations.php

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace PhpOffice\PhpSpreadsheet\Reader\Xml;
44

55
use PhpOffice\PhpSpreadsheet\Cell\AddressHelper;
6-
use PhpOffice\PhpSpreadsheet\Cell\AddressRange;
76
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
87
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
98
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces;
@@ -84,27 +83,25 @@ public function loadDataValidations(SimpleXMLElement $worksheet, Spreadsheet $sp
8483
$this->thisColumn = (int) $selectionMatches[2];
8584
$combinedCells .= "$separator$cell";
8685
$separator = ' ';
87-
} elseif (preg_match('/^C(\d+)$/', (string) $range, $selectionMatches) === 1) {
86+
} elseif (preg_match('/^C(\d+)(:C(]\\d+))?$/', (string) $range, $selectionMatches) === 1) {
8887
// column
89-
$firstCell = Coordinate::stringFromColumnIndex((int) $selectionMatches[1])
90-
. '1';
91-
$cell = $firstCell
92-
. ':'
93-
. Coordinate::stringFromColumnIndex((int) $selectionMatches[1])
94-
. ((string) AddressRange::MAX_ROW);
95-
$this->thisColumn = (int) $selectionMatches[1];
88+
$firstCol = $selectionMatches[1];
89+
$firstColString = Coordinate::stringFromColumnIndex((int) $firstCol);
90+
$lastCol = $selectionMatches[3] ?? $firstCol;
91+
$lastColString = Coordinate::stringFromColumnIndex((int) $lastCol);
92+
$firstCell = "{$firstColString}1";
93+
$cell = "$firstColString:$lastColString";
94+
$this->thisColumn = (int) $firstCol;
9695
$sheet->getCell($firstCell);
9796
$combinedCells .= "$separator$cell";
9897
$separator = ' ';
99-
} elseif (preg_match('/^R(\d+)$/', (string) $range, $selectionMatches)) {
98+
} elseif (preg_match('/^R(\\d+)(:R(]\\d+))?$/', (string) $range, $selectionMatches)) {
10099
// row
101-
$firstCell = 'A'
102-
. $selectionMatches[1];
103-
$cell = $firstCell
104-
. ':'
105-
. AddressRange::MAX_COLUMN
106-
. $selectionMatches[1];
107-
$this->thisRow = (int) $selectionMatches[1];
100+
$firstRow = $selectionMatches[1];
101+
$lastRow = $selectionMatches[3] ?? $firstRow;
102+
$firstCell = "A$firstRow";
103+
$cell = "$firstRow:$lastRow";
104+
$this->thisRow = (int) $firstRow;
108105
$sheet->getCell($firstCell);
109106
$combinedCells .= "$separator$cell";
110107
$separator = ' ';

src/PhpSpreadsheet/Worksheet/Worksheet.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,10 +3262,12 @@ public function getHyperlinkCollection(): array
32623262
*/
32633263
public function getDataValidation(string $cellCoordinate): DataValidation
32643264
{
3265+
// return data validation if we already have one
32653266
if (isset($this->dataValidationCollection[$cellCoordinate])) {
32663267
return $this->dataValidationCollection[$cellCoordinate];
32673268
}
32683269

3270+
// or if cell is part of a data validation range
32693271
foreach ($this->dataValidationCollection as $key => $dataValidation) {
32703272
$keyParts = explode(' ', $key);
32713273
foreach ($keyParts as $keyPart) {

tests/PhpSpreadsheetTests/Reader/Xml/DataValidationsTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function testValidation(): void
2222
$sheet = $spreadsheet->getActiveSheet();
2323
$assertions = $this->validationAssertions();
2424
$validation = $sheet->getCell('A1')->getDataValidation();
25-
self::assertSame('A1:A1048576', $validation->getSqref());
25+
self::assertSame('A:A', $validation->getSqref());
2626
$validation = $sheet->getCell('B3')->getDataValidation();
2727
self::assertSame('B2:B1048576', $validation->getSqref());
2828

@@ -42,14 +42,14 @@ public function testValidationWholeRow(): void
4242
$spreadsheet = $reader->load($this->filename2);
4343
$sheet = $spreadsheet->getActiveSheet();
4444
$collection = $sheet->getDataValidationCollection();
45-
self::assertSame(['A1', 'A1:XFD1'], array_keys($collection));
45+
self::assertSame(['A1', '1:1'], array_keys($collection));
4646
$dv = $collection['A1'];
4747
self::assertSame('"Item A,Item B,Item D"', $dv->getFormula1());
4848
self::assertSame('warn', $dv->getErrorStyle());
4949
self::assertFalse($dv->getShowDropDown());
5050
self::assertFalse($dv->getShowErrorMessage());
5151

52-
$dv = $collection['A1:XFD1'];
52+
$dv = $collection['1:1'];
5353
self::assertSame('"Item A,Item B,Item C"', $dv->getFormula1());
5454
self::assertSame('stop', $dv->getErrorStyle());
5555
self::assertTrue($dv->getShowDropDown());
@@ -67,7 +67,7 @@ public function testValidationXlsx(): void
6767
$sheet = $spreadsheet->getActiveSheet();
6868
$assertions = $this->validationAssertions();
6969
$validation = $sheet->getCell('A1')->getDataValidation();
70-
self::assertSame('A1:A1048576', $validation->getSqref());
70+
self::assertSame('A:A', $validation->getSqref());
7171
$validation = $sheet->getCell('B3')->getDataValidation();
7272
self::assertSame('B2:B1048576', $validation->getSqref());
7373

@@ -87,10 +87,10 @@ public function testValidationXls(): void
8787

8888
$sheet = $spreadsheet->getActiveSheet();
8989
$assertions = $this->validationAssertions();
90-
//$validation = $sheet->getCell('A1')->getDataValidation();
91-
//self::assertSame('A1:A1048576', $validation->getSqref());
92-
//$validation = $sheet->getCell('B3')->getDataValidation();
93-
//self::assertSame('B2:B1048576', $validation->getSqref());
90+
$validation = $sheet->getCell('A1')->getDataValidation();
91+
self::assertSame('A:A', $validation->getSqref(), 'limited number of rows in Xls');
92+
$validation = $sheet->getCell('B3')->getDataValidation();
93+
self::assertSame('B2:B1048576', $validation->getSqref());
9494

9595
foreach ($assertions as $title => $assertion) {
9696
$sheet->getCell($assertion[1])->setValue($assertion[2]);

tests/PhpSpreadsheetTests/Writer/Xls/DataValidationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function testWholeRow(): void
3333
$robj = $this->writeAndReload($spreadsheet, 'Xls');
3434
$spreadsheet->disconnectWorksheets();
3535
$sheet0 = $robj->getActiveSheet();
36-
self::assertSame(['H1', 'C1:F1', 'A1:IV1'], array_keys($sheet0->getDataValidationCollection()));
36+
self::assertSame(['H1', 'C1:F1', '1:1'], array_keys($sheet0->getDataValidationCollection()));
3737
self::assertTrue(true);
3838
$robj->disconnectWorksheets();
3939
}

0 commit comments

Comments
 (0)