support strings for BIFF8 and a few fixes to allow both versions to work

git-svn-id: https://svn.php.net/repository/pear/packages/Spreadsheet_Excel_Writer/trunk@144430 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Xavier Noguer Gallego 2003-11-15 20:53:18 +00:00
parent 5d77b80670
commit 182b39b5fe
2 changed files with 405 additions and 80 deletions

View File

@ -183,7 +183,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
// Add the default format for hyperlinks // Add the default format for hyperlinks
$this->_url_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1)); $this->_url_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1));
$this->_str_total = 0;
$this->_str_unique = 0;
$this->_str_table = array();
$this->_setPaletteXl97(); $this->_setPaletteXl97();
} }
@ -248,6 +250,8 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
if ($version == 8) { // only accept version 8 if ($version == 8) { // only accept version 8
$version = 0x0600; $version = 0x0600;
$this->_BIFF_version = $version; $this->_BIFF_version = $version;
// change BIFFwriter limit for CONTINUE records
$this->_limit = 8224;
$this->_tmp_format->_BIFF_version = $version; $this->_tmp_format->_BIFF_version = $version;
$this->_url_format->_BIFF_version = $version; $this->_url_format->_BIFF_version = $version;
$this->_parser->_BIFF_version = $version; $this->_parser->_BIFF_version = $version;
@ -300,7 +304,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$worksheet = new Spreadsheet_Excel_Writer_Worksheet($this->_BIFF_version, $worksheet = new Spreadsheet_Excel_Writer_Worksheet($this->_BIFF_version,
$name, $index, $name, $index,
$this->_activesheet, $this->_firstsheet, $this->_activesheet, $this->_firstsheet,
$this->_url_format, $this->_parser); $this->_str_total, $this->_str_unique,
$this->_str_table, $this->_url_format,
$this->_parser);
$this->_worksheets[$index] = &$worksheet; // Store ref for iterator $this->_worksheets[$index] = &$worksheet; // Store ref for iterator
$this->_sheetnames[$index] = $name; // Store EXTERNSHEET names $this->_sheetnames[$index] = $name; // Store EXTERNSHEET names
@ -453,16 +459,14 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
function _storeWorkbook() function _storeWorkbook()
{ {
// Ensure that at least one worksheet has been selected. // Ensure that at least one worksheet has been selected.
if ($this->_activesheet == 0) if ($this->_activesheet == 0) {
{
$this->_worksheets[0]->selected = 1; $this->_worksheets[0]->selected = 1;
} }
// Calculate the number of selected worksheet tabs and call the finalization // Calculate the number of selected worksheet tabs and call the finalization
// methods for each worksheet // methods for each worksheet
$total_worksheets = count($this->_worksheets); $total_worksheets = count($this->_worksheets);
for ($i=0; $i < $total_worksheets; $i++) for ($i=0; $i < $total_worksheets; $i++) {
{
if ($this->_worksheets[$i]->selected) { if ($this->_worksheets[$i]->selected) {
$this->_selected++; $this->_selected++;
} }
@ -499,15 +503,12 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
if ($this->_BIFF_version == 0x0600) { if ($this->_BIFF_version == 0x0600) {
//$this->_storeSupbookInternal(); //$this->_storeSupbookInternal();
/* /* TODO: store external SUPBOOK records and XCT and CRN records
TODO: store external SUPBOOK records and XCT and CRN records in case of external references for BIFF8 */
in case of external references for BIFF8
*/
//$this->_storeExternsheetBiff8(); //$this->_storeExternsheetBiff8();
$this->_storeSharedStringsTable();
} }
/* TODO: store SST for BIFF8 */
$this->_storeSharedStringsTable();
// End Workbook globals // End Workbook globals
$this->_storeEof(); $this->_storeEof();
@ -555,14 +556,22 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/ */
function _calcSheetOffsets() function _calcSheetOffsets()
{ {
if ($this->_BIFF_version == 0x0600) {
$boundsheet_length = 12; // fixed length for a BOUNDSHEET record $boundsheet_length = 12; // fixed length for a BOUNDSHEET record
}
else {
$boundsheet_length = 11;
}
$EOF = 4; $EOF = 4;
$offset = $this->_datasize; $offset = $this->_datasize;
if ($this->_BIFF_version == 0x0600) {
// add the length of the SST // add the length of the SST
$offset += 12; // FIXME: update when updating _storeSharedStringsTable() /* TODO: check this works for a lot of strings (> 8224 bytes) */
$offset += $this->_calculateSharedStringsSizes();
// add the lenght of SUPBOOK, EXTERNSHEET and NAME records // add the lenght of SUPBOOK, EXTERNSHEET and NAME records
$offset += 0; // FIXME: calculate real value when storing the records //$offset += 8; // FIXME: calculate real value when storing the records
}
$total_worksheets = count($this->_worksheets); $total_worksheets = count($this->_worksheets);
// add the length of the BOUNDSHEET records // add the length of the BOUNDSHEET records
for ($i=0; $i < $total_worksheets; $i++) { for ($i=0; $i < $total_worksheets; $i++) {
@ -870,13 +879,23 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
function _storeBoundsheet($sheetname,$offset) function _storeBoundsheet($sheetname,$offset)
{ {
$record = 0x0085; // Record identifier $record = 0x0085; // Record identifier
if ($this->_BIFF_version == 0x0600) {
$length = 0x08 + strlen($sheetname); // Number of bytes to follow $length = 0x08 + strlen($sheetname); // Number of bytes to follow
}
else {
$length = 0x07 + strlen($sheetname); // Number of bytes to follow
}
$grbit = 0x0000; // Visibility and sheet type $grbit = 0x0000; // Visibility and sheet type
$cch = strlen($sheetname); // Length of sheet name $cch = strlen($sheetname); // Length of sheet name
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
if ($this->_BIFF_version == 0x0600) {
$data = pack("Vvv", $offset, $grbit, $cch); $data = pack("Vvv", $offset, $grbit, $cch);
}
else {
$data = pack("VvC", $offset, $grbit, $cch);
}
$this->_append($header.$data.$sheetname); $this->_append($header.$data.$sheetname);
} }
@ -908,7 +927,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$record = 0x0017; // Record identifier $record = 0x0017; // Record identifier
$length = 2 + 6 * $total_references; // Number of bytes to follow $length = 2 + 6 * $total_references; // Number of bytes to follow
$supbook_index = 0; // only using internal SUPBOOK record $supbook_index = 0; // FIXME: only using internal SUPBOOK record
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
$data = pack('v', $total_references); $data = pack('v', $total_references);
for ($i = 0; $i < $total_references; $i++) { for ($i = 0; $i < $total_references; $i++) {
@ -1209,6 +1228,126 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$this->_append($header.$data); $this->_append($header.$data);
} }
/**
* Calculate
* Handling of the SST continue blocks is complicated by the need to include an
* additional continuation byte depending on whether the string is split between
* blocks or whether it starts at the beginning of the block. (There are also
* additional complications that will arise later when/if Rich Strings are
* supported).
*
* @access private
*/
function _calculateSharedStringsSizes()
{
/* Iterate through the strings to calculate the CONTINUE block sizes.
The SST blocks requires a specialised CONTINUE block, so we have to
ensure that the maximum data block size is less than the limit used by
_add_continue() in BIFFwriter.pm. For simplicity we use the same size
for the SST and CONTINUE records:
8228 : Maximum Excel97 block size
-4 : Length of block header
-8 : Length of additional SST header information
-8 : Arbitrary number to keep within _add_continue() limit
= 8208
*/
$total_offset = 12;
$continue_limit = 8208;
$block_length = 0;
$written = 0;
$this->_block_sizes = array();
$continue = 0;
foreach (array_keys($this->_str_table) as $string) {
$string_length = strlen($string);
// Block length is the total length of the strings that will be
// written out in a single SST or CONTINUE block.
$block_length += $string_length;
// We can write the string if it doesn't cross a CONTINUE boundary
if ($block_length < $continue_limit) {
$written += $string_length;
$total_offset += $string_length;
continue;
}
// Deal with the cases where the next string to be written will exceed
// the CONTINUE boundary. If the string is very long it may need to be
// written in more than one CONTINUE record.
while ($block_length >= $continue_limit) {
// We need to avoid the case where a string is continued in the first
// n bytes that contain the string header information.
$header_length = 3; // Min string + header size -1
$space_remaining = $continue_limit - $written - $continue;
/* TODO: Unicode data should only be split on char (2 byte)
boundaries. Therefore, in some cases we need to reduce the
amount of available
*/
if ($space_remaining > $header_length) {
// Write as much as possible of the string in the current block
$written += $space_remaining;
// Reduce the current block length by the amount written
$block_length -= $continue_limit + $continue;
// Store the max size for this block
$this->_block_sizes[] = $continue_limit;
// If the current string was split then the next CONTINUE block
// should have the string continue flag (grbit) set unless the
// split string fits exactly into the remaining space.
if ($block_length > 0) {
$continue = 1;
}
else {
$continue = 0;
}
}
else {
// Store the max size for this block
$this->_block_sizes[] = $written + $continue;
// Not enough space to start the string in the current block
$block_length -= $continue_limit - $space_remaining - $continue;
$continue = 0;
}
// If the string (or substr) is small enough we can write it in the
// new CONTINUE block. Else, go through the loop again to write it in
// one or more CONTINUE blocks
if ($block_length < $continue_limit) {
$written = $block_length;
}
else {
$written = 0;
}
}
}
// Store the max size for the last block unless it is empty
if ($written + $continue) {
$this->_block_sizes[] = $written + $continue;
}
/* Calculate the total length of the SST and associated CONTINUEs (if any).
The SST record will have a length even if it contains no strings.
This length is required to set the offsets in the BOUNDSHEET records since
they must be written before the SST records
*/
if (!empty($this->_block_sizes)) {
$total_offset += (count($this->_block_sizes) - 1) * 4; // add CONTINUE headers
}
return $total_offset;
}
/** /**
* Write all of the workbooks strings into an indexed array. * Write all of the workbooks strings into an indexed array.
* See the comments in _calculate_shared_string_sizes() for more information. * See the comments in _calculate_shared_string_sizes() for more information.
@ -1224,16 +1363,111 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
function _storeSharedStringsTable() function _storeSharedStringsTable()
{ {
$record = 0x00fc; // Record identifier $record = 0x00fc; // Record identifier
$length = 8; // Number of bytes to follow $length = 8 + array_sum($this->_block_sizes); // Number of bytes to follow
$this->_str_total = 0;
$this->_str_unique = 0;
// Write the SST block header information // Write the SST block header information
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
$data = pack("VV", $this->_str_total, $this->_str_unique); $data = pack("VV", $this->_str_total, $this->_str_unique);
$this->_append($header.$data); $this->_append($header.$data);
// Iterate through the strings to calculate the CONTINUE block sizes
$continue_limit = 8208;
$block_length = 0;
$written = 0;
$continue = 0;
/* TODO: not good for performance */
foreach (array_keys($this->_str_table) as $string) {
$string_length = strlen($string);
$encoding = 0; // assume there are no Unicode strings
$split_string = 0;
// Block length is the total length of the strings that will be
// written out in a single SST or CONTINUE block.
//
$block_length += $string_length;
// We can write the string if it doesn't cross a CONTINUE boundary
if ($block_length < $continue_limit) {
$this->_append($string);
$written += $string_length;
continue;
}
// Deal with the cases where the next string to be written will exceed
// the CONTINUE boundary. If the string is very long it may need to be
// written in more than one CONTINUE record.
//
while ($block_length >= $continue_limit) {
// We need to avoid the case where a string is continued in the first
// n bytes that contain the string header information.
//
$header_length = 3; // Min string + header size -1
$space_remaining = $continue_limit - $written - $continue;
// Unicode data should only be split on char (2 byte) boundaries.
// Therefore, in some cases we need to reduce the amount of available
if ($space_remaining > $header_length) {
// Write as much as possible of the string in the current block
$tmp = substr($string, 0, $space_remaining);
$this->_append($tmp);
// The remainder will be written in the next block(s)
$string = substr($string, $space_remaining);
// Reduce the current block length by the amount written
$block_length -= $continue_limit - $continue;
// If the current string was split then the next CONTINUE block
// should have the string continue flag (grbit) set unless the
// split string fits exactly into the remaining space.
//
if ($block_length > 0) {
$continue = 1;
}
else {
$continue = 0;
}
}
else {
// Not enough space to start the string in the current block
$block_length -= $continue_limit - $space_remaining - $continue;
$continue = 0;
}
// Write the CONTINUE block header
if (!empty($this->_block_sizes)) {
$record = 0x003C;
$length = array_push($this->_block_sizes);
$header = pack('vv', $record, $length);
if ($continue) {
$header .= pack('C', $encoding);
}
$this->_append($header);
}
// If the string (or substr) is small enough we can write it in the
// new CONTINUE block. Else, go through the loop again to write it in
// one or more CONTINUE blocks
//
if ($block_length < $continue_limit) {
$this->_append($string);
$written = $block_length;
}
else {
$written = 0;
}
}
}
} }
} }
?> ?>

View File

@ -331,6 +331,24 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
*/ */
var $_fit_height; var $_fit_height;
/**
* Reference to the total number of strings in the workbook
* @var integer
*/
var $_str_total;
/**
* Reference to the number of unique strings in the workbook
* @var integer
*/
var $_str_unique;
/**
* Reference to the array containing all the unique strings in the workbook
* @var array
*/
var $_str_table;
/** /**
* Constructor * Constructor
* *
@ -344,8 +362,9 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
*/ */
function Spreadsheet_Excel_Writer_Worksheet($BIFF_version, $name, function Spreadsheet_Excel_Writer_Worksheet($BIFF_version, $name,
$index, &$activesheet, $index, &$activesheet,
&$firstsheet, &$url_format, &$firstsheet, &$str_total,
&$parser) &$str_unique, &$str_table,
&$url_format, &$parser)
{ {
// It needs to call its parent's constructor explicitly // It needs to call its parent's constructor explicitly
$this->Spreadsheet_Excel_Writer_BIFFwriter(); $this->Spreadsheet_Excel_Writer_BIFFwriter();
@ -357,6 +376,9 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$this->index = $index; $this->index = $index;
$this->activesheet = &$activesheet; $this->activesheet = &$activesheet;
$this->firstsheet = &$firstsheet; $this->firstsheet = &$firstsheet;
$this->_str_total = &$str_total;
$this->_str_unique = &$str_unique;
$this->_str_table = &$str_table;
$this->_url_format = &$url_format; $this->_url_format = &$url_format;
$this->_parser = &$parser; $this->_parser = &$parser;
@ -515,12 +537,14 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
// Prepend WSBOOL // Prepend WSBOOL
$this->_storeWsbool(); $this->_storeWsbool();
// Prepend GUTS
//$this->_storeGuts();
// Prepend GRIDSET // Prepend GRIDSET
$this->_storeGridset(); $this->_storeGridset();
// Prepend GUTS
if ($this->_BIFF_version == 0x0500) {
$this->_storeGuts();
}
// Prepend PRINTGRIDLINES // Prepend PRINTGRIDLINES
$this->_storePrintGridlines(); $this->_storePrintGridlines();
@ -528,14 +552,17 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$this->_storePrintHeaders(); $this->_storePrintHeaders();
// Prepend EXTERNSHEET references // Prepend EXTERNSHEET references
/*for ($i = $num_sheets; $i > 0; $i--) if ($this->_BIFF_version == 0x0500) {
{ for ($i = $num_sheets; $i > 0; $i--) {
$sheetname = $sheetnames[$i-1]; $sheetname = $sheetnames[$i-1];
$this->_storeExternsheet($sheetname); $this->_storeExternsheet($sheetname);
}*/ }
}
// Prepend the EXTERNCOUNT of external references. // Prepend the EXTERNCOUNT of external references.
//$this->_storeExterncount($num_sheets); if ($this->_BIFF_version == 0x0500) {
$this->_storeExterncount($num_sheets);
}
// Prepend the COLINFO records if they exist // Prepend the COLINFO records if they exist
if (!empty($this->_colinfo)) if (!empty($this->_colinfo))
@ -561,7 +588,9 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
} }
$this->_storeSelection($this->_selection); $this->_storeSelection($this->_selection);
/* TODO: add data validity */ /* TODO: add data validity */
//$this->_storeDataValidity(); /*if ($this->_BIFF_version == 0x0600) {
$this->_storeDataValidity();
}*/
$this->_storeEof(); $this->_storeEof();
} }
@ -1419,6 +1448,9 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
*/ */
function writeString($row, $col, $str, $format = 0) function writeString($row, $col, $str, $format = 0)
{ {
if ($this->_BIFF_version == 0x0600) {
return $this->writeStringBIFF8($row, $col, $str, $format);
}
$strlen = strlen($str); $strlen = strlen($str);
$record = 0x0204; // Record identifier $record = 0x0204; // Record identifier
$length = 0x0008 + $strlen; // Bytes to follow $length = 0x0008 + $strlen; // Bytes to follow
@ -1466,6 +1498,68 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
return($str_error); return($str_error);
} }
function writeStringBIFF8($row, $col, $str, $format = 0)
{
$strlen = strlen($str);
$record = 0x00FD; // Record identifier
$length = 0x000A; // Bytes to follow
$xf = $this->_XF($format); // The cell format
$encoding = 0x0;
$str_error = 0;
// Check that row and col are valid and store max and min values
if ($this->_checkRowCol($row, $col) == false) {
return -2;
}
$str = pack('vC', $strlen, $encoding).$str;
/* check if string is already present */
if (!isset($this->_str_table[$str])) {
$this->_str_table[$str] = $this->_str_unique++;
}
$this->_str_total++;
$header = pack('vv', $record, $length);
$data = pack('vvvV', $row, $col, $xf, $this->_str_table[$str]);
$this->_append($header.$data);
return $str_error;
}
/**
* Check row and col before writing to a cell, and update the sheet's
* dimensions accordingly
*
* @access private
* @param integer $row Zero indexed row
* @param integer $col Zero indexed column
* @return boolean true for success, false if row and/or col are grester
* then maximums allowed.
*/
function _checkRowCol($row, $col)
{
if ($row >= $this->_xls_rowmax) {
return false;
}
if ($col >= $this->_xls_colmax) {
return false;
}
if ($row < $this->_dim_rowmin) {
$this->_dim_rowmin = $row;
}
if ($row > $this->_dim_rowmax) {
$this->_dim_rowmax = $row;
}
if ($col < $this->_dim_colmin) {
$this->_dim_colmin = $col;
}
if ($col > $this->_dim_colmax) {
$this->_dim_colmax = $col;
}
return true;
}
/** /**
* Writes a note associated with the cell given by the row and column. * Writes a note associated with the cell given by the row and column.
* NOTE records don't have a length limit. * NOTE records don't have a length limit.
@ -1614,33 +1708,12 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$xf = $this->_XF($format); // The cell format $xf = $this->_XF($format); // The cell format
$num = 0x00; // Current value of formula $num = 0x00; // Current value of formula
$grbit = 0x03; // Option flags $grbit = 0x03; // Option flags
$chn = 0x0000; // Must be zero $unknown = 0x0000; // Must be zero
// Check that row and col are valid and store max and min values // Check that row and col are valid and store max and min values
if ($row >= $this->_xls_rowmax) if ($this->_checkRowCol($row, $col) == false) {
{ return -2;
return(-2);
}
if ($col >= $this->_xls_colmax)
{
return(-2);
}
if ($row < $this->_dim_rowmin)
{
$this->_dim_rowmin = $row;
}
if ($row > $this->_dim_rowmax)
{
$this->_dim_rowmax = $row;
}
if ($col < $this->_dim_colmin)
{
$this->_dim_colmin = $col;
}
if ($col > $this->_dim_colmax)
{
$this->_dim_colmax = $col;
} }
// Strip the '=' or '@' sign at the beginning of the formula string // Strip the '=' or '@' sign at the beginning of the formula string
@ -1677,7 +1750,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
$data = pack("vvvdvVv", $row, $col, $xf, $num, $data = pack("vvvdvVv", $row, $col, $xf, $num,
$grbit, $chn, $formlen); $grbit, $unknown, $formlen);
$this->_append($header.$data.$formula); $this->_append($header.$data.$formula);
return 0; return 0;
@ -2038,9 +2111,13 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
// collapsed. The zero height flag, 0x20, is used to collapse a row. // collapsed. The zero height flag, 0x20, is used to collapse a row.
$grbit |= $level; $grbit |= $level;
if($hidden) $grbit |= 0x0020; if ($hidden) {
$grbit |= 0x0040; # fUnsynced $grbit |= 0x0020;
if($format) $grbit |= 0x0080; }
$grbit |= 0x0040; // fUnsynced
if ($format) {
$grbit |= 0x0080;
}
$grbit |= 0x0100; $grbit |= 0x0100;
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
@ -2476,11 +2553,20 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$str = $this->_header; // header string $str = $this->_header; // header string
$cch = strlen($str); // Length of header string $cch = strlen($str); // Length of header string
if ($this->_BIFF_version == 0x0600) {
$encoding = 0x0; // TODO: Unicode support $encoding = 0x0; // TODO: Unicode support
$length = 3 + $cch; // Bytes to follow $length = 3 + $cch; // Bytes to follow
}
else {
$length = 1 + $cch; // Bytes to follow
}
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
if ($this->_BIFF_version == 0x0600) {
$data = pack("vC", $cch, $encoding); $data = pack("vC", $cch, $encoding);
}
else {
$data = pack("C", $cch);
}
$this->_append($header.$data.$str); $this->_append($header.$data.$str);
} }
@ -2496,11 +2582,20 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$str = $this->_footer; // Footer string $str = $this->_footer; // Footer string
$cch = strlen($str); // Length of footer string $cch = strlen($str); // Length of footer string
if ($this->_BIFF_version == 0x0600) {
$encoding = 0x0; // TODO: Unicode support $encoding = 0x0; // TODO: Unicode support
$length = 3 + $cch; // Bytes to follow $length = 3 + $cch; // Bytes to follow
}
else {
$length = 1 + $cch;
}
$header = pack("vv", $record, $length); $header = pack("vv", $record, $length);
if ($this->_BIFF_version == 0x0600) {
$data = pack("vC", $cch, $encoding); $data = pack("vC", $cch, $encoding);
}
else {
$data = pack("C", $cch);
}
$this->_append($header.$data.$str); $this->_append($header.$data.$str);
} }
@ -3334,13 +3429,9 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$verPos = 0x00000000; // Vertical position of prompt box, if fixed position $verPos = 0x00000000; // Vertical position of prompt box, if fixed position
$objId = 0xffffffff; // Object identifier of drop down arrow object, or -1 if not visible $objId = 0xffffffff; // Object identifier of drop down arrow object, or -1 if not visible
$header = pack("vv", $record, $length); $header = pack('vv', $record, $length);
$data = pack("v", $grbit); $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId,
$data .= pack("V", $horPos); count($this->_dv));
$data .= pack("V", $verPos);
$data .= pack("V", $objId);
$data .= pack("V", count($this->_dv));
$this->_append($header.$data); $this->_append($header.$data);
$record = 0x01be; // Record identifier $record = 0x01be; // Record identifier