Advertisement
arifh28

biffwriter phpexcel

Nov 1st, 2015
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.82 KB | None | 0 0
  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. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement