File Source for BIFFwriter.php

PHPExcel_Writer_Excel5

# Source for file BIFFwriter.php

Documentation is available at BIFFwriter.php

1. <?php
2. /**
3. * PHPExcel
4. *
5. * Copyright (c) 2006 - 2011 PHPExcel
6. *
7. * This library is free software; you can redistribute it and/or
8. * modify it under the terms of the GNU Lesser General Public
9. * License as published by the Free Software Foundation; either
10. * version 2.1 of the License, or (at your option) any later version.
11. *
12. * This library is distributed in the hope that it will be useful,
13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15. * Lesser General Public License for more details.
16. *
17. * You should have received a copy of the GNU Lesser General Public
18. * License along with this library; if not, write to the Free Software
19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20. *
21. * @category PHPExcel
22. * @package PHPExcel_Writer_Excel5
23. * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25. * @version 1.7.6, 2011-02-27
26. */
28. // Original file header of PEAR::Spreadsheet_Excel_Writer_BIFFwriter (used as the base for this class):
29. // -----------------------------------------------------------------------------------------
30. // * Module written/ported by Xavier Noguer <xnoguer@rezebra.com>
31. // *
32. // * The majority of this is _NOT_ my code. I simply ported it from the
33. // * PERL Spreadsheet::WriteExcel module.
34. // *
35. // * The author of the Spreadsheet::WriteExcel module is John McNamara
36. // * <jmcnamara@cpan.org>
37. // *
38. // * I _DO_ maintain this code, and John McNamara has nothing to do with the
39. // * porting of this code to PHP. Any questions directly related to this
40. // * class library should be directed to me.
41. // *
42. // * License Information:
43. // *
44. // * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
45. // * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com
46. // *
47. // * This library is free software; you can redistribute it and/or
48. // * modify it under the terms of the GNU Lesser General Public
49. // * License as published by the Free Software Foundation; either
50. // * version 2.1 of the License, or (at your option) any later version.
51. // *
52. // * This library is distributed in the hope that it will be useful,
53. // * but WITHOUT ANY WARRANTY; without even the implied warranty of
54. // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55. // * Lesser General Public License for more details.
56. // *
57. // * You should have received a copy of the GNU Lesser General Public
58. // * License along with this library; if not, write to the Free Software
59. // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
60. // */
63. /**
64. * PHPExcel_Writer_Excel5_BIFFwriter
65. *
66. * @category PHPExcel
67. * @package PHPExcel_Writer_Excel5
68. * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
69. */
70. class PHPExcel_Writer_Excel5_BIFFwriter
71. {
72. /**
73. * The BIFF/Excel version (5).
74. * @var integer
75. */
76. public $_BIFF_version = 0x0500;
78. /**
79. * The byte order of this architecture. 0 => little endian, 1 => big endian
80. * @var integer
81. */
82. private static $_byte_order;
84. /**
85. * The string containing the data of the BIFF stream
86. * @var string
87. */
88. public $_data;
90. /**
91. * The size of the data in bytes. Should be the same as strlen($this->_data)
92. * @var integer
93. */
94. public $_datasize;
96. /**
97. * The maximum length for a BIFF record (excluding record header and length field). See _addContinue()
98. * @var integer
99. * @see _addContinue()
100. */
101. public $_limit;
103. /**
104. * Constructor
105. */
106. public function __construct()
107. {
108. $this->_data = '';
109. $this->_datasize = 0;
110. $this->_limit = 2080;
111. }
113. /**
114. * Determine the byte order and store it as class data to avoid
115. * recalculating it for each call to new().
116. *
117. * @return int
118. */
119. public static function getByteOrder()
120. {
121. if (!isset(self::$_byte_order)) {
122. // Check if "pack" gives the required IEEE 64bit float
123. $teststr = pack("d", 1.2345);
124. $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F);
125. if ($number == $teststr) {
126. $byte_order = 0; // Little Endian
127. } elseif ($number == strrev($teststr)){
128. $byte_order = 1; // Big Endian
129. } else {
130. // Give up. I'll fix this in a later version.
131. throw new Exception("Required floating point format ".
132. "not supported on this platform.");
133. }
134. self::$_byte_order = $byte_order;
135. }
137. return self::$_byte_order;
138. }
140. /**
141. * General storage function
142. *
143. * @param string $data binary data to append
144. * @access private
145. */
146. function _append($data)
147. {
148. if (strlen($data) - 4 > $this->_limit) {
149. $data = $this->_addContinue($data);
150. }
151. $this->_data .= $data;
152. $this->_datasize += strlen($data);
153. }
155. /**
156. * General storage function like _append, but returns string instead of modifying $this->_data
157. *
158. * @param string $data binary data to write
159. * @return string
160. */
161. public function writeData($data)
162. {
163. if ( strlen($data) - 4 > $this->_limit) {
164. $data = $this->_addContinue($data);
165. }
166. $this->_datasize += strlen($data);
168. return $data;
169. }
171. /**
172. * Writes Excel BOF record to indicate the beginning of a stream or
173. * sub-stream in the BIFF file.
174. *
175. * @param integer $type Type of BIFF file to write: 0x0005 Workbook,
176. * 0x0010 Worksheet.
177. * @access private
178. */
179. function _storeBof($type)
180. {
181. $record = 0x0809; // Record identifier
183. // According to the SDK $build and $year should be set to zero.
184. // However, this throws a warning in Excel 5. So, use magic numbers.
185. if ($this->_BIFF_version == 0x0500) {
186. $length = 0x0008;
187. $unknown = '';
188. $build = 0x096C;
189. $year = 0x07C9;
190. } elseif ($this->_BIFF_version == 0x0600) {
191. $length = 0x0010;
193. // by inspection of real files, MS Office Excel 2007 writes the following
194. $unknown = pack("VV", 0x000100D1, 0x00000406);
196. $build = 0x0DBB;
197. $year = 0x07CC;
198. }
199. $version = $this->_BIFF_version;
201. $header = pack("vv", $record, $length);
202. $data = pack("vvvv", $version, $type, $build, $year);
203. $this->_append($header . $data . $unknown);
204. }
206. /**
207. * Writes Excel EOF record to indicate the end of a BIFF stream.
208. *
209. * @access private
210. */
211. function _storeEof()
212. {
213. $record = 0x000A; // Record identifier
214. $length = 0x0000; // Number of bytes to follow
215. $header = pack("vv", $record, $length);
216. $this->_append($header);
217. }
219. /**
220. * Writes Excel EOF record to indicate the end of a BIFF stream.
221. *
222. * @access private
223. */
224. public function writeEof()
225. {
226. $record = 0x000A; // Record identifier
227. $length = 0x0000; // Number of bytes to follow
228. $header = pack("vv", $record, $length);
229. return $this-> writeData($header);
230. }
232. /**
233. * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In
234. * Excel 97 the limit is 8228 bytes. Records that are longer than these limits
235. * must be split up into CONTINUE blocks.
236. *
237. * This function takes a long BIFF record and inserts CONTINUE records as
238. * necessary.
239. *
240. * @param string $data The original binary data to be written
241. * @return string A very convenient string of continue blocks
242. * @access private
243. */
244. function _addContinue($data)
245. {
246. $limit = $this->_limit;
247. $record = 0x003C; // Record identifier
249. // The first 2080/8224 bytes remain intact. However, we have to change
250. // the length field of the record.
251. $tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit);
253. $header = pack("vv", $record, $limit); // Headers for continue records
255. // Retrieve chunks of 2080/8224 bytes +4 for the header.
256. $data_length = strlen($data);
257. for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) {
258. $tmp .= $header;
259. $tmp .= substr($data, $i, $limit);
260. }
262. // Retrieve the last chunk of data
263. $header = pack("vv", $record, strlen($data) - $i);
264. $tmp .= $header;
265. $tmp .= substr($data, $i, strlen($data) - $i);
267. return $tmp;
268. }
270. }

Documentation generated on Sun, 27 Feb 2011 16:28:33 -0800 by phpDocumentor 1.4.3