private function PHPExcel_Writer_Excel5_Workbook::_writeSharedStringsTable in Loft Data Grids 7.2
Same name and namespace in other branches
- 6.2 vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Workbook.php \PHPExcel_Writer_Excel5_Workbook::_writeSharedStringsTable()
* 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). * * The Excel documentation says that the SST record should be followed by an * EXTSST record. The EXTSST record is a hash table that is used to optimise * access to SST. However, despite the documentation it doesn't seem to be * required so we will ignore it. * *
Return value
string Binary data
1 call to PHPExcel_Writer_Excel5_Workbook::_writeSharedStringsTable()
- PHPExcel_Writer_Excel5_Workbook::writeWorkbook in vendor/
phpoffice/ phpexcel/ Classes/ PHPExcel/ Writer/ Excel5/ Workbook.php - * Assemble worksheets into a workbook and send the BIFF data to an OLE * storage. * *
File
- vendor/
phpoffice/ phpexcel/ Classes/ PHPExcel/ Writer/ Excel5/ Workbook.php, line 1297
Class
- PHPExcel_Writer_Excel5_Workbook
- PHPExcel_Writer_Excel5_Workbook
Code
private function _writeSharedStringsTable() {
// maximum size of record data (excluding record header)
$continue_limit = 8224;
// initialize array of record data blocks
$recordDatas = array();
// start SST record data block with total number of strings, total number of unique strings
$recordData = pack("VV", $this->_str_total, $this->_str_unique);
// loop through all (unique) strings in shared strings table
foreach (array_keys($this->_str_table) as $string) {
// here $string is a BIFF8 encoded string
// length = character count
$headerinfo = unpack("vlength/Cencoding", $string);
// currently, this is always 1 = uncompressed
$encoding = $headerinfo["encoding"];
// initialize finished writing current $string
$finished = false;
while ($finished === false) {
// normally, there will be only one cycle, but if string cannot immediately be written as is
// there will be need for more than one cylcle, if string longer than one record data block, there
// may be need for even more cycles
if (strlen($recordData) + strlen($string) <= $continue_limit) {
// then we can write the string (or remainder of string) without any problems
$recordData .= $string;
if (strlen($recordData) + strlen($string) == $continue_limit) {
// we close the record data block, and initialize a new one
$recordDatas[] = $recordData;
$recordData = '';
}
// we are finished writing this string
$finished = true;
}
else {
// special treatment writing the string (or remainder of the string)
// If the string is very long it may need to be written in more than one CONTINUE record.
// check how many bytes more there is room for in the current record
$space_remaining = $continue_limit - strlen($recordData);
// minimum space needed
// uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character
// compressed: 2 byte string length length field + 1 byte option flags + 1 byte character
$min_space_needed = $encoding == 1 ? 5 : 4;
// We have two cases
// 1. space remaining is less than minimum space needed
// here we must waste the space remaining and move to next record data block
// 2. space remaining is greater than or equal to minimum space needed
// here we write as much as we can in the current block, then move to next record data block
// 1. space remaining is less than minimum space needed
if ($space_remaining < $min_space_needed) {
// we close the block, store the block data
$recordDatas[] = $recordData;
// and start new record data block where we start writing the string
$recordData = '';
// 2. space remaining is greater than or equal to minimum space needed
}
else {
// initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below
$effective_space_remaining = $space_remaining;
// for uncompressed strings, sometimes effective space remaining is reduced by 1
if ($encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1) {
--$effective_space_remaining;
}
// one block fininshed, store the block data
$recordData .= substr($string, 0, $effective_space_remaining);
$string = substr($string, $effective_space_remaining);
// for next cycle in while loop
$recordDatas[] = $recordData;
// start new record data block with the repeated option flags
$recordData = pack('C', $encoding);
}
}
}
}
// Store the last record data block unless it is empty
// if there was no need for any continue records, this will be the for SST record data block itself
if (strlen($recordData) > 0) {
$recordDatas[] = $recordData;
}
// combine into one chunk with all the blocks SST, CONTINUE,...
$chunk = '';
foreach ($recordDatas as $i => $recordData) {
// first block should have the SST record header, remaing should have CONTINUE header
$record = $i == 0 ? 0xfc : 0x3c;
$header = pack("vv", $record, strlen($recordData));
$data = $header . $recordData;
$chunk .= $this
->writeData($data);
}
return $chunk;
}