Bugfix: Workitem 14374 - BUG : Excel5 and setReadFilter ?
Modifications to Worksheet's to_array() method to handle worksheets partially loaded with a readFilter by switching to iterators git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@61913 2327b42d-5241-43d6-9e2a-de5ac946f064
This commit is contained in:
parent
2ec5a8b3bb
commit
9946aa1595
|
@ -2118,48 +2118,47 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
|
|||
* @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
|
||||
* @param boolean $calculateFormulas Should formulas be calculated?
|
||||
* @param boolean $formatData Should formatting be applied to cell values?
|
||||
* @param boolean $returnColumnRef False - Return columns indexed by number (0..x)
|
||||
* True - Return columns indexed by column ID (A..x)
|
||||
* @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
|
||||
* True - Return rows and columns indexed by their actual row and column IDs
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnColumnRef = false) {
|
||||
public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
|
||||
// Returnvalue
|
||||
$returnValue = array();
|
||||
|
||||
// Garbage collect...
|
||||
$this->garbageCollect();
|
||||
|
||||
// Get worksheet dimension
|
||||
$dimension = explode(':', $this->calculateWorksheetDimension());
|
||||
$dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]);
|
||||
$dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1;
|
||||
$dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]);
|
||||
$dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1;
|
||||
|
||||
// Loop through cells
|
||||
for ($row = $dimension[0][1]; $row <= $dimension[1][1]; ++$row) {
|
||||
for ($column = $dimension[0][0]; $column <= $dimension[1][0]; ++$column) {
|
||||
$columnRef = ($returnColumnRef) ? PHPExcel_Cell::stringFromColumnIndex($column) : $column;
|
||||
// Loop through rows
|
||||
$r = -2;
|
||||
$rowIterator = $this->getRowIterator();
|
||||
foreach ($rowIterator as $row) {
|
||||
++$r;
|
||||
$cellIterator = $row->getCellIterator();
|
||||
$cellIterator->setIterateOnlyExistingCells(true); // Loop through each cell in the current row
|
||||
$c = -1;
|
||||
foreach ($cellIterator as $cell) {
|
||||
++$c;
|
||||
$rRef = ($returnCellRef) ? $cell->getRow() : $r;
|
||||
$cRef = ($returnCellRef) ? $cell->getColumn() : $c;
|
||||
if (!is_null($cell)) {
|
||||
// Cell exists?
|
||||
if ($this->cellExistsByColumnAndRow($column, $row)) {
|
||||
$cell = $this->getCellByColumnAndRow($column, $row);
|
||||
|
||||
if ($cell->getValue() instanceof PHPExcel_RichText) {
|
||||
$returnValue[$row][$columnRef] = $cell->getValue()->getPlainText();
|
||||
$returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();
|
||||
} else {
|
||||
if ($calculateFormulas) {
|
||||
$returnValue[$row][$columnRef] = $cell->getCalculatedValue();
|
||||
$returnValue[$rRef][$cRef] = $cell->getCalculatedValue();
|
||||
} else {
|
||||
$returnValue[$row][$columnRef] = $cell->getValue();
|
||||
$returnValue[$rRef][$cRef] = $cell->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if ($formatData) {
|
||||
$style = $this->_parent->getCellXfByIndex($cell->getXfIndex());
|
||||
$returnValue[$row][$columnRef] = PHPExcel_Style_NumberFormat::toFormattedString($returnValue[$row][$columnRef], $style->getNumberFormat()->getFormatCode());
|
||||
$returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString($returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode());
|
||||
}
|
||||
} else {
|
||||
$returnValue[$row][$columnRef] = $nullValue;
|
||||
$returnValue[$rRef][$cRef] = $nullValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -478,6 +478,8 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
|
|||
// Add part 3 of the Workbook globals
|
||||
$this->_data .= $part3;
|
||||
|
||||
$this->_data .= $this->_createPropertySets();
|
||||
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
|
@ -1423,6 +1425,185 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
|
|||
}
|
||||
}
|
||||
|
||||
private function _createPropertySets()
|
||||
{
|
||||
$stream = pack('v*', unpack('C*', "\5SummaryInformation"));
|
||||
$summary = $this->_create_summary_property_set();
|
||||
|
||||
$stream = pack('v*', unpack('C*', "\5DocumentSummaryInformation"));
|
||||
$summary = $this->_create_doc_summary_property_set();
|
||||
}
|
||||
|
||||
private function _create_summary_property_set()
|
||||
{
|
||||
$properties = array();
|
||||
if ($this->_phpExcel->getProperties()->getTitle() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getTitle(), 'id' => 0x02);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getSubject() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getSubject(), 'id' => 0x03);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getCreator() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getCreator(), 'id' => 0x04);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getKeywords() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getKeywords(), 'id' => 0x05);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getDescription() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getDescription(), 'id' => 0x06);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getLastModifiedBy() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getLastModifiedBy(), 'id' => 0x08);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getCreated() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getCreated(), 'id' => 0x0C);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getModified() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getModified(), 'id' => 0x0D);
|
||||
}
|
||||
|
||||
$propertyCount = count($properties);
|
||||
if ($propertyCount > 0) {
|
||||
$byte_order = pack('v', 0xFFFE);
|
||||
$version = pack('v', 0x0000);
|
||||
$system_id = pack('V', 0x00020105);
|
||||
$class_id = pack('H*', '00000000000000000000000000000000');
|
||||
$num_property_sets = pack('V', 0x0001);
|
||||
$format_id = pack('H*', 'E0859FF2F94F6810AB9108002B27B3D9');
|
||||
$offset = pack('V', 0x0030);
|
||||
$num_property = pack('V', $propertyCount);
|
||||
$property_offsets = '';
|
||||
|
||||
# Create the property set data block and calculate the offsets into it.
|
||||
list($property_data, $offsets) = $this->_pack_property_data($properties);
|
||||
|
||||
# Create the property type and offsets based on the previous calculation.
|
||||
for ($i = 0; $i < $propertyCount; ++$i) {
|
||||
$property_offsets .= pack('VV', $properties[$i][0], $offsets[$i]);
|
||||
}
|
||||
|
||||
# Size of $size (4 bytes) + $num_property (4 bytes) + the data structures.
|
||||
$size = 8 + strlen($property_offsets) + strlen($property_data);
|
||||
$size = pack('V', $size);
|
||||
|
||||
return $byte_order .
|
||||
$version .
|
||||
$system_id .
|
||||
$class_id .
|
||||
$num_property_sets .
|
||||
$format_id .
|
||||
$offset .
|
||||
$size .
|
||||
$num_property .
|
||||
$property_offsets .
|
||||
$property_data;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private function _create_doc_summary_property_set()
|
||||
{
|
||||
$properties = array();
|
||||
if ($this->_phpExcel->getProperties()->getCategory() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getCategory(), 'id' => 0x02);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getManager() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getManager(), 'id' => 0x0E);
|
||||
}
|
||||
if ($this->_phpExcel->getProperties()->getCompany() > '') {
|
||||
$properties[] = array( 'value' => $this->_phpExcel->getProperties()->getCompany(), 'id' => 0x0F);
|
||||
}
|
||||
|
||||
$propertyCount = count($properties);
|
||||
if ($propertyCount > 0) {
|
||||
$byte_order = pack('v', 0xFFFE);
|
||||
$version = pack('v', 0x0000);
|
||||
$system_id = pack('V', 0x00020105);
|
||||
$class_id = pack('H*', '00000000000000000000000000000000');
|
||||
$num_property_sets = pack('V', 0x0002);
|
||||
$format_id_0 = pack('H*', '02D5CDD59C2E1B10939708002B2CF9AE');
|
||||
$format_id_1 = pack('H*', '05D5CDD59C2E1B10939708002B2CF9AE');
|
||||
$offset_0 = pack('V', 0x0044);
|
||||
$num_property_0 = pack('V', $propertyCount);
|
||||
$property_offsets_0 = '';
|
||||
|
||||
# Create the property set data block and calculate the offsets into it.
|
||||
list($property_data_0, $offsets) = $this->_pack_property_data($properties);
|
||||
|
||||
# Create the property type and offsets based on the previous calculation.
|
||||
for ($i = 0; $i < $propertyCount; ++$i) {
|
||||
$property_offsets_0 .= pack('VV', $properties[$i][0], $offsets[$i]);
|
||||
}
|
||||
|
||||
# Size of $size (4 bytes) + $num_property (4 bytes) + the data structures.
|
||||
$data_len = 8 + length($property_offsets_0) + length($property_data_0);
|
||||
$size_0 = pack('V', $data_len);
|
||||
|
||||
# The second property set offset is at the end of the first property set.
|
||||
$offset_1 = pack('V', 0x0044 + $data_len);
|
||||
|
||||
# We will use a static property set stream rather than try to generate it.
|
||||
$property_data_1 . pack('H*', 0x98 . 0x00 . 0x00 . 0x00 . 0x03 . 0x00 . 0x00 . 0x00 . 0x00 . 0x00 . 0x00 . 0x00 . 0x20 . 0x00 . 0x00 . 0x00 .
|
||||
0x01 . 0x00 . 0x00 . 0x00 . 0x36 . 0x00 . 0x00 . 0x00 . 0x02 . 0x00 . 0x00 . 0x00 . 0x3E . 0x00 . 0x00 . 0x00 .
|
||||
0x01 . 0x00 . 0x00 . 0x00 . 0x02 . 0x00 . 0x00 . 0x00 . 0x0A . 0x00 . 0x00 . 0x00 . 0x5F . 0x50 . 0x49 . 0x44 .
|
||||
0x5F . 0x47 . 0x55 . 0x49 . 0x44 . 0x00 . 0x02 . 0x00 . 0x00 . 0x00 . 0xE4 . 0x04 . 0x00 . 0x00 . 0x41 . 0x00 .
|
||||
0x00 . 0x00 . 0x4E . 0x00 . 0x00 . 0x00 . 0x7B . 0x00 . 0x31 . 0x00 . 0x36 . 0x00 . 0x43 . 0x00 . 0x34 . 0x00 .
|
||||
0x42 . 0x00 . 0x38 . 0x00 . 0x33 . 0x00 . 0x42 . 0x00 . 0x2D . 0x00 . 0x39 . 0x00 . 0x36 . 0x00 . 0x35 . 0x00 .
|
||||
0x46 . 0x00 . 0x2D . 0x00 . 0x34 . 0x00 . 0x42 . 0x00 . 0x32 . 0x00 . 0x31 . 0x00 . 0x2D . 0x00 . 0x39 . 0x00 .
|
||||
0x30 . 0x00 . 0x33 . 0x00 . 0x44 . 0x00 . 0x2D . 0x00 . 0x39 . 0x00 . 0x31 . 0x00 . 0x30 . 0x00 . 0x46 . 0x00 .
|
||||
0x41 . 0x00 . 0x44 . 0x00 . 0x46 . 0x00 . 0x41 . 0x00 . 0x37 . 0x00 . 0x30 . 0x00 . 0x31 . 0x00 . 0x42 . 0x00 .
|
||||
0x7D . 0x00 . 0x00 . 0x00 . 0x00 . 0x00 . 0x00 . 0x00 . 0x2D . 0x00 . 0x39 . 0x00 . 0x30 . 0x00 . 0x33 . 0x00
|
||||
);
|
||||
|
||||
return $byte_order .
|
||||
$version .
|
||||
$system_id .
|
||||
$class_id .
|
||||
$num_property_sets .
|
||||
$format_id_0 .
|
||||
$offset_0 .
|
||||
$format_id_1 .
|
||||
$offset_1 .
|
||||
$size_0 .
|
||||
$num_property_0 .
|
||||
$property_offsets_0 .
|
||||
$property_data_0 .
|
||||
$property_data_1;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private function _pack_property_data($properties)
|
||||
{
|
||||
# The properties start after 8 bytes for size + num_properties + 8 bytes
|
||||
# for each propety type/offset pair.
|
||||
$offset += 8 * (count(properties) + 1);
|
||||
|
||||
$offsets = $data = array();
|
||||
foreach($properties as $property) {
|
||||
$offsets[] = $offset;
|
||||
|
||||
$property_type = $property['id'];
|
||||
|
||||
if ($property_type == 'VT_I2') {
|
||||
$packed_property = $this->_pack_VT_I2($property['value']);
|
||||
} elseif ($property_type == 'VT_LPSTR') {
|
||||
$packed_property = $this->_pack_VT_LPSTR($property['value'], $this->_codepage);
|
||||
} elseif ($property_type == 'VT_FILETIME') {
|
||||
$packed_property = $this->_pack_VT_FILETIME($property['value']);
|
||||
} else {
|
||||
die("Unknown property type: $property_type\n");
|
||||
}
|
||||
|
||||
$offset += strlen($packed_property);
|
||||
$data[] = $packed_property;
|
||||
}
|
||||
|
||||
return array($data, $offsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Escher object
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue