PHPExcel_Writer_Excel5
[ class tree: PHPExcel_Writer_Excel5 ] [ index: PHPExcel_Writer_Excel5 ] [ all elements ]

Source for file BIFFwriter.php

Documentation is available at BIFFwriter.php

  1. <?php
  2. /*
  3. *  Module written/ported by Xavier Noguer <xnoguer@php.net>
  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. *    PHPExcel_Writer_Excel5_Writer:  A library for generating Excel Spreadsheets
  18. *    Copyright (c) 2002-2003 Xavier Noguer xnoguer@php.net
  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@php.net>
  48. @category PHPExcel
  49. @package  PHPExcel_Writer_Excel5
  50. */
  51.  
  52. {
  53.     /**
  54.     * The BIFF/Excel version (5).
  55.     * @var integer 
  56.     */
  57.     var $_BIFF_version = 0x0500;
  58.  
  59.     /**
  60.     * The byte order of this architecture. 0 => little endian, 1 => big endian
  61.     * @var integer 
  62.     */
  63.     var $_byte_order;
  64.  
  65.     /**
  66.     * The string containing the data of the BIFF stream
  67.     * @var string 
  68.     */
  69.     var $_data;
  70.  
  71.     /**
  72.     * The size of the data in bytes. Should be the same as strlen($this->_data)
  73.     * @var integer 
  74.     */
  75.     var $_datasize;
  76.  
  77.     /**
  78.     * The maximun length for a BIFF record. See _addContinue()
  79.     * @var integer 
  80.     * @see _addContinue()
  81.     */
  82.     var $_limit;
  83.  
  84.     /**
  85.     * Constructor
  86.     *
  87.     * @access public
  88.     */
  89.     {
  90.         $this->_byte_order = '';
  91.         $this->_data       = '';
  92.         $this->_datasize   = 0;
  93.         $this->_limit      = 2080;
  94.         // Set the byte order
  95.         $this->_setByteOrder();
  96.     }
  97.  
  98.     /**
  99.     * Determine the byte order and store it as class data to avoid
  100.     * recalculating it for each call to new().
  101.     *
  102.     * @access private
  103.     */
  104.     function _setByteOrder()
  105.     {
  106.         // Check if "pack" gives the required IEEE 64bit float
  107.         $teststr pack("d"1.2345);
  108.         $number  pack("C8"0x8D0x970x6E0x120x830xC00xF30x3F);
  109.         if ($number == $teststr{
  110.             $byte_order 0;    // Little Endian
  111.         elseif ($number == strrev($teststr)){
  112.             $byte_order 1;    // Big Endian
  113.         else {
  114.             // Give up. I'll fix this in a later version.
  115.             throw new Exception("Required floating point format ".
  116.                                      "not supported on this platform.");
  117.         }
  118.         $this->_byte_order = $byte_order;
  119.     }
  120.  
  121.     /**
  122.     * General storage function
  123.     *
  124.     * @param string $data binary data to prepend
  125.     * @access private
  126.     */
  127.     function _prepend($data)
  128.     {
  129.         if (strlen($data$this->_limit{
  130.             $data $this->_addContinue($data);
  131.         }
  132.         $this->_data      = $data.$this->_data;
  133.         $this->_datasize += strlen($data);
  134.     }
  135.  
  136.     /**
  137.     * General storage function
  138.     *
  139.     * @param string $data binary data to append
  140.     * @access private
  141.     */
  142.     function _append($data)
  143.     {
  144.         if (strlen($data$this->_limit{
  145.             $data $this->_addContinue($data);
  146.         }
  147.         $this->_data      = $this->_data.$data;
  148.         $this->_datasize += strlen($data);
  149.     }
  150.  
  151.     /**
  152.     * General storage function like _append and _prepend, but returns string instead of modifying $this->_data
  153.     *
  154.     * @param string $data binary data to write
  155.     * @return string 
  156.     */
  157.     public function writeData($data)
  158.     {
  159.         if (strlen($data$this->_limit{
  160.             $data $this->_addContinue($data);
  161.         }
  162.         //$this->_data      = $this->_data.$data;
  163.         $this->_datasize += strlen($data);
  164.         
  165.         return $data;
  166.     }
  167.  
  168.     /**
  169.     * Writes Excel BOF record to indicate the beginning of a stream or
  170.     * sub-stream in the BIFF file.
  171.     *
  172.     * @param  integer $type Type of BIFF file to write: 0x0005 Workbook,
  173.     *                        0x0010 Worksheet.
  174.     * @access private
  175.     */
  176.     function _storeBof($type)
  177.     {
  178.         $record  0x0809;        // Record identifier
  179.  
  180.         // According to the SDK $build and $year should be set to zero.
  181.         // However, this throws a warning in Excel 5. So, use magic numbers.
  182.         if ($this->_BIFF_version == 0x0500{
  183.             $length  0x0008;
  184.             $unknown '';
  185.             $build   0x096C;
  186.             $year    0x07C9;
  187.         elseif ($this->_BIFF_version == 0x0600{
  188.             $length  0x0010;
  189.             $unknown pack("VV"0x000000410x00000006)//unknown last 8 bytes for BIFF8
  190.             $build   0x0DBB;
  191.             $year    0x07CC;
  192.         }
  193.         $version $this->_BIFF_version;
  194.  
  195.         $header  pack("vv",   $record$length);
  196.         $data    pack("vvvv"$version$type$build$year);
  197.         $this->_prepend($header $data $unknown);
  198.     }
  199.  
  200.     /**
  201.     * Writes Excel EOF record to indicate the end of a BIFF stream.
  202.     *
  203.     * @access private
  204.     */
  205.     function _storeEof()
  206.     {
  207.         $record    0x000A;   // Record identifier
  208.         $length    0x0000;   // Number of bytes to follow
  209.         $header    pack("vv"$record$length);
  210.         $this->_append($header);
  211.     }
  212.  
  213.     /**
  214.     * Writes Excel EOF record to indicate the end of a BIFF stream.
  215.     *
  216.     * @access private
  217.     */
  218.     public function writeEof()
  219.     {
  220.         $record    0x000A;   // Record identifier
  221.         $length    0x0000;   // Number of bytes to follow
  222.         $header    pack("vv"$record$length);
  223.         return $this->writeData($header);
  224.     }
  225.  
  226.     /**
  227.     * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In
  228.     * Excel 97 the limit is 8228 bytes. Records that are longer than these limits
  229.     * must be split up into CONTINUE blocks.
  230.     *
  231.     * This function takes a long BIFF record and inserts CONTINUE records as
  232.     * necessary.
  233.     *
  234.     * @param  string  $data The original binary data to be written
  235.     * @return string        A very convenient string of continue blocks
  236.     * @access private
  237.     */
  238.     function _addContinue($data)
  239.     {
  240.         $limit  $this->_limit;
  241.         $record 0x003C;         // Record identifier
  242.  
  243.         // The first 2080/8224 bytes remain intact. However, we have to change
  244.         // the length field of the record.
  245.         $tmp substr($data02).pack("v"$limit-4).substr($data4$limit 4);
  246.  
  247.         $header pack("vv"$record$limit);  // Headers for continue records
  248.  
  249.         // Retrieve chunks of 2080/8224 bytes +4 for the header.
  250.         $data_length strlen($data);
  251.         for ($i $limit$i <  ($data_length $limit)$i += $limit{
  252.             $tmp .= $header;
  253.             $tmp .= substr($data$i$limit);
  254.         }
  255.  
  256.         // Retrieve the last chunk of data
  257.         $header  pack("vv"$recordstrlen($data$i);
  258.         $tmp    .= $header;
  259.         $tmp    .= substr($data$istrlen($data$i);
  260.  
  261.         return $tmp;
  262.     }
  263. }

Documentation generated on Mon, 05 Jan 2009 20:36:27 +0100 by phpDocumentor 1.4.1