Skip to content

Commit 9f5a472

Browse files
astronatiPowerKiKi
authored andcommitted
Fix XLSX file loading with autofilter containing '$'
The `setRange` method of the `Xlsx/AutoFilter` class expects a filter range format like "A1:E10". The returned value from `$this->worksheetXml->autoFilter['ref']` could contain "$" and returning a value like "$A$1:$E$10". Fixes #687 Fixes #1325 Closes #1326
1 parent fb37938 commit 9f5a472

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2121
- Fix for issue by removing test code mistakenly left in [#1328](https://github.com/PHPOffice/PhpSpreadsheet/pull/1328)
2222
- Fix for Xls writer wrong selected cells and active sheet [#1256](https://github.com/PHPOffice/PhpSpreadsheet/pull/1256)
2323
- Fix active cell when freeze pane is used [#1323](https://github.com/PHPOffice/PhpSpreadsheet/pull/1323)
24+
- Fix XLSX file loading with autofilter containing '$' [#1326](https://github.com/PHPOffice/PhpSpreadsheet/pull/1326)
2425

2526
## [1.10.1] - 2019-12-02
2627

src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public function __construct(Worksheet $workSheet, \SimpleXMLElement $worksheetXm
2020

2121
public function load()
2222
{
23-
$autoFilterRange = (string) $this->worksheetXml->autoFilter['ref'];
23+
// Remove all "$" in the auto filter range
24+
$autoFilterRange = preg_replace('/\$/', '', $this->worksheetXml->autoFilter['ref']);
2425
if (strpos($autoFilterRange, ':') !== false) {
2526
$this->readAutoFilter($autoFilterRange, $this->worksheetXml);
2627
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
4+
5+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\AutoFilter;
6+
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter as WorksheetAutoFilter;
7+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class AutoFilterTest extends TestCase
11+
{
12+
private function getWorksheetInstance()
13+
{
14+
return $this->getMockBuilder(Worksheet::class)
15+
->disableOriginalConstructor()
16+
->getMock();
17+
}
18+
19+
private function getXMLInstance($ref)
20+
{
21+
return new \SimpleXMLElement(
22+
'<?xml version="1.0" encoding="UTF-8"?>' .
23+
'<root>' .
24+
'<autoFilter ref="' . $ref . '"></autoFilter>' .
25+
'</root>'
26+
);
27+
}
28+
29+
private function getAutoFilterInstance()
30+
{
31+
$instance = $this->getMockBuilder(WorksheetAutoFilter::class)
32+
->disableOriginalConstructor()
33+
->getMock();
34+
35+
return $instance;
36+
}
37+
38+
public function loadDataProvider()
39+
{
40+
return [
41+
['$B3$E8', 0, 'B3E8'],
42+
['$B3:$E8', 1, 'B3:E8'],
43+
];
44+
}
45+
46+
/**
47+
* @dataProvider loadDataProvider
48+
*
49+
* @param string $ref
50+
* @param int $expectedReadAutoFilterCalled
51+
* @param string $expectedRef
52+
*/
53+
public function testLoad($ref, $expectedReadAutoFilterCalled, $expectedRef)
54+
{
55+
$worksheetAutoFilter = $this->getAutoFilterInstance();
56+
$worksheetAutoFilter->expects($this->exactly($expectedReadAutoFilterCalled ? 1 : 0))
57+
->method('setRange')
58+
->with($expectedRef);
59+
60+
$worksheet = $this->getWorksheetInstance();
61+
$worksheet->expects($this->exactly($expectedReadAutoFilterCalled ? 1 : 0))
62+
->method('getAutoFilter')
63+
->willReturn($worksheetAutoFilter);
64+
65+
$autoFilter = new AutoFilter($worksheet, $this->getXMLInstance($ref));
66+
67+
$autoFilter->load();
68+
}
69+
}

0 commit comments

Comments
 (0)