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:
parent
5d77b80670
commit
182b39b5fe
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue