Issue #5 - Refactor autoFilter range into an autofilter class in

preparation for adding support for autofilter expressions
This commit is contained in:
Mark Baker 2012-07-18 21:12:02 +01:00
parent 59932b0cac
commit 5e44fa2517
9 changed files with 172 additions and 66 deletions

View File

@ -1098,7 +1098,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
} }
if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) {
$docSheet->setAutoFilter((string) $xmlSheet->autoFilter["ref"]); $docSheet->getAutoFilter()->setRange((string) $xmlSheet->autoFilter["ref"]);
} }
if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) {
@ -1560,7 +1560,7 @@ class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
switch ((string)$definedName['name']) { switch ((string)$definedName['name']) {
case '_xlnm._FilterDatabase': case '_xlnm._FilterDatabase':
$docSheet->setAutoFilter($extractedRange); $docSheet->getAutoFilter()->setRange($extractedRange);
break; break;
case '_xlnm.Print_Titles': case '_xlnm.Print_Titles':

View File

@ -312,8 +312,8 @@ class PHPExcel_ReferenceHelper
// Update worksheet: autofilter // Update worksheet: autofilter
if ($pSheet->getAutoFilter() != '') { if ($pSheet->getAutoFilter()->getRange() !== '') {
$pSheet->setAutoFilter( $this->updateCellReference($pSheet->getAutoFilter(), $pBefore, $pNumCols, $pNumRows) ); $pSheet->setAutoFilter( $this->updateCellReference($pSheet->getAutoFilter()->getRange(), $pBefore, $pNumCols, $pNumRows) );
} }

View File

@ -200,11 +200,11 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
private $_protectedCells = array(); private $_protectedCells = array();
/** /**
* Autofilter Range * Autofilter Range and selection
* *
* @var string * @var PHPExcel_Worksheet_AutoFilter
*/ */
private $_autoFilter = ''; private $_autoFilter = NULL;
/** /**
* Freeze pane * Freeze pane
@ -365,7 +365,9 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
$this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null); $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null);
// Default column dimension // Default column dimension
$this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null); $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null);
$this->_autoFilter = new PHPExcel_Worksheet_AutoFilter();
} }
@ -1832,9 +1834,9 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
} }
/** /**
* Get Autofilter Range * Get Autofilter
* *
* @return string * @return PHPExcel_Worksheet_AutoFilter
*/ */
public function getAutoFilter() public function getAutoFilter()
{ {
@ -1842,35 +1844,32 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
} }
/** /**
* Set Autofilter Range * Set AutoFilter
* *
* @param string $pRange Cell range (i.e. A1:E10) * @param PHPExcel_Worksheet_AutoFilter|string $pValue
* @throws Exception * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility
* @return PHPExcel_Worksheet * @throws Exception
* @return PHPExcel_Worksheet
*/ */
public function setAutoFilter($pRange = '') public function setAutoFilter($pValue)
{ {
// Uppercase coordinate if (is_string($pValue)) {
$pRange = strtoupper($pRange); $this->_autoFilter->setRange($pValue);
} elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) {
if (strpos($pRange,':') !== false) { $this->_autoFilter = $pValue;
$this->_autoFilter = $pRange;
$this->_dirty = true;
} else {
throw new Exception('Autofilter must be set on a range of cells.');
} }
return $this; return $this;
} }
/** /**
* Set Autofilter Range by using numeric cell coordinates * Set Autofilter Range by using numeric cell coordinates
* *
* @param int $pColumn1 Numeric column coordinate of the first cell * @param int $pColumn1 Numeric column coordinate of the first cell
* @param int $pRow1 Numeric row coordinate of the first cell * @param int $pRow1 Numeric row coordinate of the first cell
* @param int $pColumn2 Numeric column coordinate of the second cell * @param int $pColumn2 Numeric column coordinate of the second cell
* @param int $pRow2 Numeric row coordinate of the second cell * @param int $pRow2 Numeric row coordinate of the second cell
* @throws Exception * @throws Exception
* @return PHPExcel_Worksheet * @return PHPExcel_Worksheet
*/ */
public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
{ {

View File

@ -0,0 +1,107 @@
<?php
/**
* PHPExcel
*
* Copyright (c) 2006 - 2012 PHPExcel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* @category PHPExcel
* @package PHPExcel_Worksheet
* @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version ##VERSION##, ##DATE##
*/
/**
* PHPExcel_Worksheet_AutoFilter
*
* @category PHPExcel
* @package PHPExcel_Worksheet
* @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
*/
class PHPExcel_Worksheet_AutoFilter
{
/**
* Autofilter Range
*
* @var string
*/
private $_range = '';
/**
* Create a new PHPExcel_Worksheet_AutoFilter
*/
public function __construct($pRange = '')
{
$this->_range = $pRange;
}
/**
* Get AutoFilter Range
*
* @return string
*/
public function getRange() {
return $this->_range;
}
/**
* Set AutoFilter Range
*
* @param string $pRange Cell range (i.e. A1:E10)
* @throws Exception
* @return PHPExcel_Worksheet_AutoFilter
*/
public function setRange($pRange = '') {
// Uppercase coordinate
$pRange = strtoupper($pRange);
if (strpos($pRange,':') !== FALSE) {
$this->_range = $pRange;
} elseif(empty($pRange)) {
$this->_range = '';
} else {
throw new Exception('Autofilter must be set on a range of cells.');
}
return $this;
}
/**
* Implement PHP __clone to create a deep clone, not just a shallow copy.
*/
public function __clone() {
$vars = get_object_vars($this);
foreach ($vars as $key => $value) {
if (is_object($value)) {
$this->$key = clone $value;
} else {
$this->$key = $value;
}
}
}
/**
* toString method replicates previous behavior by returning the range if object is
* referenced as a property of its parent.
*/
public function __toString() {
return $this->_range;
}
}

View File

@ -306,7 +306,7 @@ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_Write
} }
/** /**
* Write Defined Name for autoFilter * Write Defined Name for named range
* *
* @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
* @param PHPExcel_NamedRange $pNamedRange * @param PHPExcel_NamedRange $pNamedRange
@ -347,14 +347,14 @@ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_Write
private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)
{ {
// definedName for autoFilter // definedName for autoFilter
if ($pSheet->getAutoFilter() != '') { if ($pSheet->getAutoFilter()->getRange() !== '') {
$objWriter->startElement('definedName'); $objWriter->startElement('definedName');
$objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); $objWriter->writeAttribute('name', '_xlnm._FilterDatabase');
$objWriter->writeAttribute('localSheetId', $pSheetId); $objWriter->writeAttribute('localSheetId', $pSheetId);
$objWriter->writeAttribute('hidden', '1'); $objWriter->writeAttribute('hidden', '1');
// Create absolute coordinate and write as raw text // Create absolute coordinate and write as raw text
$range = PHPExcel_Cell::splitRange($pSheet->getAutoFilter()); $range = PHPExcel_Cell::splitRange($pSheet->getAutoFilter()->getRange());
$range = $range[0]; $range = $range[0];
// Strip any worksheet ref so we can make the cell ref absolute // Strip any worksheet ref so we can make the cell ref absolute
if (strpos($range[0],'!') !== false) { if (strpos($range[0],'!') !== false) {

View File

@ -725,12 +725,12 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ
*/ */
private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)
{ {
if ($pSheet->getAutoFilter() != '') { if ($pSheet->getAutoFilter()->getRange() !== '') {
// autoFilter // autoFilter
$objWriter->startElement('autoFilter'); $objWriter->startElement('autoFilter');
// Strip any worksheet reference from the filter coordinates // Strip any worksheet reference from the filter coordinates
$range = PHPExcel_Cell::splitRange($pSheet->getAutoFilter()); $range = PHPExcel_Cell::splitRange($pSheet->getAutoFilter()->getRange());
$range = $range[0]; $range = $range[0];
// Strip any worksheet ref // Strip any worksheet ref
if (strpos($range[0],'!') !== false) { if (strpos($range[0],'!') !== false) {

View File

@ -282,7 +282,7 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
$escher = null; $escher = null;
// check if there are any shapes for this sheet // check if there are any shapes for this sheet
if (count($sheet->getDrawingCollection()) == 0 && $sheet->getAutoFilter() == '') { if (count($sheet->getDrawingCollection()) == 0 && $sheet->getAutoFilter()->getRange() === '') {
continue; continue;
} }
@ -358,43 +358,43 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
$spgrContainer->addChild($spContainer); $spgrContainer->addChild($spContainer);
} }
// AutoFilters // AutoFilters
if($sheet->getAutoFilter() != ''){ if($sheet->getAutoFilter()->getRange() !== ''){
$rangeBounds = PHPExcel_Cell::rangeBoundaries($sheet->getAutoFilter()); $rangeBounds = PHPExcel_Cell::rangeBoundaries($sheet->getAutoFilter()->getRange());
$iNumColStart = $rangeBounds[0][0]; $iNumColStart = $rangeBounds[0][0];
$iNumColEnd = $rangeBounds[1][0]; $iNumColEnd = $rangeBounds[1][0];
$iInc = $iNumColStart; $iInc = $iNumColStart;
while($iInc <= $iNumColEnd){ while($iInc <= $iNumColEnd){
++$countShapes[$sheetIndex]; ++$countShapes[$sheetIndex];
// create an Drawing Object for the dropdown // create an Drawing Object for the dropdown
$oDrawing = new PHPExcel_Worksheet_BaseDrawing(); $oDrawing = new PHPExcel_Worksheet_BaseDrawing();
// get the coordinates of drawing // get the coordinates of drawing
$cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1];
$oDrawing->setCoordinates($cDrawing); $oDrawing->setCoordinates($cDrawing);
$oDrawing->setWorksheet($sheet); $oDrawing->setWorksheet($sheet);
// add the shape // add the shape
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
// set the shape type // set the shape type
$spContainer->setSpType(0x00C9); $spContainer->setSpType(0x00C9);
// set the shape flag // set the shape flag
$spContainer->setSpFlag(0x01); $spContainer->setSpFlag(0x01);
// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
$reducedSpId = $countShapes[$sheetIndex]; $reducedSpId = $countShapes[$sheetIndex];
$spId = $reducedSpId $spId = $reducedSpId
| ($sheet->getParent()->getIndex($sheet) + 1) << 10; | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
$spContainer->setSpId($spId); $spContainer->setSpId($spId);
// keep track of last reducedSpId // keep track of last reducedSpId
$lastReducedSpId = $reducedSpId; $lastReducedSpId = $reducedSpId;
// keep track of last spId // keep track of last spId
$lastSpId = $spId; $lastSpId = $spId;
$spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping
$spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape
$spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest
@ -411,7 +411,7 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
$spContainer->setEndCoordinates($endCoordinates); $spContainer->setEndCoordinates($endCoordinates);
$spContainer->setEndOffsetX(0); $spContainer->setEndOffsetX(0);
$spContainer->setEndOffsetY(0); $spContainer->setEndOffsetY(0);
$spgrContainer->addChild($spContainer); $spgrContainer->addChild($spContainer);
$iInc++; $iInc++;
} }

View File

@ -779,16 +779,16 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
$chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true));
} }
} }
// write autofilters, if any // write autofilters, if any
for ($i = 0; $i < $total_worksheets; ++$i) { for ($i = 0; $i < $total_worksheets; ++$i) {
$sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter();
if($sheetAutoFilter != ''){ if($sheetAutoFilter->getRange() !== ''){
$rangeBounds = PHPExcel_Cell::rangeBoundaries($sheetAutoFilter); $rangeBounds = PHPExcel_Cell::rangeBoundaries($sheetAutoFilter->getRange());
//Autofilter built in name //Autofilter built in name
$name = pack('C', 0x0D); $name = pack('C', 0x0D);
$chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true));
} }
} }
@ -830,7 +830,7 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
return $header . $data; return $header . $data;
} }
/** /**
* Write a short NAME record * Write a short NAME record
* *
@ -842,10 +842,10 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
* */ * */
private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){
$record = 0x0018; $record = 0x0018;
// option flags // option flags
$options = ($isHidden ? 0x21 : 0x00); $options = ($isHidden ? 0x21 : 0x00);
$extra = pack('Cvvvvv', $extra = pack('Cvvvvv',
0x3B, 0x3B,
$sheetIndex - 1, $sheetIndex - 1,
@ -853,17 +853,17 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
$rangeBounds[1][1] - 1, $rangeBounds[1][1] - 1,
$rangeBounds[0][0] - 1, $rangeBounds[0][0] - 1,
$rangeBounds[1][0] - 1); $rangeBounds[1][0] - 1);
// size of the formula (in bytes) // size of the formula (in bytes)
$sz = strlen($extra); $sz = strlen($extra);
// combine the parts // combine the parts
$data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0)
. $name . $extra; . $name . $extra;
$length = strlen($data); $length = strlen($data);
$header = pack('vv', $record, $length); $header = pack('vv', $record, $length);
return $header . $data; return $header . $data;
} }

View File

@ -390,8 +390,8 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
$this->_writeColinfo($this->_colinfo[$i]); $this->_writeColinfo($this->_colinfo[$i]);
} }
} }
if ($_phpSheet->getAutoFilter() != '') { if ($_phpSheet->getAutoFilter()->getRange() !== '') {
// Write AUTOFILTERINFO // Write AUTOFILTERINFO
$this->_writeAutoFilterInfo(); $this->_writeAutoFilterInfo();
} }
@ -2048,15 +2048,15 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
private function _writeAutoFilterInfo(){ private function _writeAutoFilterInfo(){
$record = 0x009D; // Record identifier $record = 0x009D; // Record identifier
$length = 0x0002; // Bytes to follow $length = 0x0002; // Bytes to follow
$rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()); $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange());
$iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0];
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
$data = pack("v", $iNumFilters); $data = pack("v", $iNumFilters);
$this->_append($header . $data); $this->_append($header . $data);
} }
/** /**
* Write the GUTS BIFF record. This is used to configure the gutter margins * Write the GUTS BIFF record. This is used to configure the gutter margins
* where Excel outline symbols are displayed. The visibility of the gutters is * where Excel outline symbols are displayed. The visibility of the gutters is
@ -2737,7 +2737,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
, 0 // reserved , 0 // reserved
, 0 // reserved , 0 // reserved
); );
// Add ftSbs Scroll bar subobject // Add ftSbs Scroll bar subobject
$objData .= pack('vv', 0x00C, 0x0014); $objData .= pack('vv', 0x00C, 0x0014);
$objData .= pack('H*', '0000000000000000640001000A00000010000100'); $objData .= pack('H*', '0000000000000000640001000A00000010000100');
@ -2759,7 +2759,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
, 0 // reserved , 0 // reserved
); );
} }
// ftEnd // ftEnd
$objData .= $objData .=
pack('vv' pack('vv'