@ -32,12 +32,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
require_once( api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Format.php') ;
require_once( api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/BIFFwriter.php') ;
require_once( api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Worksheet.php') ;
require_once( api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Parser.php') ;
require_once( api_get_path(LIBRARY_PATH).'pear/OLE/PPS/Root.php') ;
require_once( api_get_path(LIBRARY_PATH).'pear/OLE/PPS/File.php') ;
require_once api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Format.php';
require_once api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/BIFFwriter.php';
require_once api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Worksheet.php';
require_once api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Parser.php';
require_once api_get_path(LIBRARY_PATH).'pear/OLE/PPS/Root.php';
require_once api_get_path(LIBRARY_PATH).'pear/OLE/PPS/File.php';
/**
* Class for generating Excel Spreadsheets
@ -159,12 +159,6 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/
var $_country_code;
/**
* The temporary dir for storing the OLE file
* @var string
*/
var $_tmp_dir;
/**
* number of bytes for sizeinfo of strings
* @var integer
@ -207,7 +201,6 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$this->_str_unique = 0;
$this->_str_table = array();
$this->_setPaletteXl97();
$this->_tmp_dir = '';
}
/**
@ -276,6 +269,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$this->_tmp_format->_BIFF_version = $version;
$this->_url_format->_BIFF_version = $version;
$this->_parser->_BIFF_version = $version;
$this->_codepage = 0x04B0;
$total_worksheets = count($this->_worksheets);
// change version for all worksheets too
@ -343,8 +337,8 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$this->_activesheet, $this->_firstsheet,
$this->_str_total, $this->_str_unique,
$this->_str_table, $this->_url_format,
$this->_parser);
$this->_parser, $this->_tmp_dir );
$this->_worksheets[$index] = &$worksheet; // Store ref for iterator
$this->_sheetnames[$index] = $name; // Store EXTERNSHEET names
$this->_parser->setExtSheet($name, $index); // Register worksheet name with parser
@ -375,7 +369,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/
function & addValidator()
{
include_once( api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Validator.php') ;
include_once api_get_path(LIBRARY_PATH).'pear/Spreadsheet_Excel_Writer/Writer/Validator.php';
/* FIXME: check for successful inclusion*/
$valid = new Spreadsheet_Excel_Writer_Validator($this->_parser);
return $valid;
@ -495,6 +489,10 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/
function _storeWorkbook()
{
if (count($this->_worksheets) == 0) {
return true;
}
// Ensure that at least one worksheet has been selected.
if ($this->_activesheet == 0) {
$this->_worksheets[0]->selected = 1;
@ -559,22 +557,6 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
return true;
}
/**
* Sets the temp dir used for storing the OLE file
*
* @access public
* @param string $dir The dir to be used as temp dir
* @return true if given dir is valid, false otherwise
*/
function setTempDir($dir)
{
if (is_dir($dir)) {
$this->_tmp_dir = $dir;
return true;
}
return false;
}
/**
* Store the workbook in an OLE container
*
@ -583,7 +565,11 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/
function _storeOLEFile()
{
$OLE = new OLE_PPS_File(OLE::Asc2Ucs('Book'));
if($this->_BIFF_version == 0x0600) {
$OLE = new OLE_PPS_File(OLE::Asc2Ucs('Workbook'));
} else {
$OLE = new OLE_PPS_File(OLE::Asc2Ucs('Book'));
}
if ($this->_tmp_dir != '') {
$OLE->setTempDir($this->_tmp_dir);
}
@ -1311,9 +1297,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
8228 : Maximum Excel97 block size
-4 : Length of block header
-8 : Length of additional SST header information
= 8216
-8 : Arbitrary number to keep within _add_continue() limit = 8208
*/
$continue_limit = 8216 ;
$continue_limit = 8208 ;
$block_length = 0;
$written = 0;
$this->_block_sizes = array();
@ -1321,6 +1307,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
foreach (array_keys($this->_str_table) as $string) {
$string_length = strlen($string);
$headerinfo = unpack("vlength/Cencoding", $string);
$encoding = $headerinfo["encoding"];
$split_string = 0;
// Block length is the total length of the strings that will be
// written out in a single SST or CONTINUE block.
@ -1347,16 +1336,39 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
boundaries. Therefore, in some cases we need to reduce the
amount of available
*/
$align = 0;
// Only applies to Unicode strings
if ($encoding == 1) {
// Min string + header size -1
$header_length = 4;
if ($space_remaining > $header_length) {
// String contains 3 byte header => split on odd boundary
if (!$split_string & & $space_remaining % 2 != 1) {
$space_remaining--;
$align = 1;
}
// Split section without header => split on even boundary
else if ($split_string & & $space_remaining % 2 == 1) {
$space_remaining--;
$align = 1;
}
$split_string = 1;
}
}
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;
$block_length -= $continue_limit - $continue - $align ;
// Store the max size for this block
$this->_block_sizes[] = $continue_limit;
$this->_block_sizes[] = $continue_limit - $align ;
// If the current string was split then the next CONTINUE block
// should have the string continue flag (grbit) set unless the
@ -1398,13 +1410,19 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
This length is required to set the offsets in the BOUNDSHEET records since
they must be written before the SST records
*/
$total_offset = array_sum($this->_block_sizes);
// SST information
$total_offset += 8;
if (!empty($this->_block_sizes)) {
$total_offset += (count($this->_block_sizes)) * 4; // add CONTINUE headers
$tmp_block_sizes = array();
$tmp_block_sizes = $this->_block_sizes;
$length = 12;
if (!empty($tmp_block_sizes)) {
$length += array_shift($tmp_block_sizes); // SST
}
return $total_offset;
while (!empty($tmp_block_sizes)) {
$length += 4 + array_shift($tmp_block_sizes); // CONTINUEs
}
return $length;
}
/**
@ -1421,9 +1439,31 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
function _storeSharedStringsTable()
{
$record = 0x00fc; // Record identifier
$length = 0x0008; // Number of bytes to follow
$total = 0x0000;
// Iterate through the strings to calculate the CONTINUE block sizes
$continue_limit = 8208;
$block_length = 0;
$written = 0;
$continue = 0;
// sizes are upside down
$this->_block_sizes = array_reverse($this->_block_sizes);
$length = array_pop($this->_block_sizes) + 8; // First block size plus SST information
$tmp_block_sizes = $this->_block_sizes;
// $tmp_block_sizes = array_reverse($this->_block_sizes);
// The SST record is required even if it contains no strings. Thus we will
// always have a length
//
if (!empty($tmp_block_sizes)) {
$length = 8 + array_shift($tmp_block_sizes);
}
else {
// No strings
$length = 8;
}
// Write the SST block header information
$header = pack("vv", $record, $length);
@ -1431,18 +1471,14 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$this->_append($header . $data);
// Iterate through the strings to calculate the CONTINUE block sizes
$continue_limit = 8216;
$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
$headerinfo = unpack("vlength/Cencoding", $string);
$encoding = $headerinfo["encoding"];
$split_string = 0;
// Block length is the total length of the strings that will be
@ -1473,6 +1509,30 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
// Unicode data should only be split on char (2 byte) boundaries.
// Therefore, in some cases we need to reduce the amount of available
// space by 1 byte to ensure the correct alignment.
$align = 0;
// Only applies to Unicode strings
if ($encoding == 1) {
// Min string + header size -1
$header_length = 4;
if ($space_remaining > $header_length) {
// String contains 3 byte header => split on odd boundary
if (!$split_string & & $space_remaining % 2 != 1) {
$space_remaining--;
$align = 1;
}
// Split section without header => split on even boundary
else if ($split_string & & $space_remaining % 2 == 1) {
$space_remaining--;
$align = 1;
}
$split_string = 1;
}
}
if ($space_remaining > $header_length) {
// Write as much as possible of the string in the current block
@ -1483,7 +1543,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$string = substr($string, $space_remaining);
// Reduce the current block length by the amount written
$block_length -= $continue_limit - $continue;
$block_length -= $continue_limit - $continue - $align ;
// If the current string was split then the next CONTINUE block
// should have the string continue flag (grbit) set unless the
@ -1503,7 +1563,8 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
// Write the CONTINUE block header
if (!empty($this->_block_sizes)) {
$record = 0x003C;
$length = array_pop($this->_block_sizes);
$length = array_shift($tmp_block_sizes);
$header = pack('vv', $record, $length);
if ($continue) {
$header .= pack('C', $encoding);
@ -1524,5 +1585,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
}
}
}
}
?>