X-Git-Url: https://delta.frontaccounting.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=reporting%2Fincludes%2FWorkbook.php;h=718bdb66343e1bec237c5d543d7ce6af309e799f;hb=5e63c6ace55729bbb5ee3b060035a25a4426eb0a;hp=1f53c2aad6973ca143a7a5dbec8bfb817e6925cd;hpb=18ccf94f0421e7693bc40e177732a3f937b54d1a;p=fa-stable.git diff --git a/reporting/includes/Workbook.php b/reporting/includes/Workbook.php index 1f53c2aa..718bdb66 100644 --- a/reporting/includes/Workbook.php +++ b/reporting/includes/Workbook.php @@ -102,7 +102,6 @@ define('SPREADSHEET_EXCEL_WRITER_EQ', "="); */ define('SPREADSHEET_EXCEL_WRITER_NE', "<>"); -$encoding_string=''; /** * Class for creating OLE streams for Excel Spreadsheets * @@ -2479,9 +2478,9 @@ class Spreadsheet_Excel_Writer_Parser // Split the range into 2 cell refs if (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\:([A-Ia-i]?[A-Za-z])(\d+)$/", $range)) { - list($cell1, $cell2) = split(':', $range); + list($cell1, $cell2) = preg_split('/:/', $range); } elseif (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\.\.([A-Ia-i]?[A-Za-z])(\d+)$/", $range)) { - list($cell1, $cell2) = split('\.\.', $range); + list($cell1, $cell2) = preg_split('/\.\./', $range); } else { // TODO: use real error codes @@ -2521,7 +2520,7 @@ class Spreadsheet_Excel_Writer_Parser $class = 2; // as far as I know, this is magick. // Split the ref at the ! symbol - list($ext_ref, $range) = split('!', $token); + list($ext_ref, $range) = preg_split('/!/', $token); // Convert the external reference part (different for BIFF8) if ($this->_BIFF_version == 0x0500) { @@ -2531,7 +2530,7 @@ class Spreadsheet_Excel_Writer_Parser } // Split the range into 2 cell refs - list($cell1, $cell2) = split(':', $range); + list($cell1, $cell2) = preg_split('/:/', $range); // Convert the cell references if (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/", $cell1)) { @@ -2600,7 +2599,7 @@ class Spreadsheet_Excel_Writer_Parser $class = 2; // as far as I know, this is magick. // Split the ref at the ! symbol - list($ext_ref, $cell) = split('!', $cell); + list($ext_ref, $cell) = preg_split('/!/', $cell); // Convert the external reference part (different for BIFF8) if ($this->_BIFF_version == 0x0500) { @@ -2641,7 +2640,7 @@ class Spreadsheet_Excel_Writer_Parser // Check if there is a sheet range eg., Sheet1:Sheet2. if (preg_match("/:/", $ext_ref)) { - list($sheet_name1, $sheet_name2) = split(':', $ext_ref); + list($sheet_name1, $sheet_name2) = preg_split('/:/', $ext_ref); $sheet1 = $this->_getSheetIndex($sheet_name1); if ($sheet1 == -1) { @@ -2687,7 +2686,7 @@ class Spreadsheet_Excel_Writer_Parser // Check if there is a sheet range eg., Sheet1:Sheet2. if (preg_match("/:/", $ext_ref)) { - list($sheet_name1, $sheet_name2) = split(':', $ext_ref); + list($sheet_name1, $sheet_name2) = preg_split('/:/', $ext_ref); $sheet1 = $this->_getSheetIndex($sheet_name1); if ($sheet1 == -1) { @@ -2986,7 +2985,7 @@ class Spreadsheet_Excel_Writer_Parser default: // if it's a reference if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and - !ereg("[0-9]",$this->_lookahead) and + !preg_match("/[0-9]/",$this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.') and ($this->_lookahead != '!')) { @@ -2994,39 +2993,39 @@ class Spreadsheet_Excel_Writer_Parser } // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) elseif (preg_match("/^\w+(\:\w+)?\![A-Ia-i]?[A-Za-z][0-9]+$/u",$token) and - !ereg("[0-9]",$this->_lookahead) and + !preg_match("/[0-9]/",$this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { return $token; } // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1) elseif (preg_match("/^'[\w -]+(\:[\w -]+)?'\![A-Ia-i]?[A-Za-z][0-9]+$/u",$token) and - !ereg("[0-9]",$this->_lookahead) and + !preg_match("/[0-9]/",$this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { return $token; } // if it's a range (A1:A2) elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and - !ereg("[0-9]",$this->_lookahead)) + !preg_match("/[0-9]/",$this->_lookahead)) { return $token; } // if it's a range (A1..A2) elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and - !ereg("[0-9]",$this->_lookahead)) + !preg_match("/[0-9]/",$this->_lookahead)) { return $token; } // If it's an external range like Sheet1!A1 or Sheet1:Sheet2!A1:B2 elseif (preg_match("/^\w+(\:\w+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/u",$token) and - !ereg("[0-9]",$this->_lookahead)) + !preg_match("/[0-9]/",$this->_lookahead)) { return $token; } // If it's an external range like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1:B2 elseif (preg_match("/^'[\w -]+(\:[\w -]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/u",$token) and - !ereg("[0-9]",$this->_lookahead)) + !preg_match("/[0-9]/",$this->_lookahead)) { return $token; } @@ -3038,12 +3037,12 @@ class Spreadsheet_Excel_Writer_Parser return $token; } // If it's a string (of maximum 255 characters) - elseif (ereg("^\"[^\"]{0,255}\"$",$token)) + elseif (preg_match("/^\"[^\"]{0,255}\"$/",$token)) { return $token; } // if it's a function call - elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$token) and ($this->_lookahead == "(")) + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$token) and ($this->_lookahead == "(")) { return $token; } @@ -3118,7 +3117,7 @@ class Spreadsheet_Excel_Writer_Parser function _expression() { // If it's a string return a string node - if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token)) { + if (preg_match("/^\"[^\"]{0,255}\"$/", $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; @@ -3258,7 +3257,7 @@ class Spreadsheet_Excel_Writer_Parser return $result; } // if it's a function call - elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$this->_current_token)) + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$this->_current_token)) { $result = $this->_func(); return $result; @@ -4683,7 +4682,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr $row = $match[2]; // Convert base26 column string to number - $chars = split('', $col); + $chars = preg_split('//', $col); $expn = 0; $col = 0; @@ -4878,11 +4877,10 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr */ function setInputEncoding($encoding) { - global $encoding_string; if ($encoding != 'UTF-16LE' && !function_exists('iconv')) { die("Using an input encoding other than UTF-16LE requires PHP support for iconv"); } - $this->_input_encoding = $encoding_string = $encoding; + $this->_input_encoding = $encoding; } /** added 2009-03-05 by Joe Hunt, FA for arabic languages */ @@ -5401,7 +5399,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr // parameters accordingly. // Split the dir name and sheet name (if it exists) /*if (preg_match("/\#/", $url)) { - list($dir_long, $sheet) = split("\#", $url); + list($dir_long, $sheet) = preg_split("/\#/", $url); } else { $dir_long = $url; } @@ -5409,7 +5407,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr if (isset($sheet)) { $link_type |= 0x08; $sheet_len = pack("V", strlen($sheet) + 0x01); - $sheet = join("\0", split('', $sheet)); + $sheet = join("\0", preg_split('//', $sheet)); $sheet .= "\0\0\0"; } else { $sheet_len = ''; @@ -5433,7 +5431,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr $dir_short = preg_replace("/\.\.\\\/", '', $dir_long) . "\0"; // Store the long dir name as a wchar string (non-null terminated) - //$dir_long = join("\0", split('', $dir_long)); + //$dir_long = join("\0", preg_split('//', $dir_long)); $dir_long = $dir_long . "\0"; // Pack the lengths of the dir strings @@ -7007,7 +7005,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri $this->Spreadsheet_Excel_Writer_BIFFwriter(); $this->_filename = $filename; - $this->_parser =& new Spreadsheet_Excel_Writer_Parser($this->_byte_order, $this->_BIFF_version); + $this->_parser = new Spreadsheet_Excel_Writer_Parser($this->_byte_order, $this->_BIFF_version); $this->_1904 = 0; $this->_activesheet = 0; $this->_firstsheet = 0; @@ -7016,7 +7014,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri $this->_fileclosed = 0; $this->_biffsize = 0; $this->_sheetname = 'Sheet'; - $this->_tmp_format =& new Spreadsheet_Excel_Writer_Format($this->_BIFF_version); + $this->_tmp_format = new Spreadsheet_Excel_Writer_Format($this->_BIFF_version); $this->_worksheets = array(); $this->_sheetnames = array(); $this->_formats = array(); @@ -7744,7 +7742,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri /* if ($this->_BIFF_version == 0x0600) // Tried to fix the correct handling here, with the { // corrected specification from M$ - Joe Hunt 2009-03-08 - global $encoding_string; + $encoding_string = $this->_input_encoding; if ($encoding_string == 'UTF-16LE') { $strlen = function_exists('mb_strlen') ? mb_strlen($sheetname, 'UTF-16LE') : (strlen($sheetname) / 2); @@ -8156,9 +8154,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(); @@ -8166,6 +8164,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. @@ -8192,16 +8193,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 @@ -8243,13 +8267,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; } /** @@ -8266,28 +8296,41 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri function _storeSharedStringsTable() { $record = 0x00fc; // Record identifier - // 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 - - // Write the SST block header information - $header = pack("vv", $record, $length); - $data = pack("VV", $this->_str_total, $this->_str_unique); - $this->_append($header . $data); - + $length = 0x0008; // Number of bytes to follow + $total = 0x0000; // Iterate through the strings to calculate the CONTINUE block sizes - $continue_limit = 8216; + $continue_limit = 8208; $block_length = 0; $written = 0; $continue = 0; + // sizes are upside down + $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); + $data = pack("VV", $this->_str_total, $this->_str_unique); + $this->_append($header . $data); /* 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 @@ -8318,6 +8361,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 @@ -8328,7 +8395,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 @@ -8348,7 +8415,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); @@ -8370,4 +8438,3 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri } } } -?>