[ Index ] |
|
Code source de vtiger CRM 5.0.2 |
1 <?php 2 3 /* 4 * Copyleft 2002 Johann Hanne 5 * 6 * This is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This software is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this software; if not, write to the 18 * Free Software Foundation, Inc., 59 Temple Place, 19 * Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 /* 23 * This is the Spreadsheet::WriteExcel Perl package ported to PHP 24 * Spreadsheet::WriteExcel was written by John McNamara, jmcnamara@cpan.org 25 */ 26 27 class writeexcel_olewriter { 28 var $_OLEfilename; 29 var $_OLEtmpfilename; /* ABR */ 30 var $_filehandle; 31 var $_fileclosed; 32 var $_internal_fh; 33 var $_biff_only; 34 var $_size_allowed; 35 var $_biffsize; 36 var $_booksize; 37 var $_big_blocks; 38 var $_list_blocks; 39 var $_root_start; 40 var $_block_count; 41 42 /* 43 * Constructor 44 */ 45 function writeexcel_olewriter($filename) { 46 47 $this->_OLEfilename = $filename; 48 $this->_filehandle = false; 49 $this->_fileclosed = 0; 50 $this->_internal_fh = 0; 51 $this->_biff_only = 0; 52 $this->_size_allowed = 0; 53 $this->_biffsize = 0; 54 $this->_booksize = 0; 55 $this->_big_blocks = 0; 56 $this->_list_blocks = 0; 57 $this->_root_start = 0; 58 $this->_block_count = 4; 59 60 $this->_initialize(); 61 } 62 63 /* 64 * Check for a valid filename and store the filehandle. 65 */ 66 function _initialize() { 67 $OLEfile = $this->_OLEfilename; 68 69 /* Check for a filename. Workbook.pm will catch this first. */ 70 if ($OLEfile == '') { 71 trigger_error("Filename required", E_USER_ERROR); 72 } 73 74 /* 75 * If the filename is a resource it is assumed that it is a valid 76 * filehandle, if not we create a filehandle. 77 */ 78 if (is_resource($OLEfile)) { 79 $fh = $OLEfile; 80 } else { 81 // Create a new file, open for writing 82 $fh = fopen($OLEfile, "wb"); 83 // The workbook class also checks this but something may have 84 // happened since then. 85 if (!$fh) { 86 trigger_error("Can't open $OLEfile. It may be in use or ". 87 "protected", E_USER_ERROR); 88 } 89 90 $this->_internal_fh = 1; 91 } 92 93 // Store filehandle 94 $this->_filehandle = $fh; 95 } 96 97 /* 98 * Set the size of the data to be written to the OLE stream 99 * 100 * $big_blocks = (109 depot block x (128 -1 marker word) 101 * - (1 x end words)) = 13842 102 * $maxsize = $big_blocks * 512 bytes = 7087104 103 */ 104 function set_size($size) { 105 $maxsize = 7087104; 106 107 if ($size > $maxsize) { 108 trigger_error("Maximum file size, $maxsize, exceeded. To create ". 109 "files bigger than this limit please use the ". 110 "workbookbig class.", E_USER_ERROR); 111 return ($this->_size_allowed = 0); 112 } 113 114 $this->_biffsize = $size; 115 116 // Set the min file size to 4k to avoid having to use small blocks 117 if ($size > 4096) { 118 $this->_booksize = $size; 119 } else { 120 $this->_booksize = 4096; 121 } 122 123 return ($this->_size_allowed = 1); 124 } 125 126 /* 127 * Calculate various sizes needed for the OLE stream 128 */ 129 function _calculate_sizes() { 130 $datasize = $this->_booksize; 131 132 if ($datasize % 512 == 0) { 133 $this->_big_blocks = $datasize/512; 134 } else { 135 $this->_big_blocks = floor($datasize/512)+1; 136 } 137 // There are 127 list blocks and 1 marker blocks for each big block 138 // depot + 1 end of chain block 139 $this->_list_blocks = floor(($this->_big_blocks)/127)+1; 140 $this->_root_start = $this->_big_blocks; 141 142 //print $this->_biffsize. "\n"; 143 //print $this->_big_blocks. "\n"; 144 //print $this->_list_blocks. "\n"; 145 } 146 147 /* 148 * Write root entry, big block list and close the filehandle. 149 * This method must be called so that the file contents are 150 * actually written. 151 */ 152 function close() { 153 154 if (!$this->_size_allowed) { 155 return; 156 } 157 158 if (!$this->_biff_only) { 159 $this->_write_padding(); 160 $this->_write_property_storage(); 161 $this->_write_big_block_depot(); 162 } 163 164 // Close the filehandle if it was created internally. 165 if ($this->_internal_fh) { 166 fclose($this->_filehandle); 167 } 168 /* ABR */ 169 if ($this->_OLEtmpfilename != '') { 170 $fh = fopen($this->_OLEtmpfilename, "rb"); 171 if ($fh == false) { 172 trigger_error("Can't read temporary file.", E_USER_ERROR); 173 } 174 fpassthru($fh); 175 fclose($fh); 176 unlink($this->_OLEtmpfilename); 177 }; 178 179 $this->_fileclosed = 1; 180 } 181 182 /* 183 * Write BIFF data to OLE file. 184 */ 185 function write($data) { 186 fputs($this->_filehandle, $data); 187 } 188 189 /* 190 * Write OLE header block. 191 */ 192 function write_header() { 193 if ($this->_biff_only) { 194 return; 195 } 196 197 $this->_calculate_sizes(); 198 199 $root_start = $this->_root_start; 200 $num_lists = $this->_list_blocks; 201 202 $id = pack("C8", 0xD0, 0xCF, 0x11, 0xE0, 203 0xA1, 0xB1, 0x1A, 0xE1); 204 $unknown1 = pack("VVVV", 0x00, 0x00, 0x00, 0x00); 205 $unknown2 = pack("vv", 0x3E, 0x03); 206 $unknown3 = pack("v", -2); 207 $unknown4 = pack("v", 0x09); 208 $unknown5 = pack("VVV", 0x06, 0x00, 0x00); 209 $num_bbd_blocks = pack("V", $num_lists); 210 $root_startblock = pack("V", $root_start); 211 $unknown6 = pack("VV", 0x00, 0x1000); 212 $sbd_startblock = pack("V", -2); 213 $unknown7 = pack("VVV", 0x00, -2 ,0x00); 214 $unused = pack("V", -1); 215 216 fputs($this->_filehandle, $id); 217 fputs($this->_filehandle, $unknown1); 218 fputs($this->_filehandle, $unknown2); 219 fputs($this->_filehandle, $unknown3); 220 fputs($this->_filehandle, $unknown4); 221 fputs($this->_filehandle, $unknown5); 222 fputs($this->_filehandle, $num_bbd_blocks); 223 fputs($this->_filehandle, $root_startblock); 224 fputs($this->_filehandle, $unknown6); 225 fputs($this->_filehandle, $sbd_startblock); 226 fputs($this->_filehandle, $unknown7); 227 228 for ($c=1;$c<=$num_lists;$c++) { 229 $root_start++; 230 fputs($this->_filehandle, pack("V", $root_start)); 231 } 232 233 for ($c=$num_lists;$c<=108;$c++) { 234 fputs($this->_filehandle, $unused); 235 } 236 } 237 238 /* 239 * Write big block depot. 240 */ 241 function _write_big_block_depot() { 242 $num_blocks = $this->_big_blocks; 243 $num_lists = $this->_list_blocks; 244 $total_blocks = $num_lists * 128; 245 $used_blocks = $num_blocks + $num_lists + 2; 246 247 $marker = pack("V", -3); 248 $end_of_chain = pack("V", -2); 249 $unused = pack("V", -1); 250 251 for ($i=1;$i<=($num_blocks-1);$i++) { 252 fputs($this->_filehandle, pack("V", $i)); 253 } 254 255 fputs($this->_filehandle, $end_of_chain); 256 fputs($this->_filehandle, $end_of_chain); 257 258 for ($c=1;$c<=$num_lists;$c++) { 259 fputs($this->_filehandle, $marker); 260 } 261 262 for ($c=$used_blocks;$c<=$total_blocks;$c++) { 263 fputs($this->_filehandle, $unused); 264 } 265 } 266 267 /* 268 * Write property storage. TODO: add summary sheets 269 */ 270 function _write_property_storage() { 271 $rootsize = -2; 272 $booksize = $this->_booksize; 273 274 // name type dir start size 275 $this->_write_pps('Root Entry', 0x05, 1, -2, 0x00); 276 $this->_write_pps('Book', 0x02, -1, 0x00, $booksize); 277 $this->_write_pps('', 0x00, -1, 0x00, 0x0000); 278 $this->_write_pps('', 0x00, -1, 0x00, 0x0000); 279 } 280 281 /* 282 * Write property sheet in property storage 283 */ 284 function _write_pps($name, $type, $dir, $start, $size) { 285 $names = array(); 286 $length = 0; 287 288 if ($name != '') { 289 $name = $name . "\0"; 290 // Simulate a Unicode string 291 $chars=preg_split("''", $name, -1, PREG_SPLIT_NO_EMPTY); 292 foreach ($chars as $char) { 293 array_push($names, ord($char)); 294 } 295 $length = strlen($name) * 2; 296 } 297 298 $rawname = call_user_func_array('pack', array_merge(array("v*"), $names)); 299 $zero = pack("C", 0); 300 301 $pps_sizeofname = pack("v", $length); //0x40 302 $pps_type = pack("v", $type); //0x42 303 $pps_prev = pack("V", -1); //0x44 304 $pps_next = pack("V", -1); //0x48 305 $pps_dir = pack("V", $dir); //0x4c 306 307 $unknown1 = pack("V", 0); 308 309 $pps_ts1s = pack("V", 0); //0x64 310 $pps_ts1d = pack("V", 0); //0x68 311 $pps_ts2s = pack("V", 0); //0x6c 312 $pps_ts2d = pack("V", 0); //0x70 313 $pps_sb = pack("V", $start); //0x74 314 $pps_size = pack("V", $size); //0x78 315 316 fputs($this->_filehandle, $rawname); 317 fputs($this->_filehandle, str_repeat($zero, (64-$length))); 318 fputs($this->_filehandle, $pps_sizeofname); 319 fputs($this->_filehandle, $pps_type); 320 fputs($this->_filehandle, $pps_prev); 321 fputs($this->_filehandle, $pps_next); 322 fputs($this->_filehandle, $pps_dir); 323 fputs($this->_filehandle, str_repeat($unknown1, 5)); 324 fputs($this->_filehandle, $pps_ts1s); 325 fputs($this->_filehandle, $pps_ts1d); 326 fputs($this->_filehandle, $pps_ts2d); 327 fputs($this->_filehandle, $pps_ts2d); 328 fputs($this->_filehandle, $pps_sb); 329 fputs($this->_filehandle, $pps_size); 330 fputs($this->_filehandle, $unknown1); 331 } 332 333 /* 334 * Pad the end of the file 335 */ 336 function _write_padding() { 337 $biffsize = $this->_biffsize; 338 339 if ($biffsize < 4096) { 340 $min_size = 4096; 341 } else { 342 $min_size = 512; 343 } 344 345 if ($biffsize % $min_size != 0) { 346 $padding = $min_size - ($biffsize % $min_size); 347 fputs($this->_filehandle, str_repeat("\0", $padding)); 348 } 349 } 350 351 } 352 353 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 10:22:19 2007 | par Balluche grâce à PHPXref 0.7 |