[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/excel/ -> BIFFwriter.php (source)

   1  <?php
   2  /*

   3  *  Module written/ported by Xavier Noguer <xnoguer@rezebra.com>

   4  *

   5  *  The majority of this is _NOT_ my code.  I simply ported it from the

   6  *  PERL Spreadsheet::WriteExcel module.

   7  *

   8  *  The author of the Spreadsheet::WriteExcel module is John McNamara 

   9  *  <jmcnamara@cpan.org>

  10  *

  11  *  I _DO_ maintain this code, and John McNamara has nothing to do with the

  12  *  porting of this code to PHP.  Any questions directly related to this

  13  *  class library should be directed to me.

  14  *

  15  *  License Information:

  16  *

  17  *    Spreadsheet::WriteExcel:  A library for generating Excel Spreadsheets

  18  *    Copyright (C) 2002 Xavier Noguer xnoguer@rezebra.com

  19  *

  20  *    This library is free software; you can redistribute it and/or

  21  *    modify it under the terms of the GNU Lesser General Public

  22  *    License as published by the Free Software Foundation; either

  23  *    version 2.1 of the License, or (at your option) any later version.

  24  *

  25  *    This library is distributed in the hope that it will be useful,

  26  *    but WITHOUT ANY WARRANTY; without even the implied warranty of

  27  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

  28  *    Lesser General Public License for more details.

  29  *

  30  *    You should have received a copy of the GNU Lesser General Public

  31  *    License along with this library; if not, write to the Free Software

  32  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  33  */
  34  
  35  /**

  36  * Class for writing Excel BIFF records.

  37  * 

  38  * From "MICROSOFT EXCEL BINARY FILE FORMAT" by Mark O'Brien (Microsoft Corporation):

  39  *

  40  * BIFF (BInary File Format) is the file format in which Excel documents are 

  41  * saved on disk.  A BIFF file is a complete description of an Excel document.

  42  * BIFF files consist of sequences of variable-length records. There are many 

  43  * different types of BIFF records.  For example, one record type describes a 

  44  * formula entered into a cell; one describes the size and location of a 

  45  * window into a document; another describes a picture format.

  46  *

  47  * @author Xavier Noguer <xnoguer@rezebra.com>

  48  * @package Spreadsheet_WriteExcel

  49  */
  50  
  51  class BIFFWriter
  52  {
  53      var $_BIFF_version = 0x0500;
  54  
  55  /**

  56  * Constructor

  57  *

  58  * @access public

  59  */
  60      function BIFFwriter()
  61      {
  62          // The byte order of this architecture. 0 => little endian, 1 => big endian

  63          $this->_byte_order = '';
  64          // The string containing the data of the BIFF stream

  65          $this->_data       = '';
  66          // Should be the same as strlen($this->_data)

  67          $this->_datasize   = 0;
  68          // The maximun length for a BIFF record. See _add_continue()

  69          $this->_limit      = 2080;   
  70          // Set the byte order

  71          $this->_set_byte_order();
  72      }
  73  
  74  /**

  75  * Determine the byte order and store it as class data to avoid

  76  * recalculating it for each call to new().

  77  *

  78  * @access private

  79  */
  80      function _set_byte_order()
  81      {
  82          if ($this->_byte_order == '')
  83          {
  84              // Check if "pack" gives the required IEEE 64bit float

  85              $teststr = pack("d", 1.2345);
  86              $number  = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F);
  87              if ($number == $teststr) {
  88                  $byte_order = 0;    // Little Endian

  89              }
  90              elseif ($number == strrev($teststr)){
  91                  $byte_order = 1;    // Big Endian

  92              }
  93              else {
  94                  // Give up. I'll fix this in a later version.

  95                  die("Required floating point format not supported ".
  96                      "on this platform. See the portability section ".
  97                      "of the documentation."
  98                     );
  99              }
 100          }
 101          $this->_byte_order = $byte_order;
 102      }
 103  
 104  /**

 105  * General storage function

 106  *

 107  * @param string $data binary data to prepend

 108  * @access private

 109  */
 110      function _prepend($data)
 111      {
 112          if (strlen($data) > $this->_limit) {
 113              $data = $this->_add_continue($data);
 114          }
 115          $this->_data      = $data.$this->_data;
 116          $this->_datasize += strlen($data);
 117      }
 118  
 119  /**

 120  * General storage function

 121  *

 122  * @param string $data binary data to append

 123  * @access private

 124  */
 125      function _append($data)
 126      {
 127          if (strlen($data) > $this->_limit) {
 128              $data = $this->_add_continue($data);
 129          }
 130          $this->_data      = $this->_data.$data;
 131          $this->_datasize += strlen($data);
 132      }
 133  
 134  /**

 135  * Writes Excel BOF record to indicate the beginning of a stream or

 136  * sub-stream in the BIFF file.

 137  *

 138  * @param  integer $type type of BIFF file to write: 0x0005 Workbook, 0x0010 Worksheet.

 139  * @access private

 140  */
 141      function _store_bof($type)
 142      {
 143          $record  = 0x0809;        // Record identifier

 144          $length  = 0x0008;        // Number of bytes to follow

 145          $version = $this->_BIFF_version;
 146     
 147          // According to the SDK $build and $year should be set to zero.

 148          // However, this throws a warning in Excel 5. So, use these

 149          // magic numbers.

 150          $build   = 0x096C;
 151          $year    = 0x07C9;
 152     
 153          $header  = pack("vv",   $record, $length);
 154          $data    = pack("vvvv", $version, $type, $build, $year);
 155          $this->_prepend($header.$data);
 156      }
 157  
 158  /**

 159  * Writes Excel EOF record to indicate the end of a BIFF stream.

 160  *

 161  * @access private

 162  */
 163      function _store_eof() 
 164      {
 165          $record    = 0x000A;   // Record identifier

 166          $length    = 0x0000;   // Number of bytes to follow

 167          $header    = pack("vv", $record, $length);
 168          $this->_append($header);
 169      }
 170  
 171  /**

 172  * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In

 173  * Excel 97 the limit is 8228 bytes. Records that are longer than these limits

 174  * must be split up into CONTINUE blocks.

 175  *

 176  * This function takes a long BIFF record and inserts CONTINUE records as

 177  * necessary.

 178  *

 179  * @param  string  $data The original binary data to be written

 180  * @return string        A very convenient string of continue blocks

 181  * @access private

 182  */
 183      function _add_continue($data)
 184      {
 185          $limit      = $this->_limit;
 186          $record     = 0x003C;         // Record identifier

 187   
 188          // The first 2080/8224 bytes remain intact. However, we have to change

 189          // the length field of the record.

 190          $tmp = substr($data, 0, 2).pack("v", $limit-4).substr($data, 4, $limit - 4);
 191          
 192          $header = pack("vv", $record, $limit);  // Headers for continue records

 193   
 194          // Retrieve chunks of 2080/8224 bytes +4 for the header.

 195          for($i = $limit; $i < strlen($data) - $limit; $i += $limit)
 196          {
 197              $tmp .= $header;
 198              $tmp .= substr($data, $i, $limit);
 199          }
 200  
 201          // Retrieve the last chunk of data

 202          $header  = pack("vv", $record, strlen($data) - $i);
 203          $tmp    .= $header;
 204          $tmp    .= substr($data,$i,strlen($data) - $i);
 205   
 206          return($tmp);
 207      }
 208  }
 209  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7