BIFF8 now working on OpenOffice

git-svn-id: https://svn.php.net/repository/pear/packages/Spreadsheet_Excel_Writer/trunk@143911 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Xavier Noguer Gallego 2003-11-06 18:50:27 +00:00
parent 230fd2386a
commit 02036526a2
5 changed files with 164 additions and 57 deletions

View File

@ -176,7 +176,7 @@ class Spreadsheet_Excel_Writer_BIFFwriter extends PEAR
}
elseif ($this->_BIFF_version == 0x0600) {
$length = 0x0010;
$unknown = pack("VV", 0x00000000, 0x00000006); //unknown last 8 bytes for BIFF8
$unknown = pack("VV", 0x00000041, 0x00000006); //unknown last 8 bytes for BIFF8
$build = 0x0DBB;
$year = 0x07CC;
}

View File

@ -245,11 +245,11 @@ class Spreadsheet_Excel_Writer_Format extends PEAR
/**
* Constructor
*
* @access public
* @access private
* @param integer $index the XF index for the format.
* @param array $properties array with properties to be set on initialization.
*/
function Spreadsheet_Excel_Writer_Format($BIFF_version, $index = 0,$properties = array())
function Spreadsheet_Excel_Writer_Format($BIFF_version, $index = 0, $properties = array())
{
$this->_xf_index = $index;
$this->_BIFF_version = $BIFF_version;
@ -350,6 +350,9 @@ class Spreadsheet_Excel_Writer_Format extends PEAR
if ($this->_left == 0) {
$this->_left_color = 0;
}
if ($this->_diag == 0) {
$this->_diag_color = 0;
}
$record = 0x00E0; // Record identifier
if ($this->_BIFF_version == 0x0500) {
@ -455,11 +458,16 @@ class Spreadsheet_Excel_Writer_Format extends PEAR
$uls = $this->_underline; // Underline
$bFamily = $this->_font_family; // Font family
$bCharSet = $this->_font_charset; // Character set
$rgch = $this->_font_name; // Font name
$encoding = 0; // TODO: Unicode support
$cch = strlen($rgch); // Length of font name
$record = 0x31; // Record identifier
$length = 0x0F + $cch; // Record length
$cch = strlen($this->_font_name); // Length of font name
$record = 0x31; // Record identifier
if ($this->_BIFF_version == 0x0500) {
$length = 0x0F + $cch; // Record length
}
elseif ($this->_BIFF_version == 0x0600) {
$length = 0x10 + $cch;
}
$reserved = 0x00; // Reserved
$grbit = 0x00; // Font attributes
if ($this->_italic) {
@ -476,9 +484,16 @@ class Spreadsheet_Excel_Writer_Format extends PEAR
}
$header = pack("vv", $record, $length);
$data = pack("vvvvvCCCCC", $dyHeight, $grbit, $icv, $bls,
$sss, $uls, $bFamily,
$bCharSet, $reserved, $cch);
if ($this->_BIFF_version == 0x0500) {
$data = pack("vvvvvCCCCC", $dyHeight, $grbit, $icv, $bls,
$sss, $uls, $bFamily,
$bCharSet, $reserved, $cch);
}
elseif ($this->_BIFF_version == 0x0600) {
$data = pack("vvvvvCCCCCC", $dyHeight, $grbit, $icv, $bls,
$sss, $uls, $bFamily,
$bCharSet, $reserved, $cch, $encoding);
}
return($header . $data. $this->_font_name);
}

View File

@ -624,13 +624,24 @@ class Spreadsheet_Excel_Writer_Parser extends PEAR
* Convert a string token to ptgStr
*
* @access private
* @param string $string A string for conversion to its ptg value
* @param string $string A string for conversion to its ptg value.
* @return mixed the converted token on success. PEAR_Error if the string
* is longer than 255 characters.
*/
function _convertString($string)
{
// chop away beggining and ending quotes
$string = substr($string, 1, strlen($string) - 2);
return pack("CC", $this->ptg['ptgStr'], strlen($string)).$string;
if (strlen($string) > 255) {
return $this->raiseError("String is too long");
}
if ($this->_BIFF_version == 0x0500) {
return pack("CC", $this->ptg['ptgStr'], strlen($string)).$string;
}
elseif ($this->_BIFF_version == 0x0600) {
$encoding = 0; // TODO: Unicode support
return pack("CCC", $this->ptg['ptgStr'], strlen($string), $encoding).$string;
}
}
/**

View File

@ -147,6 +147,12 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/
var $_url_format;
/**
* The codepage indicates the text encoding used for strings
* @var integer
*/
var $_codepage;
/**
* Class constructor
*
@ -173,6 +179,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$this->_sheetnames = array();
$this->_formats = array();
$this->_palette = array();
$this->_codepage = 0x04E4; // FIXME: should change for BIFF8
// Add the default format for hyperlinks
$this->_url_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1));
@ -228,7 +235,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
/**
* Sets the BIFF version.
* Possible values are 5 (Excel 5.0), or 8 (Excel 97/2000).
* This method exists just to access experimental functionality
* from BIFF8. It will be deprecated !
* Only possible value is 8 (Excel 97/2000).
* For any other value it fails silently.
*
* @access public
@ -236,19 +245,22 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*/
function setVersion($version)
{
if (($version == 5) or ($version == 8)) {
if ($version == 5) {
$version = 0x0500;
}
elseif ($version == 8) {
$version = 0x0600;
}
if ($version == 8) { // only accept version 8
$version = 0x0600;
$this->_BIFF_version = $version;
$this->_tmp_format->_BIFF_version = $version;
$this->_url_format->_BIFF_version = $version;
$this->_parser->_BIFF_version = $version;
$total_worksheets = count($this->_worksheets);
// change version for all worksheets too
for ($i = 0; $i < $total_worksheets; $i++) {
$this->_worksheets[$i]->_BIFF_version = $version;
}
$total_formats = count($this->_formats);
// change version for all formats too
for ($i = 0; $i < $total_formats; $i++) {
$this->_formats[$i]->_BIFF_version = $version;
}
}
}
@ -285,7 +297,8 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
}
}
$worksheet = new Spreadsheet_Excel_Writer_Worksheet($name, $index,
$worksheet = new Spreadsheet_Excel_Writer_Worksheet($this->_BIFF_version,
$name, $index,
$this->_activesheet, $this->_firstsheet,
$this->_url_format, $this->_parser);
@ -459,6 +472,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
// Add Workbook globals
$this->_storeBof(0x0005);
if ($this->_BIFF_version == 0x0600) {
$this->_storeCodepage();
$this->_storeWindow1();
}
if ($this->_BIFF_version == 0x0500) {
@ -484,15 +498,16 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
/* TODO: store COUNTRY record? */
if ($this->_BIFF_version == 0x0600) {
$this->_storeSupbookInternal();
//$this->_storeSupbookInternal();
/*
TODO: store external SUPBOOK records and XCT and CRN records
in case of external references for BIFF8
*/
$this->_storeExternsheetBiff8();
//$this->_storeExternsheetBiff8();
}
/* TODO: store SST for BIFF8 */
$this->_storeSharedStringsTable();
// End Workbook globals
$this->_storeEof();
@ -790,6 +805,23 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
*
*/
/**
* Stores the CODEPAGE biff record.
*
* @access private
*/
function _storeCodepage()
{
$record = 0x0042; // Record identifier
$length = 0x0002; // Number of bytes to follow
$cv = $this->_codepage; // The code page
$header = pack('vv', $record, $length);
$data = pack('v', $cv);
$this->_append($header.$data);
}
/**
* Write Excel BIFF WINDOW1 record.
*
@ -822,6 +854,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
/**
* Writes Excel BIFF BOUNDSHEET record.
* FIXME: inconsistent with BIFF documentation
*
* @param string $sheetname Worksheet name
* @param integer $offset Location of worksheet BOF
@ -830,13 +863,13 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
function _storeBoundsheet($sheetname,$offset)
{
$record = 0x0085; // Record identifier
$length = 0x07 + strlen($sheetname); // Number of bytes to follow
$length = 0x08 + strlen($sheetname); // Number of bytes to follow
$grbit = 0x0000; // Sheet identifier
$grbit = 0x0000; // Visibility and sheet type
$cch = strlen($sheetname); // Length of sheet name
$header = pack("vv", $record, $length);
$data = pack("VvC", $offset, $grbit, $cch);
$data = pack("Vvv", $offset, $grbit, $cch);
$this->_append($header.$data.$sheetname);
}
@ -907,12 +940,24 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
function _storeNumFormat($format,$ifmt)
{
$record = 0x041E; // Record identifier
$length = 0x03 + strlen($format); // Number of bytes to follow
if ($this->_BIFF_version == 0x0600) {
$length = 5 + strlen($format); // Number of bytes to follow
$encoding = 0x0;
}
elseif ($this->_BIFF_version == 0x0500) {
$length = 3 + strlen($format); // Number of bytes to follow
}
$cch = strlen($format); // Length of format string
$header = pack("vv", $record, $length);
$data = pack("vC", $ifmt, $cch);
if ($this->_BIFF_version == 0x0600) {
$data = pack("vvC", $ifmt, $cch, $encoding);
}
elseif ($this->_BIFF_version == 0x0500) {
$data = pack("vC", $ifmt, $cch);
}
$this->_append($header.$data.$format);
}
@ -1156,5 +1201,31 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
$header = pack("vvv", $record, $length, $ccv);
$this->_append($header.$data);
}
/**
* Write all of the workbooks strings into an indexed array.
* See the comments in _calculate_shared_string_sizes() for more information.
*
* 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.
*
* @access private
*/
function _storeSharedStringsTable()
{
$record = 0x00fc; // Record identifier
$length = 8; // Number of bytes to follow
$this->_str_total = 0;
$this->_str_unique = 0;
// Write the SST block header information
$header = pack("vv", $record, $length);
$data = pack("VV", $this->_str_total, $this->_str_unique);
$this->_append($header.$data);
}
}
?>

View File

@ -285,7 +285,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
/**
* Whether to use outline.
* @var bool
* @var integer
*/
var $_outline_on;
@ -340,13 +340,16 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
* @param mixed &$firstsheet The first worksheet in the workbook we belong to
* @param mixed &$url_format The default format for hyperlinks
* @param mixed &$parser The formula parser created for the Workbook
* @access private
*/
function Spreadsheet_Excel_Writer_Worksheet($name, $index, &$activesheet,
function Spreadsheet_Excel_Writer_Worksheet($BIFF_version, $name,
$index, &$activesheet,
&$firstsheet, &$url_format,
&$parser)
{
// It needs to call its parent's constructor explicitly
$this->Spreadsheet_Excel_Writer_BIFFwriter();
$this->_BIFF_version = $BIFF_version;
$rowmax = 65536; // 16384 in Excel 5
$colmax = 256;
@ -512,7 +515,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$this->_storeWsbool();
// Prepend GUTS
$this->_storeGuts();
//$this->_storeGuts();
// Prepend GRIDSET
$this->_storeGridset();
@ -524,14 +527,14 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$this->_storePrintHeaders();
// Prepend EXTERNSHEET references
for ($i = $num_sheets; $i > 0; $i--)
/*for ($i = $num_sheets; $i > 0; $i--)
{
$sheetname = $sheetnames[$i-1];
$this->_storeExternsheet($sheetname);
}
}*/
// Prepend the EXTERNCOUNT of external references.
$this->_storeExterncount($num_sheets);
//$this->_storeExterncount($num_sheets);
// Prepend the COLINFO records if they exist
if (!empty($this->_colinfo))
@ -556,7 +559,8 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$this->_storePanes($this->_panes);
}
$this->_storeSelection($this->_selection);
$this->_storeDataValidity();
/* TODO: add data validity */
//$this->_storeDataValidity();
$this->_storeEof();
}
@ -1326,7 +1330,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
// Ensure this is a boolean vale for Window2
if ($this->_outline_on) {
$this->_outline_on = true;
$this->_outline_on = 1;
}
}
@ -2052,22 +2056,23 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
function storeDimensions()
{
$record = 0x0200; // Record identifier
$length = 0x000A; // Number of bytes to follow
$row_min = $this->_dim_rowmin; // First row
$row_max = $this->_dim_rowmax; // Last row plus 1
$col_min = $this->_dim_colmin; // First column
$col_max = $this->_dim_colmax; // Last column plus 1
$reserved = 0x0000; // Reserved by Excel
$header = pack("vv", $record, $length);
if ($this->_BIFF_version == 0x0500) {
$length = 0x000A; // Number of bytes to follow
$data = pack("vvvvv", $row_min, $row_max,
$col_min, $col_max, $reserved);
}
elseif ($this->_BIFF_version == 0x0600) {
$length = 0x000E;
$data = pack("VVvvv", $row_min, $row_max,
$col_min, $col_max, $reserved);
}
$header = pack("vv", $record, $length);
$this->_prepend($header.$data);
}
@ -2089,7 +2094,7 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$grbit = 0x00B6; // Option flags
$rwTop = 0x0000; // Top row visible in window
$colLeft = 0x0000; // Leftmost column visible in window
$rgbHdr = 0x00000000; // Row/column heading and gridline color
// The options flags that comprise $grbit
$fDspFmla = 0; // 0 - bit
@ -2118,13 +2123,16 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$header = pack("vv", $record, $length);
$data = pack("vvv", $grbit, $rwTop, $colLeft);
// FIXME !!!
if ($this->_BIFF_version == 0x0500) {
$rgbHdr = 0x00000000; // Row/column heading and gridline color
$data .= pack("V", $rgbHdr);
}
elseif ($this->_BIFF_version == 0x0600) {
$rgbHdr = 0x0040; // Row/column heading and gridline color index
$zoom_factor_page_break = 0x0000;
$zoom_factor_normal = 0x0000;
$data .= pack("vvvvV", 0x0001, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000);
$data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000);
}
$this->_append($header.$data);
}
@ -2465,12 +2473,13 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
{
$record = 0x0014; // Record identifier
$str = $this->_header; // header string
$cch = strlen($str); // Length of header string
$length = 1 + $cch; // Bytes to follow
$str = $this->_header; // header string
$cch = strlen($str); // Length of header string
$encoding = 0x0; // TODO: Unicode support
$length = 3 + $cch; // Bytes to follow
$header = pack("vv", $record, $length);
$data = pack("C", $cch);
$header = pack("vv", $record, $length);
$data = pack("vC", $cch, $encoding);
$this->_append($header.$data.$str);
}
@ -2484,12 +2493,13 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
{
$record = 0x0015; // Record identifier
$str = $this->_footer; // Footer string
$cch = strlen($str); // Length of footer string
$length = 1 + $cch; // Bytes to follow
$str = $this->_footer; // Footer string
$cch = strlen($str); // Length of footer string
$encoding = 0x0; // TODO: Unicode support
$length = 3 + $cch; // Bytes to follow
$header = pack("vv", $record, $length);
$data = pack("C", $cch);
$data = pack("vC", $cch, $encoding);
$this->_append($header.$data.$str);
}
@ -2808,21 +2818,21 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
// Sort and filter array of page breaks
$breaks = $this->_hbreaks;
sort($breaks,SORT_NUMERIC);
sort($breaks, SORT_NUMERIC);
if ($breaks[0] == 0) { // don't use first break if it's 0
array_shift($breaks);
}
$record = 0x001b; // Record identifier
$cbrk = count($breaks); // Number of page breaks
$length = ($cbrk + 1) * 2; // Bytes to follow
$length = 2 + 6*$cbrk; // Bytes to follow
$header = pack("vv", $record, $length);
$data = pack("v", $cbrk);
// Append each page break
foreach($breaks as $break) {
$data .= pack("v", $break);
$data .= pack("vvv", $break, 0x0000, 0x00ff);
}
$this->_prepend($header.$data);
@ -2846,21 +2856,21 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
$breaks = array_slice($this->_vbreaks,0,1000);
// Sort and filter array of page breaks
sort($breaks,SORT_NUMERIC);
sort($breaks, SORT_NUMERIC);
if ($breaks[0] == 0) { // don't use first break if it's 0
array_shift($breaks);
}
$record = 0x001a; // Record identifier
$cbrk = count($breaks); // Number of page breaks
$length = ($cbrk + 1) * 2; // Bytes to follow
$length = 2 + 6*$cbrk; // Bytes to follow
$header = pack("vv", $record, $length);
$data = pack("v", $cbrk);
// Append each page break
foreach ($breaks as $break) {
$data .= pack("v", $break);
$data .= pack("vvv", $break, 0x0000, 0xffff);
}
$this->_prepend($header.$data);