From e419b92765eb50f06893dba58080a35083d72a4f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 24 Aug 2012 23:38:18 +0100 Subject: [PATCH] Autofilter expressions - TopTen, and minor patches --- Classes/PHPExcel/Worksheet/AutoFilter.php | 71 +++++++++++++------ .../PHPExcel/Writer/Excel2007/Workbook.php | 2 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 2 +- Tests/runall.php | 4 ++ 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 4e7f6542..5d2360aa 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -426,12 +426,6 @@ class PHPExcel_Worksheet_AutoFilter return FALSE; } - private static function _filterTypeTopTenFilters($cellValue,$testSet) - { - echo 'CALLING _filterTypeTopTenFilters',PHP_EOL; - return TRUE; - } - /** * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching * @@ -448,7 +442,7 @@ class PHPExcel_Worksheet_AutoFilter * @param PHPExcel_Worksheet_AutoFilter_Column $filterColumn * @return mixed[] */ - private function _dynamicFilterDateRange($dynamicRuleType, $filterColumn) + private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) { $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); @@ -541,7 +535,7 @@ class PHPExcel_Worksheet_AutoFilter // Set the filter column rule attributes ready for writing $filterColumn->setAttributes(array( 'val' => $val, - 'maxVal', $maxVal + 'maxVal' => $maxVal ) ); @@ -562,6 +556,22 @@ class PHPExcel_Worksheet_AutoFilter ); } + private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { + $range = $columnID.$startRow.':'.$columnID.$endRow; + $dataValues = PHPExcel_Calculation_Functions::flattenArray( + $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) + ); + + $dataValues = array_filter($dataValues); + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { + rsort($dataValues); + } else { + sort($dataValues); + } + + return array_pop(array_slice($dataValues,0,$ruleValue)); + } + /** * Apply the AutoFilter rules to the AutoFilter Range * @@ -573,7 +583,7 @@ class PHPExcel_Worksheet_AutoFilter list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); // The heading row should always be visible - echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; +// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); $columnFilterTests = array(); @@ -717,32 +727,49 @@ class PHPExcel_Worksheet_AutoFilter $ruleValues = array(); $dataRowCount = $rangeEnd[1] - $rangeStart[1]; foreach($rules as $rule) { -var_dump($rule); // We should only ever have one Dynamic Filter Rule anyway $toptenRuleType = $rule->getGrouping(); $ruleValue = $rule->getValue(); + $ruleOperator = $rule->getOperator(); } -var_dump($toptenRuleType); -var_dump($ruleValue); + if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { + $ruleValue = floor($ruleValue * ($dataRowCount / 100)); + } + if ($ruleValue < 1) $ruleValue = 1; + if ($ruleValue > 500) $ruleValue = 500; + + $maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); + + $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $maxVal + ); $columnFilterTests[$columnID] = array( - 'method' => '_filterTypeTopTenFilters', - 'arguments' => $ruleValues + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + $filterColumn->setAttributes( + array('maxVal' => $maxVal) ); break; } } - echo 'Column Filter Test CRITERIA',PHP_EOL; - var_dump($columnFilterTests); - +// echo 'Column Filter Test CRITERIA',PHP_EOL; +// var_dump($columnFilterTests); +// // Execute the column tests for each row in the autoFilter range to determine show/hide, for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { - echo 'Testing Row = ',$row,PHP_EOL; +// echo 'Testing Row = ',$row,PHP_EOL; $result = TRUE; foreach($columnFilterTests as $columnID => $columnFilterTest) { - echo 'Testing cell ',$columnID.$row,PHP_EOL; +// echo 'Testing cell ',$columnID.$row,PHP_EOL; $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); - echo 'Value is ',$cellValue,PHP_EOL; +// echo 'Value is ',$cellValue,PHP_EOL; // Execute the filter test $result = $result && call_user_func_array( @@ -752,13 +779,13 @@ var_dump($ruleValue); $columnFilterTest['arguments'] ) ); - echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; +// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests if (!$result) break; } // Set show/hide for the row based on the result of the autoFilter result - echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; +// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; $this->_workSheet->getRowDimension($row)->setVisible($result); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 67a4dd2f..eefe7f10 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -197,7 +197,7 @@ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_Write $objWriter->writeAttribute('calcId', '124519'); $objWriter->writeAttribute('calcMode', 'auto'); // fullCalcOnLoad isn't needed if we've recalculating for the save - $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? '1' : '0'); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? '0' : '1'); $objWriter->endElement(); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 711d656e..80603777 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -151,7 +151,7 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { $objWriter->writeAttribute('filterMode', 1); -// $pSheet->getAutoFilter()->showHideRows(); + $pSheet->getAutoFilter()->showHideRows(); } // tabColor diff --git a/Tests/runall.php b/Tests/runall.php index 4de37b8e..1e94a2ac 100644 --- a/Tests/runall.php +++ b/Tests/runall.php @@ -28,6 +28,10 @@ /** Error reporting */ error_reporting(E_ALL); +if (PHP_SAPI != 'cli') { + die ('This script executes all tests, and should only be run from the command line'); +} + // List of tests $aTests = array( '01simple.php'