From fdefb8e392cb0a7c0f8b62dd1fb0164b8a7b4236 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 11 Nov 2014 23:18:13 +0000 Subject: [PATCH] Discard Autofilters in Excel2007 Reader when filter range isn't a valid range --- Classes/PHPExcel/Reader/Excel2007.php | 203 +++++++++++----------- Classes/PHPExcel/Worksheet/AutoFilter.php | 6 +- changelog.txt | 2 + 3 files changed, 107 insertions(+), 104 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index afe3b5c8..3b0c1a74 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1006,108 +1006,106 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE } if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { - $autoFilter = $docSheet->getAutoFilter(); - $autoFilterRange = (string) $xmlSheet->autoFilter["ref"]; - if (strpos($autoFilterRange, ':') === false) { - $autoFilterRange = "${autoFilterRange}:${autoFilterRange}"; - } - $autoFilter->setRange($autoFilterRange); + if (strpos($autoFilterRange, ':') !== false) { + $autoFilter = $docSheet->getAutoFilter(); + $autoFilter->setRange($autoFilterRange); - foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { - $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); - // Check for standard filters - if ($filterColumn->filters) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); - $filters = $filterColumn->filters; - if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - '' - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); - } - // Standard filters are always an OR join, so no join rule needs to be set - // Entries can be either filter elements - foreach ($filters->filter as $filterRule) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); - } - // Or Date Group elements - foreach ($filters->dateGroupItem as $dateGroupItem) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - array( - 'year' => (string) $dateGroupItem["year"], - 'month' => (string) $dateGroupItem["month"], - 'day' => (string) $dateGroupItem["day"], - 'hour' => (string) $dateGroupItem["hour"], - 'minute' => (string) $dateGroupItem["minute"], - 'second' => (string) $dateGroupItem["second"], - ), - (string) $dateGroupItem["dateTimeGrouping"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); - } - } - // Check for custom filters - if ($filterColumn->customFilters) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); - $customFilters = $filterColumn->customFilters; - // Custom filters can an AND or an OR join; - // and there should only ever be one or two entries - if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { - $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); - } - foreach ($customFilters->customFilter as $filterRule) { - $column->createRule()->setRule( - (string) $filterRule["operator"], - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); - } - } - // Check for dynamic filters - if ($filterColumn->dynamicFilter) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); - // We should only ever have one dynamic filter - foreach ($filterColumn->dynamicFilter as $filterRule) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"], - (string) $filterRule["type"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); - if (isset($filterRule["val"])) { - $column->setAttribute('val',(string) $filterRule["val"]); - } - if (isset($filterRule["maxVal"])) { - $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); - } - } - } - // Check for dynamic filters - if ($filterColumn->top10) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); - // We should only ever have one top10 filter - foreach ($filterColumn->top10 as $filterRule) { - $column->createRule()->setRule( - (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE - ), - (string) $filterRule["val"], - (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM - ) - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); - } - } + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { + $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); + // Check for standard filters + if ($filterColumn->filters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); + $filters = $filterColumn->filters; + if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + '' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Standard filters are always an OR join, so no join rule needs to be set + // Entries can be either filter elements + foreach ($filters->filter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Or Date Group elements + foreach ($filters->dateGroupItem as $dateGroupItem) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + array( + 'year' => (string) $dateGroupItem["year"], + 'month' => (string) $dateGroupItem["month"], + 'day' => (string) $dateGroupItem["day"], + 'hour' => (string) $dateGroupItem["hour"], + 'minute' => (string) $dateGroupItem["minute"], + 'second' => (string) $dateGroupItem["second"], + ), + (string) $dateGroupItem["dateTimeGrouping"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); + } + } + // Check for custom filters + if ($filterColumn->customFilters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); + $customFilters = $filterColumn->customFilters; + // Custom filters can an AND or an OR join; + // and there should only ever be one or two entries + if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { + $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + } + foreach ($customFilters->customFilter as $filterRule) { + $column->createRule()->setRule( + (string) $filterRule["operator"], + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); + } + } + // Check for dynamic filters + if ($filterColumn->dynamicFilter) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + // We should only ever have one dynamic filter + foreach ($filterColumn->dynamicFilter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"], + (string) $filterRule["type"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); + if (isset($filterRule["val"])) { + $column->setAttribute('val',(string) $filterRule["val"]); + } + if (isset($filterRule["maxVal"])) { + $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); + } + } + } + // Check for dynamic filters + if ($filterColumn->top10) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); + // We should only ever have one top10 filter + foreach ($filterColumn->top10 as $filterRule) { + $column->createRule()->setRule( + (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE + ), + (string) $filterRule["val"], + (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM + ) + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); + } + } + } } } @@ -1584,10 +1582,9 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE $extractedRange = explode(',', $extractedRange); foreach ($extractedRange as $range) { $autoFilterRange = $range; - if (strpos($autoFilterRange, ':') === false) { - $autoFilterRange = "${autoFilterRange}:${autoFilterRange}"; + if (strpos($autoFilterRange, ':') !== false) { + $docSheet->getAutoFilter()->setRange($autoFilterRange); } - $docSheet->getAutoFilter()->setRange($autoFilterRange); } } break; diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index d0fa8b6d..22c35748 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -633,7 +633,11 @@ class PHPExcel_Worksheet_AutoFilter ); } else { // Filter on date group values - $arguments = array(); + $arguments = array( + 'date' => array(), + 'time' => array(), + 'dateTime' => array(), + ); foreach($ruleDataSet as $ruleValue) { $date = $time = ''; if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && diff --git a/changelog.txt b/changelog.txt index 3bb1ab5c..d4e59470 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,10 +33,12 @@ Planned for v1.8.1 - Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - Bugfix: (MBaker) - Fix to getStyle() call for cell object +- Bugfix: (MBaker) - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range - Bugfix: (masanaikeshima) Work Item GH-426 - Pie chart won't work in Excel 2013 - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric +- General: (MBaker) - Default precalculate formulas to false for writers - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions