first commit
git-svn-id: https://svn.php.net/repository/pear/packages/Spreadsheet_Excel_Writer/trunk@108662 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
parent
87b1ebfb66
commit
dc0a731457
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
*
|
||||||
|
* PERL Spreadsheet::WriteExcel module.
|
||||||
|
*
|
||||||
|
* The author of the Spreadsheet::WriteExcel module is John McNamara
|
||||||
|
* <jmcnamara@cpan.org>
|
||||||
|
*
|
||||||
|
* I _DO_ maintain this code, and John McNamara has nothing to do with the
|
||||||
|
* porting of this code to PHP. Any questions directly related to this
|
||||||
|
* class library should be directed to me.
|
||||||
|
*
|
||||||
|
* License Information:
|
||||||
|
*
|
||||||
|
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
|
||||||
|
* Copyright (C) 2002 Xavier Noguer xnoguer@rezebra.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once('PEAR.php');
|
||||||
|
require_once('Spreadsheet/Excel/Writer/Workbook.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for writing Excel Spreadsheets. This class should change COMPLETELY.
|
||||||
|
*
|
||||||
|
* @author Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
* @package Spreadsheet_Excel_Writer
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Spreadsheet_Excel_Writer extends Workbook
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The constructor. It just creates a Workbook
|
||||||
|
*
|
||||||
|
* @param string $filename The optional filename for the Workbook.
|
||||||
|
* @return object The Workbook created
|
||||||
|
*/
|
||||||
|
function Spreadsheet_Excel_Writer($filename = '')
|
||||||
|
{
|
||||||
|
$this->_filename = $filename;
|
||||||
|
$this->Workbook($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send HTTP headers for the Excel file.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function send($filename)
|
||||||
|
{
|
||||||
|
header("Content-type: application/vnd.ms-excel");
|
||||||
|
header("Content-Disposition: attachment; filename=$filename");
|
||||||
|
header("Expires: 0");
|
||||||
|
header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
|
||||||
|
header("Pragma: public");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
*
|
||||||
|
* The majority of this is _NOT_ my code. I simply ported it from the
|
||||||
|
* PERL Spreadsheet::WriteExcel module.
|
||||||
|
*
|
||||||
|
* The author of the Spreadsheet::WriteExcel module is John McNamara
|
||||||
|
* <jmcnamara@cpan.org>
|
||||||
|
*
|
||||||
|
* I _DO_ maintain this code, and John McNamara has nothing to do with the
|
||||||
|
* porting of this code to PHP. Any questions directly related to this
|
||||||
|
* class library should be directed to me.
|
||||||
|
*
|
||||||
|
* License Information:
|
||||||
|
*
|
||||||
|
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
|
||||||
|
* Copyright (C) 2002 Xavier Noguer xnoguer@rezebra.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once('PEAR.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for writing Excel BIFF records.
|
||||||
|
*
|
||||||
|
* From "MICROSOFT EXCEL BINARY FILE FORMAT" by Mark O'Brien (Microsoft Corporation):
|
||||||
|
*
|
||||||
|
* BIFF (BInary File Format) is the file format in which Excel documents are
|
||||||
|
* saved on disk. A BIFF file is a complete description of an Excel document.
|
||||||
|
* BIFF files consist of sequences of variable-length records. There are many
|
||||||
|
* different types of BIFF records. For example, one record type describes a
|
||||||
|
* formula entered into a cell; one describes the size and location of a
|
||||||
|
* window into a document; another describes a picture format.
|
||||||
|
*
|
||||||
|
* @author Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
* @package Spreadsheet_Excel_Writer
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BIFFwriter extends PEAR
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The BIFF/Excel version (5).
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_BIFF_version = 0x0500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The byte order of this architecture. 0 => little endian, 1 => big endian
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_byte_order;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The string containing the data of the BIFF stream
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the data in bytes. Should be the same as strlen($this->_data)
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_datasize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximun length for a BIFF record. See _addContinue()
|
||||||
|
* @var integer
|
||||||
|
* @see _addContinue()
|
||||||
|
*/
|
||||||
|
var $_limit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function BIFFwriter()
|
||||||
|
{
|
||||||
|
$this->_byte_order = '';
|
||||||
|
$this->_data = '';
|
||||||
|
$this->_datasize = 0;
|
||||||
|
$this->_limit = 2080;
|
||||||
|
// Set the byte order
|
||||||
|
$this->_setByteOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the byte order and store it as class data to avoid
|
||||||
|
* recalculating it for each call to new().
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _setByteOrder()
|
||||||
|
{
|
||||||
|
if ($this->_byte_order == '')
|
||||||
|
{
|
||||||
|
// Check if "pack" gives the required IEEE 64bit float
|
||||||
|
$teststr = pack("d", 1.2345);
|
||||||
|
$number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F);
|
||||||
|
if ($number == $teststr) {
|
||||||
|
$byte_order = 0; // Little Endian
|
||||||
|
}
|
||||||
|
elseif ($number == strrev($teststr)){
|
||||||
|
$byte_order = 1; // Big Endian
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Give up. I'll fix this in a later version.
|
||||||
|
$this->raiseError("Required floating point format not supported ".
|
||||||
|
"on this platform.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_byte_order = $byte_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General storage function
|
||||||
|
*
|
||||||
|
* @param string $data binary data to prepend
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _prepend($data)
|
||||||
|
{
|
||||||
|
if (strlen($data) > $this->_limit) {
|
||||||
|
$data = $this->_addContinue($data);
|
||||||
|
}
|
||||||
|
$this->_data = $data.$this->_data;
|
||||||
|
$this->_datasize += strlen($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General storage function
|
||||||
|
*
|
||||||
|
* @param string $data binary data to append
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _append($data)
|
||||||
|
{
|
||||||
|
if (strlen($data) > $this->_limit) {
|
||||||
|
$data = $this->_addContinue($data);
|
||||||
|
}
|
||||||
|
$this->_data = $this->_data.$data;
|
||||||
|
$this->_datasize += strlen($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes Excel BOF record to indicate the beginning of a stream or
|
||||||
|
* sub-stream in the BIFF file.
|
||||||
|
*
|
||||||
|
* @param integer $type type of BIFF file to write: 0x0005 Workbook, 0x0010 Worksheet.
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _storeBof($type)
|
||||||
|
{
|
||||||
|
$record = 0x0809; // Record identifier
|
||||||
|
$length = 0x0008; // Number of bytes to follow
|
||||||
|
$version = $this->_BIFF_version;
|
||||||
|
|
||||||
|
// According to the SDK $build and $year should be set to zero.
|
||||||
|
// However, this throws a warning in Excel 5. So, use these
|
||||||
|
// magic numbers.
|
||||||
|
$build = 0x096C;
|
||||||
|
$year = 0x07C9;
|
||||||
|
|
||||||
|
$header = pack("vv", $record, $length);
|
||||||
|
$data = pack("vvvv", $version, $type, $build, $year);
|
||||||
|
$this->_prepend($header.$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes Excel EOF record to indicate the end of a BIFF stream.
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _storeEof()
|
||||||
|
{
|
||||||
|
$record = 0x000A; // Record identifier
|
||||||
|
$length = 0x0000; // Number of bytes to follow
|
||||||
|
$header = pack("vv", $record, $length);
|
||||||
|
$this->_append($header);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In
|
||||||
|
* Excel 97 the limit is 8228 bytes. Records that are longer than these limits
|
||||||
|
* must be split up into CONTINUE blocks.
|
||||||
|
*
|
||||||
|
* This function takes a long BIFF record and inserts CONTINUE records as
|
||||||
|
* necessary.
|
||||||
|
*
|
||||||
|
* @param string $data The original binary data to be written
|
||||||
|
* @return string A very convenient string of continue blocks
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _addContinue($data)
|
||||||
|
{
|
||||||
|
$limit = $this->_limit;
|
||||||
|
$record = 0x003C; // Record identifier
|
||||||
|
|
||||||
|
// The first 2080/8224 bytes remain intact. However, we have to change
|
||||||
|
// the length field of the record.
|
||||||
|
$tmp = substr($data, 0, 2).pack("v", $limit-4).substr($data, 4, $limit - 4);
|
||||||
|
|
||||||
|
$header = pack("vv", $record, $limit); // Headers for continue records
|
||||||
|
|
||||||
|
// Retrieve chunks of 2080/8224 bytes +4 for the header.
|
||||||
|
for($i = $limit; $i < strlen($data) - $limit; $i += $limit)
|
||||||
|
{
|
||||||
|
$tmp .= $header;
|
||||||
|
$tmp .= substr($data, $i, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the last chunk of data
|
||||||
|
$header = pack("vv", $record, strlen($data) - $i);
|
||||||
|
$tmp .= $header;
|
||||||
|
$tmp .= substr($data,$i,strlen($data) - $i);
|
||||||
|
|
||||||
|
return($tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,638 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
*
|
||||||
|
* The majority of this is _NOT_ my code. I simply ported it from the
|
||||||
|
* PERL Spreadsheet::WriteExcel module.
|
||||||
|
*
|
||||||
|
* The author of the Spreadsheet::WriteExcel module is John McNamara
|
||||||
|
* <jmcnamara@cpan.org>
|
||||||
|
*
|
||||||
|
* I _DO_ maintain this code, and John McNamara has nothing to do with the
|
||||||
|
* porting of this code to PHP. Any questions directly related to this
|
||||||
|
* class library should be directed to me.
|
||||||
|
*
|
||||||
|
* License Information:
|
||||||
|
*
|
||||||
|
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
|
||||||
|
* Copyright (C) 2002 Xavier Noguer xnoguer@rezebra.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for generating Excel XF records (formats)
|
||||||
|
*
|
||||||
|
* @author Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
* @package Spreadsheet_Excel_Writer
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Format
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $index the XF index for the format.
|
||||||
|
* @param array $properties array with properties to be set on initialization.
|
||||||
|
*/
|
||||||
|
function Format($index = 0,$properties = array())
|
||||||
|
{
|
||||||
|
$this->xf_index = $index;
|
||||||
|
|
||||||
|
$this->font_index = 0;
|
||||||
|
$this->font = 'Arial';
|
||||||
|
$this->size = 10;
|
||||||
|
$this->bold = 0x0190;
|
||||||
|
$this->_italic = 0;
|
||||||
|
$this->color = 0x7FFF;
|
||||||
|
$this->_underline = 0;
|
||||||
|
$this->font_strikeout = 0;
|
||||||
|
$this->font_outline = 0;
|
||||||
|
$this->font_shadow = 0;
|
||||||
|
$this->font_script = 0;
|
||||||
|
$this->font_family = 0;
|
||||||
|
$this->font_charset = 0;
|
||||||
|
|
||||||
|
$this->_num_format = 0;
|
||||||
|
|
||||||
|
$this->hidden = 0;
|
||||||
|
$this->locked = 1;
|
||||||
|
|
||||||
|
$this->_text_h_align = 0;
|
||||||
|
$this->_text_wrap = 0;
|
||||||
|
$this->text_v_align = 2;
|
||||||
|
$this->text_justlast = 0;
|
||||||
|
$this->rotation = 0;
|
||||||
|
|
||||||
|
$this->fg_color = 0x40;
|
||||||
|
$this->bg_color = 0x41;
|
||||||
|
|
||||||
|
$this->pattern = 0;
|
||||||
|
|
||||||
|
$this->bottom = 0;
|
||||||
|
$this->top = 0;
|
||||||
|
$this->left = 0;
|
||||||
|
$this->right = 0;
|
||||||
|
|
||||||
|
$this->bottom_color = 0x40;
|
||||||
|
$this->top_color = 0x40;
|
||||||
|
$this->left_color = 0x40;
|
||||||
|
$this->right_color = 0x40;
|
||||||
|
|
||||||
|
// Set properties passed to Workbook::addFormat()
|
||||||
|
foreach($properties as $property => $value)
|
||||||
|
{
|
||||||
|
if(method_exists($this,'set'.ucwords($property)))
|
||||||
|
{
|
||||||
|
$method_name = 'set'.ucwords($property);
|
||||||
|
$this->$method_name($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an Excel BIFF XF record (style or cell).
|
||||||
|
*
|
||||||
|
* @param string $style The type of the XF record ('style' or 'cell').
|
||||||
|
* @return string The XF record
|
||||||
|
*/
|
||||||
|
function getXf($style)
|
||||||
|
{
|
||||||
|
// Set the type of the XF record and some of the attributes.
|
||||||
|
if ($style == "style") {
|
||||||
|
$style = 0xFFF5;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$style = $this->locked;
|
||||||
|
$style |= $this->hidden << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags to indicate if attributes have been set.
|
||||||
|
$atr_num = ($this->_num_format != 0)?1:0;
|
||||||
|
$atr_fnt = ($this->font_index != 0)?1:0;
|
||||||
|
$atr_alc = ($this->_text_wrap)?1:0;
|
||||||
|
$atr_bdr = ($this->bottom ||
|
||||||
|
$this->top ||
|
||||||
|
$this->left ||
|
||||||
|
$this->right)?1:0;
|
||||||
|
$atr_pat = (($this->fg_color != 0x40) ||
|
||||||
|
($this->bg_color != 0x41) ||
|
||||||
|
$this->pattern)?1:0;
|
||||||
|
$atr_prot = 0;
|
||||||
|
|
||||||
|
// Zero the default border colour if the border has not been set.
|
||||||
|
if ($this->bottom == 0) {
|
||||||
|
$this->bottom_color = 0;
|
||||||
|
}
|
||||||
|
if ($this->top == 0) {
|
||||||
|
$this->top_color = 0;
|
||||||
|
}
|
||||||
|
if ($this->right == 0) {
|
||||||
|
$this->right_color = 0;
|
||||||
|
}
|
||||||
|
if ($this->left == 0) {
|
||||||
|
$this->left_color = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$record = 0x00E0; // Record identifier
|
||||||
|
$length = 0x0010; // Number of bytes to follow
|
||||||
|
|
||||||
|
$ifnt = $this->font_index; // Index to FONT record
|
||||||
|
$ifmt = $this->_num_format; // Index to FORMAT record
|
||||||
|
|
||||||
|
$align = $this->_text_h_align; // Alignment
|
||||||
|
$align |= $this->_text_wrap << 3;
|
||||||
|
$align |= $this->text_v_align << 4;
|
||||||
|
$align |= $this->text_justlast << 7;
|
||||||
|
$align |= $this->rotation << 8;
|
||||||
|
$align |= $atr_num << 10;
|
||||||
|
$align |= $atr_fnt << 11;
|
||||||
|
$align |= $atr_alc << 12;
|
||||||
|
$align |= $atr_bdr << 13;
|
||||||
|
$align |= $atr_pat << 14;
|
||||||
|
$align |= $atr_prot << 15;
|
||||||
|
|
||||||
|
$icv = $this->fg_color; // fg and bg pattern colors
|
||||||
|
$icv |= $this->bg_color << 7;
|
||||||
|
|
||||||
|
$fill = $this->pattern; // Fill and border line style
|
||||||
|
$fill |= $this->bottom << 6;
|
||||||
|
$fill |= $this->bottom_color << 9;
|
||||||
|
|
||||||
|
$border1 = $this->top; // Border line style and color
|
||||||
|
$border1 |= $this->left << 3;
|
||||||
|
$border1 |= $this->right << 6;
|
||||||
|
$border1 |= $this->top_color << 9;
|
||||||
|
|
||||||
|
$border2 = $this->left_color; // Border color
|
||||||
|
$border2 |= $this->right_color << 7;
|
||||||
|
|
||||||
|
$header = pack("vv", $record, $length);
|
||||||
|
$data = pack("vvvvvvvv", $ifnt, $ifmt, $style, $align,
|
||||||
|
$icv, $fill,
|
||||||
|
$border1, $border2);
|
||||||
|
return($header.$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an Excel BIFF FONT record.
|
||||||
|
*
|
||||||
|
* @see Workbook::_storeAllFonts()
|
||||||
|
* @return string The FONT record
|
||||||
|
*/
|
||||||
|
function getFont()
|
||||||
|
{
|
||||||
|
$dyHeight = $this->size * 20; // Height of font (1/20 of a point)
|
||||||
|
$icv = $this->color; // Index to color palette
|
||||||
|
$bls = $this->bold; // Bold style
|
||||||
|
$sss = $this->font_script; // Superscript/subscript
|
||||||
|
$uls = $this->_underline; // Underline
|
||||||
|
$bFamily = $this->font_family; // Font family
|
||||||
|
$bCharSet = $this->font_charset; // Character set
|
||||||
|
$rgch = $this->font; // Font name
|
||||||
|
|
||||||
|
$cch = strlen($rgch); // Length of font name
|
||||||
|
$record = 0x31; // Record identifier
|
||||||
|
$length = 0x0F + $cch; // Record length
|
||||||
|
$reserved = 0x00; // Reserved
|
||||||
|
$grbit = 0x00; // Font attributes
|
||||||
|
if ($this->_italic) {
|
||||||
|
$grbit |= 0x02;
|
||||||
|
}
|
||||||
|
if ($this->font_strikeout) {
|
||||||
|
$grbit |= 0x08;
|
||||||
|
}
|
||||||
|
if ($this->font_outline) {
|
||||||
|
$grbit |= 0x10;
|
||||||
|
}
|
||||||
|
if ($this->font_shadow) {
|
||||||
|
$grbit |= 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = pack("vv", $record, $length);
|
||||||
|
$data = pack("vvvvvCCCCC", $dyHeight, $grbit, $icv, $bls,
|
||||||
|
$sss, $uls, $bFamily,
|
||||||
|
$bCharSet, $reserved, $cch);
|
||||||
|
return($header . $data. $this->font);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a unique hash key for a font. Used by Workbook->_storeAllFonts()
|
||||||
|
*
|
||||||
|
* The elements that form the key are arranged to increase the probability of
|
||||||
|
* generating a unique key. Elements that hold a large range of numbers
|
||||||
|
* (eg. _color) are placed between two binary elements such as _italic
|
||||||
|
*
|
||||||
|
* @return string A key for this font
|
||||||
|
*/
|
||||||
|
function getFontKey()
|
||||||
|
{
|
||||||
|
$key = "$this->font$this->size";
|
||||||
|
$key .= "$this->font_script$this->_underline";
|
||||||
|
$key .= "$this->font_strikeout$this->bold$this->font_outline";
|
||||||
|
$key .= "$this->font_family$this->font_charset";
|
||||||
|
$key .= "$this->font_shadow$this->color$this->_italic";
|
||||||
|
$key = str_replace(" ","_",$key);
|
||||||
|
return ($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index used by Worksheet->_XF()
|
||||||
|
*
|
||||||
|
* @return integer The index for the XF record
|
||||||
|
*/
|
||||||
|
function getXfIndex()
|
||||||
|
{
|
||||||
|
return($this->xf_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in conjunction with the set_xxx_color methods to convert a color
|
||||||
|
* string into a number. Color range is 0..63 but we will restrict it
|
||||||
|
* to 8..63 to comply with Gnumeric. Colors 0..7 are repeated in 8..15.
|
||||||
|
*
|
||||||
|
* @param string $name_color name of the color (i.e.: 'blue', 'red', etc..). Optional.
|
||||||
|
* @return integer The color index
|
||||||
|
*/
|
||||||
|
function _getColor($name_color = '')
|
||||||
|
{
|
||||||
|
$colors = array(
|
||||||
|
'aqua' => 0x0F,
|
||||||
|
'cyan' => 0x0F,
|
||||||
|
'black' => 0x08,
|
||||||
|
'blue' => 0x0C,
|
||||||
|
'brown' => 0x10,
|
||||||
|
'magenta' => 0x0E,
|
||||||
|
'fuchsia' => 0x0E,
|
||||||
|
'gray' => 0x17,
|
||||||
|
'grey' => 0x17,
|
||||||
|
'green' => 0x11,
|
||||||
|
'lime' => 0x0B,
|
||||||
|
'navy' => 0x12,
|
||||||
|
'orange' => 0x35,
|
||||||
|
'purple' => 0x14,
|
||||||
|
'red' => 0x0A,
|
||||||
|
'silver' => 0x16,
|
||||||
|
'white' => 0x09,
|
||||||
|
'yellow' => 0x0D
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return the default color, 0x7FFF, if undef,
|
||||||
|
if($name_color == '') {
|
||||||
|
return(0x7FFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// or the color string converted to an integer,
|
||||||
|
if(isset($colors[$name_color])) {
|
||||||
|
return($colors[$name_color]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// or the default color if string is unrecognised,
|
||||||
|
if(preg_match("/\D/",$name_color)) {
|
||||||
|
return(0x7FFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// or an index < 8 mapped into the correct range,
|
||||||
|
if($name_color < 8) {
|
||||||
|
return($name_color + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// or the default color if arg is outside range,
|
||||||
|
if($name_color > 63) {
|
||||||
|
return(0x7FFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// or an integer in the valid range
|
||||||
|
return($name_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set cell alignment.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $location alignment for the cell ('left', 'right', etc...).
|
||||||
|
*/
|
||||||
|
function setAlign($location)
|
||||||
|
{
|
||||||
|
if (preg_match("/\d/",$location)) {
|
||||||
|
return; // Ignore numbers
|
||||||
|
}
|
||||||
|
|
||||||
|
$location = strtolower($location);
|
||||||
|
|
||||||
|
if ($location == 'left')
|
||||||
|
$this->_text_h_align = 1;
|
||||||
|
if ($location == 'centre')
|
||||||
|
$this->_text_h_align = 2;
|
||||||
|
if ($location == 'center')
|
||||||
|
$this->_text_h_align = 2;
|
||||||
|
if ($location == 'right')
|
||||||
|
$this->_text_h_align = 3;
|
||||||
|
if ($location == 'fill')
|
||||||
|
$this->_text_h_align = 4;
|
||||||
|
if ($location == 'justify')
|
||||||
|
$this->_text_h_align = 5;
|
||||||
|
if ($location == 'merge')
|
||||||
|
$this->_text_h_align = 6;
|
||||||
|
if ($location == 'equal_space') // For T.K.
|
||||||
|
$this->_text_h_align = 7;
|
||||||
|
if ($location == 'top')
|
||||||
|
$this->text_v_align = 0;
|
||||||
|
if ($location == 'vcentre')
|
||||||
|
$this->text_v_align = 1;
|
||||||
|
if ($location == 'vcenter')
|
||||||
|
$this->text_v_align = 1;
|
||||||
|
if ($location == 'bottom')
|
||||||
|
$this->text_v_align = 2;
|
||||||
|
if ($location == 'vjustify')
|
||||||
|
$this->text_v_align = 3;
|
||||||
|
if ($location == 'vequal_space') // For T.K.
|
||||||
|
$this->text_v_align = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an alias for the unintuitive setAlign('merge')
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function setMerge()
|
||||||
|
{
|
||||||
|
$this->setAlign('merge');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bold has a range 0x64..0x3E8.
|
||||||
|
* 0x190 is normal. 0x2BC is bold.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $weight Weight for the text, 0 maps to 0x190, 1 maps to 0x2BC.
|
||||||
|
It's Optional, default is 1 (bold).
|
||||||
|
*/
|
||||||
|
function setBold($weight = 1)
|
||||||
|
{
|
||||||
|
if($weight == 1) {
|
||||||
|
$weight = 0x2BC; // Bold text
|
||||||
|
}
|
||||||
|
if($weight == 0) {
|
||||||
|
$weight = 0x190; // Normal text
|
||||||
|
}
|
||||||
|
if($weight < 0x064) {
|
||||||
|
$weight = 0x190; // Lower bound
|
||||||
|
}
|
||||||
|
if($weight > 0x3E8) {
|
||||||
|
$weight = 0x190; // Upper bound
|
||||||
|
}
|
||||||
|
$this->bold = $weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
* FUNCTIONS FOR SETTING CELLS BORDERS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the bottom border of the cell
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $style style of the cell border. 1 => thin, 2 => thick.
|
||||||
|
*/
|
||||||
|
function setBottom($style)
|
||||||
|
{
|
||||||
|
$this->bottom = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the top border of the cell
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $style style of the cell top border. 1 => thin, 2 => thick.
|
||||||
|
*/
|
||||||
|
function setTop($style)
|
||||||
|
{
|
||||||
|
$this->top = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the left border of the cell
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $style style of the cell left border. 1 => thin, 2 => thick.
|
||||||
|
*/
|
||||||
|
function setLeft($style)
|
||||||
|
{
|
||||||
|
$this->left = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the right border of the cell
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $style style of the cell right border. 1 => thin, 2 => thick.
|
||||||
|
*/
|
||||||
|
function setRight($style)
|
||||||
|
{
|
||||||
|
$this->right = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set cells borders to the same style
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $style style to apply for all cell borders. 1 => thin, 2 => thick.
|
||||||
|
*/
|
||||||
|
function setBorder($style)
|
||||||
|
{
|
||||||
|
$this->setBottom($style);
|
||||||
|
$this->setTop($style);
|
||||||
|
$this->setLeft($style);
|
||||||
|
$this->setRight($style);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************
|
||||||
|
* FUNCTIONS FOR SETTING CELLS BORDERS COLORS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets all the cell's borders to the same color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color The color we are setting. Either a string (like 'blue'),
|
||||||
|
* or an integer (like 0x41).
|
||||||
|
*/
|
||||||
|
function setBorderColor($color)
|
||||||
|
{
|
||||||
|
$this->setBottomColor($color);
|
||||||
|
$this->setTopColor($color);
|
||||||
|
$this->setLeftColor($color);
|
||||||
|
$this->setRightColor($color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's bottom border color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]).
|
||||||
|
*/
|
||||||
|
function setBottomColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->bottom_color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's top border color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]).
|
||||||
|
*/
|
||||||
|
function setTopColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->top_color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's left border color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (like 0x41).
|
||||||
|
*/
|
||||||
|
function setLeftColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->left_color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's right border color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (like 0x41).
|
||||||
|
*/
|
||||||
|
function setRightColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->right_color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's foreground color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (like 0x41).
|
||||||
|
*/
|
||||||
|
function setFgColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->fg_color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's background color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (like 0x41).
|
||||||
|
*/
|
||||||
|
function setBgColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->bg_color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cell's color
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $color either a string (like 'blue'), or an integer (like 0x41).
|
||||||
|
*/
|
||||||
|
function setColor($color)
|
||||||
|
{
|
||||||
|
$value = $this->_getColor($color);
|
||||||
|
$this->color = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pattern attribute of a cell
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $arg Optional. Defaults to 1.
|
||||||
|
*/
|
||||||
|
function setPattern($arg = 1)
|
||||||
|
{
|
||||||
|
$this->pattern = $arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the underline of the text
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $underline The value for underline. Possible values are:
|
||||||
|
* 1 => underline, 2 => double underline.
|
||||||
|
*/
|
||||||
|
function setUnderline($underline)
|
||||||
|
{
|
||||||
|
$this->_underline = $underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font style as italic
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function setItalic()
|
||||||
|
{
|
||||||
|
$this->_italic = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font size
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $size The font size (in pixels I think).
|
||||||
|
*/
|
||||||
|
function setSize($size)
|
||||||
|
{
|
||||||
|
$this->size = $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the num format
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $num_format The num format.
|
||||||
|
*/
|
||||||
|
function setNumFormat($num_format)
|
||||||
|
{
|
||||||
|
$this->_num_format = $num_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets text wrapping
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $text_wrap Optional. 0 => no text wrapping, 1 => text wrapping.
|
||||||
|
* Defaults to 1.
|
||||||
|
*/
|
||||||
|
function setTextWrap($text_wrap = 1)
|
||||||
|
{
|
||||||
|
$this->_text_wrap = $text_wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,417 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
*
|
||||||
|
* The majority of this is _NOT_ my code. I simply ported it from the
|
||||||
|
* PERL Spreadsheet::WriteExcel module.
|
||||||
|
*
|
||||||
|
* The author of the Spreadsheet::WriteExcel module is John McNamara
|
||||||
|
* <jmcnamara@cpan.org>
|
||||||
|
*
|
||||||
|
* I _DO_ maintain this code, and John McNamara has nothing to do with the
|
||||||
|
* porting of this code to PHP. Any questions directly related to this
|
||||||
|
* class library should be directed to me.
|
||||||
|
*
|
||||||
|
* License Information:
|
||||||
|
*
|
||||||
|
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
|
||||||
|
* Copyright (C) 2002 Xavier Noguer xnoguer@rezebra.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once('PEAR.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for creating OLE streams for Excel Spreadsheets
|
||||||
|
*
|
||||||
|
* @author Xavier Noguer <xnoguer@rezebra.com>
|
||||||
|
* @package Spreadsheet_Excel_Writer
|
||||||
|
*/
|
||||||
|
|
||||||
|
class OLEwriter extends PEAR
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Filename for the OLE stream
|
||||||
|
* @var string
|
||||||
|
* @see _initialize()
|
||||||
|
*/
|
||||||
|
var $_OLEfilename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filehandle for the OLE stream
|
||||||
|
* @var resource
|
||||||
|
*/
|
||||||
|
var $_filehandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the temporal file in case OLE stream goes to stdout
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_tmp_filename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable for preventing closing two times
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_fileclosed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the data to be written to the OLE stream
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_biffsize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Real data size to be written to the OLE stream
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_booksize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of big blocks in the OLE stream
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_big_blocks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of list blocks in the OLE stream
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_list_blocks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of big blocks in the OLE stream
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
var $_root_start;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for creating an OLEwriter
|
||||||
|
*
|
||||||
|
* @param string $OLEfilename the name of the file for the OLE stream
|
||||||
|
*/
|
||||||
|
function OLEwriter($OLEfilename)
|
||||||
|
{
|
||||||
|
$this->_OLEfilename = $OLEfilename;
|
||||||
|
$this->_filehandle = "";
|
||||||
|
$this->_tmp_filename = "";
|
||||||
|
$this->_fileclosed = 0;
|
||||||
|
$this->_biff_only = 0;
|
||||||
|
//$this->_size_allowed = 0;
|
||||||
|
$this->_biffsize = 0;
|
||||||
|
$this->_booksize = 0;
|
||||||
|
$this->_big_blocks = 0;
|
||||||
|
$this->_list_blocks = 0;
|
||||||
|
$this->_root_start = 0;
|
||||||
|
//$this->_block_count = 4;
|
||||||
|
$this->_initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for a valid filename and store the filehandle.
|
||||||
|
* Filehandle "-" writes to STDOUT
|
||||||
|
*/
|
||||||
|
function _initialize()
|
||||||
|
{
|
||||||
|
$OLEfile = $this->_OLEfilename;
|
||||||
|
|
||||||
|
if(($OLEfile == '-') or ($OLEfile == ''))
|
||||||
|
{
|
||||||
|
$this->_tmp_filename = tempnam("/tmp", "OLEwriter");
|
||||||
|
$fh = fopen($this->_tmp_filename,"wb");
|
||||||
|
if ($fh == false) {
|
||||||
|
$this->raiseError("Can't create temporary file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a new file, open for writing (in binmode)
|
||||||
|
$fh = fopen($OLEfile,"wb");
|
||||||
|
if ($fh == false) {
|
||||||
|
$this->raiseError("Can't open $OLEfile. It may be in use or protected.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store filehandle
|
||||||
|
$this->_filehandle = $fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the size of the data to be written to the OLE stream.
|
||||||
|
* The maximun size comes from this:
|
||||||
|
* $big_blocks = (109 depot block x (128 -1 marker word)
|
||||||
|
* - (1 x end words)) = 13842
|
||||||
|
* $maxsize = $big_blocks * 512 bytes = 7087104
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @see Workbook::store_OLE_file()
|
||||||
|
* @param integer $biffsize The size of the data to be written to the OLE stream
|
||||||
|
* @return integer 1 for success
|
||||||
|
*/
|
||||||
|
function setSize($biffsize)
|
||||||
|
{
|
||||||
|
$maxsize = 7087104; // TODO: extend max size
|
||||||
|
|
||||||
|
if ($biffsize > $maxsize) {
|
||||||
|
$this->raiseError("Maximum file size, $maxsize, exceeded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_biffsize = $biffsize;
|
||||||
|
// Set the min file size to 4k to avoid having to use small blocks
|
||||||
|
if ($biffsize > 4096) {
|
||||||
|
$this->_booksize = $biffsize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->_booksize = 4096;
|
||||||
|
}
|
||||||
|
//$this->_size_allowed = 1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate various sizes needed for the OLE stream
|
||||||
|
*/
|
||||||
|
function _calculateSizes()
|
||||||
|
{
|
||||||
|
$datasize = $this->_booksize;
|
||||||
|
if ($datasize % 512 == 0) {
|
||||||
|
$this->_big_blocks = $datasize/512;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->_big_blocks = floor($datasize/512) + 1;
|
||||||
|
}
|
||||||
|
// There are 127 list blocks and 1 marker blocks for each big block
|
||||||
|
// depot + 1 end of chain block
|
||||||
|
$this->_list_blocks = floor(($this->_big_blocks)/127) + 1;
|
||||||
|
$this->_root_start = $this->_big_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write root entry, big block list and close the filehandle.
|
||||||
|
* This routine is used to explicitly close the open filehandle without
|
||||||
|
* having to wait for DESTROY.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @see Workbook::store_OLE_file()
|
||||||
|
*/
|
||||||
|
function close()
|
||||||
|
{
|
||||||
|
//return if not $this->{_size_allowed};
|
||||||
|
$this->_writePadding();
|
||||||
|
$this->_writePropertyStorage();
|
||||||
|
$this->_writeBigBlockDepot();
|
||||||
|
// Close the filehandle
|
||||||
|
fclose($this->_filehandle);
|
||||||
|
if(($this->_OLEfilename == '-') or ($this->_OLEfilename == ''))
|
||||||
|
{
|
||||||
|
$fh = fopen($this->_tmp_filename, "rb");
|
||||||
|
if ($fh == false) {
|
||||||
|
$this->raiseError("Can't read temporary file.");
|
||||||
|
}
|
||||||
|
fpassthru($fh);
|
||||||
|
@unlink($this->_tmp_filename);
|
||||||
|
}
|
||||||
|
$this->_fileclosed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write BIFF data to OLE file.
|
||||||
|
*
|
||||||
|
* @param string $data string of bytes to be written
|
||||||
|
*/
|
||||||
|
function write($data) //por ahora sólo a STDOUT
|
||||||
|
{
|
||||||
|
fwrite($this->_filehandle,$data,strlen($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write OLE header block.
|
||||||
|
*/
|
||||||
|
function writeHeader()
|
||||||
|
{
|
||||||
|
$this->_calculateSizes();
|
||||||
|
$root_start = $this->_root_start;
|
||||||
|
$num_lists = $this->_list_blocks;
|
||||||
|
$id = pack("nnnn", 0xD0CF, 0x11E0, 0xA1B1, 0x1AE1);
|
||||||
|
$unknown1 = pack("VVVV", 0x00, 0x00, 0x00, 0x00);
|
||||||
|
$unknown2 = pack("vv", 0x3E, 0x03);
|
||||||
|
$unknown3 = pack("v", -2);
|
||||||
|
$unknown4 = pack("v", 0x09);
|
||||||
|
$unknown5 = pack("VVV", 0x06, 0x00, 0x00);
|
||||||
|
$num_bbd_blocks = pack("V", $num_lists);
|
||||||
|
$root_startblock = pack("V", $root_start);
|
||||||
|
$unknown6 = pack("VV", 0x00, 0x1000);
|
||||||
|
$sbd_startblock = pack("V", -2);
|
||||||
|
$unknown7 = pack("VVV", 0x00, -2 ,0x00);
|
||||||
|
$unused = pack("V", -1);
|
||||||
|
|
||||||
|
fwrite($this->_filehandle,$id);
|
||||||
|
fwrite($this->_filehandle,$unknown1);
|
||||||
|
fwrite($this->_filehandle,$unknown2);
|
||||||
|
fwrite($this->_filehandle,$unknown3);
|
||||||
|
fwrite($this->_filehandle,$unknown4);
|
||||||
|
fwrite($this->_filehandle,$unknown5);
|
||||||
|
fwrite($this->_filehandle,$num_bbd_blocks);
|
||||||
|
fwrite($this->_filehandle,$root_startblock);
|
||||||
|
fwrite($this->_filehandle,$unknown6);
|
||||||
|
fwrite($this->_filehandle,$sbd_startblock);
|
||||||
|
fwrite($this->_filehandle,$unknown7);
|
||||||
|
|
||||||
|
for($i=1; $i <= $num_lists; $i++)
|
||||||
|
{
|
||||||
|
$root_start++;
|
||||||
|
fwrite($this->_filehandle,pack("V",$root_start));
|
||||||
|
}
|
||||||
|
for($i = $num_lists; $i <=108; $i++)
|
||||||
|
{
|
||||||
|
fwrite($this->_filehandle,$unused);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write big block depot.
|
||||||
|
*/
|
||||||
|
function _writeBigBlockDepot()
|
||||||
|
{
|
||||||
|
$num_blocks = $this->_big_blocks;
|
||||||
|
$num_lists = $this->_list_blocks;
|
||||||
|
$total_blocks = $num_lists *128;
|
||||||
|
$used_blocks = $num_blocks + $num_lists +2;
|
||||||
|
|
||||||
|
$marker = pack("V", -3);
|
||||||
|
$end_of_chain = pack("V", -2);
|
||||||
|
$unused = pack("V", -1);
|
||||||
|
|
||||||
|
for($i=1; $i < $num_blocks; $i++)
|
||||||
|
{
|
||||||
|
fwrite($this->_filehandle,pack("V",$i));
|
||||||
|
}
|
||||||
|
fwrite($this->_filehandle,$end_of_chain);
|
||||||
|
fwrite($this->_filehandle,$end_of_chain);
|
||||||
|
for($i=0; $i < $num_lists; $i++)
|
||||||
|
{
|
||||||
|
fwrite($this->_filehandle,$marker);
|
||||||
|
}
|
||||||
|
for($i=$used_blocks; $i <= $total_blocks; $i++)
|
||||||
|
{
|
||||||
|
fwrite($this->_filehandle,$unused);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write property storage. TODO: add summary sheets
|
||||||
|
*/
|
||||||
|
function _writePropertyStorage()
|
||||||
|
{
|
||||||
|
//$rootsize = -2;
|
||||||
|
/*************** name type dir start size */
|
||||||
|
$this->_writePps("Root Entry", 0x05, 1, -2, 0x00);
|
||||||
|
$this->_writePps("Book", 0x02, -1, 0x00, $this->_booksize);
|
||||||
|
$this->_writePps('', 0x00, -1, 0x00, 0x0000);
|
||||||
|
$this->_writePps('', 0x00, -1, 0x00, 0x0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write property sheet in property storage
|
||||||
|
*
|
||||||
|
* @param string $name name of the property storage.
|
||||||
|
* @param integer $type type of the property storage.
|
||||||
|
* @param integer $dir dir of the property storage.
|
||||||
|
* @param integer $start start of the property storage.
|
||||||
|
* @param integer $size size of the property storage.
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _writePps($name,$type,$dir,$start,$size)
|
||||||
|
{
|
||||||
|
$length = 0;
|
||||||
|
$rawname = '';
|
||||||
|
|
||||||
|
if ($name != '')
|
||||||
|
{
|
||||||
|
$name = $name . "\0";
|
||||||
|
for($i=0;$i<strlen($name);$i++)
|
||||||
|
{
|
||||||
|
// Simulate a Unicode string
|
||||||
|
$rawname .= pack("H*",dechex(ord($name{$i}))).pack("C",0);
|
||||||
|
}
|
||||||
|
$length = strlen($name) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
$zero = pack("C", 0);
|
||||||
|
$pps_sizeofname = pack("v", $length); // 0x40
|
||||||
|
$pps_type = pack("v", $type); // 0x42
|
||||||
|
$pps_prev = pack("V", -1); // 0x44
|
||||||
|
$pps_next = pack("V", -1); // 0x48
|
||||||
|
$pps_dir = pack("V", $dir); // 0x4c
|
||||||
|
|
||||||
|
$unknown1 = pack("V", 0);
|
||||||
|
|
||||||
|
$pps_ts1s = pack("V", 0); // 0x64
|
||||||
|
$pps_ts1d = pack("V", 0); // 0x68
|
||||||
|
$pps_ts2s = pack("V", 0); // 0x6c
|
||||||
|
$pps_ts2d = pack("V", 0); // 0x70
|
||||||
|
$pps_sb = pack("V", $start); // 0x74
|
||||||
|
$pps_size = pack("V", $size); // 0x78
|
||||||
|
|
||||||
|
|
||||||
|
fwrite($this->_filehandle,$rawname);
|
||||||
|
for($i=0; $i < (64 -$length); $i++) {
|
||||||
|
fwrite($this->_filehandle,$zero);
|
||||||
|
}
|
||||||
|
fwrite($this->_filehandle,$pps_sizeofname);
|
||||||
|
fwrite($this->_filehandle,$pps_type);
|
||||||
|
fwrite($this->_filehandle,$pps_prev);
|
||||||
|
fwrite($this->_filehandle,$pps_next);
|
||||||
|
fwrite($this->_filehandle,$pps_dir);
|
||||||
|
for($i=0; $i < 5; $i++) {
|
||||||
|
fwrite($this->_filehandle,$unknown1);
|
||||||
|
}
|
||||||
|
fwrite($this->_filehandle,$pps_ts1s);
|
||||||
|
fwrite($this->_filehandle,$pps_ts1d);
|
||||||
|
fwrite($this->_filehandle,$pps_ts2d);
|
||||||
|
fwrite($this->_filehandle,$pps_ts2d);
|
||||||
|
fwrite($this->_filehandle,$pps_sb);
|
||||||
|
fwrite($this->_filehandle,$pps_size);
|
||||||
|
fwrite($this->_filehandle,$unknown1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pad the end of the file
|
||||||
|
*/
|
||||||
|
function _writePadding()
|
||||||
|
{
|
||||||
|
$biffsize = $this->_biffsize;
|
||||||
|
if ($biffsize < 4096) {
|
||||||
|
$min_size = 4096;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$min_size = 512;
|
||||||
|
}
|
||||||
|
if ($biffsize % $min_size != 0)
|
||||||
|
{
|
||||||
|
$padding = $min_size - ($biffsize % $min_size);
|
||||||
|
for($i=0; $i < $padding; $i++) {
|
||||||
|
fwrite($this->_filehandle,"\0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!DOCTYPE package SYSTEM "../package.dtd">
|
||||||
|
<package version="1.0">
|
||||||
|
<name>Spreadsheet_Excel_Writer</name>
|
||||||
|
<summary>Spreadsheet_Excel_Writer generates Excel files</summary>
|
||||||
|
<description>
|
||||||
|
Spreadsheet_Excel_Writer generates Excel files without the need for COM objects.</description>
|
||||||
|
<license>LGPL</license>
|
||||||
|
<maintainers>
|
||||||
|
<maintainer>
|
||||||
|
<user>xnoguer</user>
|
||||||
|
<name>Xavier Noguer</name>
|
||||||
|
<email>xnoguer@rezebra.com</email>
|
||||||
|
<role>lead</role>
|
||||||
|
</maintainer>
|
||||||
|
</maintainers>
|
||||||
|
<release>
|
||||||
|
<version>0.1</version>
|
||||||
|
<date>2002-11-26</date>
|
||||||
|
<notes>This is the initial release of the package.</notes>
|
||||||
|
<state>devel</state>
|
||||||
|
<filelist>
|
||||||
|
<dir name="/" baseinstalldir="Spreadsheet/Excel/">
|
||||||
|
<file role="php">Writer.php</file>
|
||||||
|
<dir name="Writer">
|
||||||
|
<file role="php">OLEwriter.php</file>
|
||||||
|
<file role="php">BIFFwriter.php</file>
|
||||||
|
<file role="php">Workbook.php</file>
|
||||||
|
<file role="php">Format.php</file>
|
||||||
|
<file role="php">Worksheet.php</file>
|
||||||
|
<file role="php">Parser.php</file>
|
||||||
|
</dir>
|
||||||
|
</dir>
|
||||||
|
</filelist>
|
||||||
|
</release>
|
||||||
|
</package>
|
||||||
Loading…
Reference in New Issue