mirror of
https://github.com/retailcrm/PHPExcel.git
synced 2024-11-25 23:06:03 +03:00
ADDED : Implement support for AutoFilter in PHPExcel_Writer_Excel5
This commit is contained in:
parent
2cbc3d24ab
commit
e1104f1862
@ -55,6 +55,13 @@ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer
|
||||
*/
|
||||
private $_spType;
|
||||
|
||||
/**
|
||||
* Shape flag
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_spFlag;
|
||||
|
||||
/**
|
||||
* Shape index (usually group shape has index 0, and the rest: 1,2,3...)
|
||||
*
|
||||
@ -171,6 +178,26 @@ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer
|
||||
return $this->_spType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape flag
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setSpFlag($value)
|
||||
{
|
||||
$this->_spFlag = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shape flag
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSpFlag()
|
||||
{
|
||||
return $this->_spFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape index
|
||||
*
|
||||
|
@ -282,7 +282,7 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
|
||||
$escher = null;
|
||||
|
||||
// check if there are any shapes for this sheet
|
||||
if (count($sheet->getDrawingCollection()) == 0) {
|
||||
if (count($sheet->getDrawingCollection()) == 0 && $sheet->getAutoFilter() == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -322,6 +322,8 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
|
||||
|
||||
// set the shape type
|
||||
$spContainer->setSpType(0x004B);
|
||||
// set the shape flag
|
||||
$spContainer->setSpFlag(0x02);
|
||||
|
||||
// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
|
||||
$reducedSpId = $countShapes[$sheetIndex];
|
||||
@ -356,6 +358,64 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter
|
||||
|
||||
$spgrContainer->addChild($spContainer);
|
||||
}
|
||||
|
||||
// AutoFilters
|
||||
if($sheet->getAutoFilter() != ''){
|
||||
$rangeBounds = PHPExcel_Cell::rangeBoundaries($sheet->getAutoFilter());
|
||||
$iNumColStart = $rangeBounds[0][0];
|
||||
$iNumColEnd = $rangeBounds[1][0];
|
||||
|
||||
$iInc = $iNumColStart;
|
||||
while($iInc <= $iNumColEnd){
|
||||
++$countShapes[$sheetIndex];
|
||||
|
||||
// create an Drawing Object for the dropdown
|
||||
$oDrawing = new PHPExcel_Worksheet_BaseDrawing();
|
||||
// get the coordinates of drawing
|
||||
$cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1];
|
||||
$oDrawing->setCoordinates($cDrawing);
|
||||
$oDrawing->setWorksheet($sheet);
|
||||
|
||||
// add the shape
|
||||
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
|
||||
// set the shape type
|
||||
$spContainer->setSpType(0x00C9);
|
||||
// set the shape flag
|
||||
$spContainer->setSpFlag(0x01);
|
||||
|
||||
// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
|
||||
$reducedSpId = $countShapes[$sheetIndex];
|
||||
$spId = $reducedSpId
|
||||
| ($sheet->getParent()->getIndex($sheet) + 1) << 10;
|
||||
$spContainer->setSpId($spId);
|
||||
|
||||
// keep track of last reducedSpId
|
||||
$lastReducedSpId = $reducedSpId;
|
||||
|
||||
// keep track of last spId
|
||||
$lastSpId = $spId;
|
||||
|
||||
$spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping
|
||||
$spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape
|
||||
$spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest
|
||||
$spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash
|
||||
$spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint
|
||||
|
||||
// set coordinates and offsets, client anchor
|
||||
$endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1));
|
||||
$endCoordinates .= $rangeBounds[0][1] + 1;
|
||||
|
||||
$spContainer->setStartCoordinates($cDrawing);
|
||||
$spContainer->setStartOffsetX(0);
|
||||
$spContainer->setStartOffsetY(0);
|
||||
$spContainer->setEndCoordinates($endCoordinates);
|
||||
$spContainer->setEndOffsetX(0);
|
||||
$spContainer->setEndOffsetY(0);
|
||||
|
||||
$spgrContainer->addChild($spContainer);
|
||||
$iInc++;
|
||||
}
|
||||
}
|
||||
|
||||
// identifier clusters, used for workbook Escher object
|
||||
$this->_IDCLs[$dgId] = $lastReducedSpId;
|
||||
|
@ -52,7 +52,13 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
*/
|
||||
private $_spOffsets;
|
||||
|
||||
|
||||
/**
|
||||
* Shape types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_spTypes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -81,6 +87,7 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
$writer = new PHPExcel_Writer_Excel5_Escher($dgContainer);
|
||||
$this->_data = $writer->close();
|
||||
$this->_spOffsets = $writer->getSpOffsets();
|
||||
$this->_spTypes = $writer->getSpTypes();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -307,13 +314,15 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
|
||||
// get the shape offsets relative to the spgrContainer record
|
||||
$spOffsets = $writer->getSpOffsets();
|
||||
|
||||
$spTypes = $writer->getSpTypes();
|
||||
|
||||
// save the shape offsets relative to dgContainer
|
||||
foreach ($spOffsets as & $spOffset) {
|
||||
$spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)
|
||||
}
|
||||
|
||||
$this->_spOffsets = $spOffsets;
|
||||
$this->_spTypes = $spTypes;
|
||||
}
|
||||
|
||||
// write the record
|
||||
@ -339,6 +348,7 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
// initialize spape offsets
|
||||
$totalSize = 8;
|
||||
$spOffsets = array();
|
||||
$spTypes = array();
|
||||
|
||||
// treat the inner data
|
||||
foreach ($this->_object->getChildren() as $spContainer) {
|
||||
@ -349,6 +359,8 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
// save the shape offsets (where new shape records begin)
|
||||
$totalSize += strlen($spData);
|
||||
$spOffsets[] = $totalSize;
|
||||
|
||||
$spTypes = array_merge($spTypes, $writer->getSpTypes());
|
||||
}
|
||||
|
||||
// write the record
|
||||
@ -364,6 +376,7 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
|
||||
$this->_data = $header . $innerData;
|
||||
$this->_spOffsets = $spOffsets;
|
||||
$this->_spTypes = $spTypes;
|
||||
break;
|
||||
|
||||
case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer':
|
||||
@ -386,6 +399,7 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
|
||||
$data .= $header . pack('VVVV', 0,0,0,0);
|
||||
}
|
||||
$this->_spTypes[] = ($this->_object->getSpType());
|
||||
|
||||
// write the shape record
|
||||
$recVer = 0x2;
|
||||
@ -450,10 +464,10 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
// end offsetY
|
||||
$endOffsetY = $this->_object->getEndOffsetY();
|
||||
|
||||
$clientAnchorData = pack('vvvvvvvvv', 0x02,
|
||||
$clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(),
|
||||
$c1, $startOffsetX, $r1, $startOffsetY,
|
||||
$c2, $endOffsetX, $r2, $endOffsetY);
|
||||
|
||||
|
||||
$length = strlen($clientAnchorData);
|
||||
|
||||
$recVerInstance = $recVer;
|
||||
@ -509,4 +523,15 @@ class PHPExcel_Writer_Excel5_Escher
|
||||
return $this->_spOffsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shape types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSpTypes()
|
||||
{
|
||||
return $this->_spTypes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -779,6 +779,19 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true));
|
||||
}
|
||||
}
|
||||
|
||||
// write autofilters, if any
|
||||
for ($i = 0; $i < $total_worksheets; ++$i) {
|
||||
$sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter();
|
||||
if($sheetAutoFilter != ''){
|
||||
$rangeBounds = PHPExcel_Cell::rangeBoundaries($sheetAutoFilter);
|
||||
|
||||
//Autofilter built in name
|
||||
$name = pack('C', 0x0D);
|
||||
|
||||
$chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true));
|
||||
}
|
||||
}
|
||||
|
||||
return $chunk;
|
||||
}
|
||||
@ -817,6 +830,42 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
|
||||
return $header . $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a short NAME record
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global
|
||||
* @param int[][] $range rangeboundaries
|
||||
* @param bool $isHidden
|
||||
* @return string Complete binary record data
|
||||
* */
|
||||
private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){
|
||||
$record = 0x0018;
|
||||
|
||||
// option flags
|
||||
$options = ($isHidden ? 0x21 : 0x00);
|
||||
|
||||
$extra = pack('Cvvvvv',
|
||||
0x3B,
|
||||
$sheetIndex - 1,
|
||||
$rangeBounds[0][1] - 1,
|
||||
$rangeBounds[1][1] - 1,
|
||||
$rangeBounds[0][0] - 1,
|
||||
$rangeBounds[1][0] - 1);
|
||||
|
||||
// size of the formula (in bytes)
|
||||
$sz = strlen($extra);
|
||||
|
||||
// combine the parts
|
||||
$data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0)
|
||||
. $name . $extra;
|
||||
$length = strlen($data);
|
||||
|
||||
$header = pack('vv', $record, $length);
|
||||
|
||||
return $header . $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the CODEPAGE biff record.
|
||||
|
@ -390,6 +390,11 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$this->_writeColinfo($this->_colinfo[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($_phpSheet->getAutoFilter() != '') {
|
||||
// Write AUTOFILTERINFO
|
||||
$this->_writeAutoFilterInfo();
|
||||
}
|
||||
|
||||
// Write sheet dimensions
|
||||
$this->_writeDimensions();
|
||||
@ -2017,7 +2022,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$fPrintGrid = $this->_phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag
|
||||
|
||||
$header = pack("vv", $record, $length);
|
||||
$data = pack("v", $fPrintGrid);
|
||||
$data = pack("v", $fPrintGrid);
|
||||
$this->_append($header . $data);
|
||||
}
|
||||
|
||||
@ -2037,6 +2042,21 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$this->_append($header . $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet.
|
||||
*/
|
||||
private function _writeAutoFilterInfo(){
|
||||
$record = 0x009D; // Record identifier
|
||||
$length = 0x0002; // Bytes to follow
|
||||
|
||||
$rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter());
|
||||
$iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0];
|
||||
|
||||
$header = pack("vv", $record, $length);
|
||||
$data = pack("v", $iNumFilters);
|
||||
$this->_append($header . $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -2681,7 +2701,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$writer = new PHPExcel_Writer_Excel5_Escher($this->_escher);
|
||||
$data = $writer->close();
|
||||
$spOffsets = $writer->getSpOffsets();
|
||||
|
||||
$spTypes = $writer->getSpTypes();
|
||||
// write the neccesary MSODRAWING, OBJ records
|
||||
|
||||
// split the Escher stream
|
||||
@ -2692,7 +2712,6 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$record = 0x00EC; // Record identifier
|
||||
|
||||
// chunk of Escher stream for one shape
|
||||
|
||||
$dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]);
|
||||
|
||||
$length = strlen($dataChunk);
|
||||
@ -2705,17 +2724,42 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
|
||||
$objData = '';
|
||||
|
||||
// ftCmo
|
||||
$objData .=
|
||||
pack('vvvvvVVV'
|
||||
, 0x0015 // 0x0015 = ftCmo
|
||||
, 0x0012 // length of ftCmo data
|
||||
, 0x0008 // object type, 0x0008 = picture
|
||||
, $i // object id number, Excel seems to use 1-based index, local for the sheet
|
||||
, 0x6011 // option flags, 0x6011 is what OpenOffice.org uses
|
||||
, 0 // reserved
|
||||
, 0 // reserved
|
||||
, 0 // reserved
|
||||
);
|
||||
if($spTypes[$i] == 0x00C9){
|
||||
// Add ftCmo (common object data) subobject
|
||||
$objData .=
|
||||
pack('vvvvvVVV'
|
||||
, 0x0015 // 0x0015 = ftCmo
|
||||
, 0x0012 // length of ftCmo data
|
||||
, 0x0014 // object type, 0x0014 = filter
|
||||
, $i // object id number, Excel seems to use 1-based index, local for the sheet
|
||||
, 0x2101 // option flags, 0x2001 is what OpenOffice.org uses
|
||||
, 0 // reserved
|
||||
, 0 // reserved
|
||||
, 0 // reserved
|
||||
);
|
||||
|
||||
// Add ftSbs Scroll bar subobject
|
||||
$objData .= pack('vv', 0x00C, 0x0014);
|
||||
$objData .= pack('H*', '0000000000000000640001000A00000010000100');
|
||||
// Add ftLbsData (List box data) subobject
|
||||
$objData .= pack('vv', 0x0013, 0x1FEE);
|
||||
$objData .= pack('H*', '00000000010001030000020008005700');
|
||||
}
|
||||
else {
|
||||
// Add ftCmo (common object data) subobject
|
||||
$objData .=
|
||||
pack('vvvvvVVV'
|
||||
, 0x0015 // 0x0015 = ftCmo
|
||||
, 0x0012 // length of ftCmo data
|
||||
, 0x0008 // object type, 0x0008 = picture
|
||||
, $i // object id number, Excel seems to use 1-based index, local for the sheet
|
||||
, 0x6011 // option flags, 0x6011 is what OpenOffice.org uses
|
||||
, 0 // reserved
|
||||
, 0 // reserved
|
||||
, 0 // reserved
|
||||
);
|
||||
}
|
||||
|
||||
// ftEnd
|
||||
$objData .=
|
||||
pack('vv'
|
||||
|
@ -29,6 +29,7 @@ Fixed in develop branch:
|
||||
Current options are tcPDF, mPDF, DomPDF
|
||||
tcPDF Library has now been removed from the deployment bundle
|
||||
- Feature: (MBaker) Initial version of HTML Reader
|
||||
- Feature: (Progi1984) & (blazzy) Work items 9605 - Implement support for AutoFilter in PHPExcel_Writer_Excel5
|
||||
- Bugfix: (cyberconte) Patch 12318 - OOCalc cells containing <text:span> inside the <text:p> tag
|
||||
- Bugfix: (schir1964) Fix to listWorksheetInfo() method for OOCalc Reader
|
||||
- Bugfix: (MBaker) Support for "e" (epoch) date format mask
|
||||
|
Loading…
Reference in New Issue
Block a user