|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 /* 00003 * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> 00004 * 00005 * The majority of this is _NOT_ my code. I simply ported it from the 00006 * PERL Spreadsheet::WriteExcel module. 00007 * 00008 * The author of the Spreadsheet::WriteExcel module is John McNamara 00009 * <jmcnamara@cpan.org> 00010 * 00011 * I _DO_ maintain this code, and John McNamara has nothing to do with the 00012 * porting of this code to PHP. Any questions directly related to this 00013 * class library should be directed to me. 00014 * 00015 * License Information: 00016 * 00017 * Spreadsheet::WriteExcel: A library for generating Excel Spreadsheets 00018 * Copyright (C) 2002 Xavier Noguer xnoguer@rezebra.com 00019 * 00020 * This library is free software; you can redistribute it and/or 00021 * modify it under the terms of the GNU Lesser General Public 00022 * License as published by the Free Software Foundation; either 00023 * version 2.1 of the License, or (at your option) any later version. 00024 * 00025 * This library is distributed in the hope that it will be useful, 00026 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00027 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00028 * Lesser General Public License for more details. 00029 * 00030 * You should have received a copy of the GNU Lesser General Public 00031 * License along with this library; if not, write to the Free Software 00032 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00033 */ 00034 00041 class OLEwriter 00042 { 00048 var $_OLEfilename; 00049 00054 var $_filehandle; 00055 00060 var $_tmp_filename; 00061 00066 var $_fileclosed; 00067 00072 var $_biffsize; 00073 00078 var $_booksize; 00079 00084 var $_big_blocks; 00085 00090 var $_list_blocks; 00091 00096 var $_root_start; 00097 00103 function OLEwriter($OLEfilename) 00104 { 00105 $this->_OLEfilename = $OLEfilename; 00106 $this->_filehandle = ""; 00107 $this->_tmp_filename = ""; 00108 $this->_fileclosed = 0; 00109 //$this->_size_allowed = 0; 00110 $this->_biffsize = 0; 00111 $this->_booksize = 0; 00112 $this->_big_blocks = 0; 00113 $this->_list_blocks = 0; 00114 $this->_root_start = 0; 00115 //$this->_block_count = 4; 00116 $this->_initialize(); 00117 } 00118 00123 function _initialize() 00124 { 00125 $OLEfile = $this->_OLEfilename; 00126 00127 if(($OLEfile == '-') or ($OLEfile == '')) 00128 { 00129 $this->_tmp_filename = tempnam("/tmp", "OLEwriter"); 00130 $fh = fopen($this->_tmp_filename,"wb"); 00131 if ($fh == false) { 00132 die("Can't create temporary file."); 00133 } 00134 } 00135 else 00136 { 00137 // Create a new file, open for writing (in binmode) 00138 $fh = fopen($OLEfile,"wb"); 00139 if ($fh == false) { 00140 die("Can't open $OLEfile. It may be in use or protected."); 00141 } 00142 } 00143 00144 // Store filehandle 00145 $this->_filehandle = $fh; 00146 } 00147 00148 00161 function set_size($biffsize) 00162 { 00163 $maxsize = 7087104; // TODO: extend max size 00164 00165 if ($biffsize > $maxsize) { 00166 die("Maximum file size, $maxsize, exceeded."); 00167 } 00168 00169 $this->_biffsize = $biffsize; 00170 // Set the min file size to 4k to avoid having to use small blocks 00171 if ($biffsize > 4096) { 00172 $this->_booksize = $biffsize; 00173 } 00174 else { 00175 $this->_booksize = 4096; 00176 } 00177 //$this->_size_allowed = 1; 00178 return(1); 00179 } 00180 00181 00185 function _calculate_sizes() 00186 { 00187 $datasize = $this->_booksize; 00188 if ($datasize % 512 == 0) { 00189 $this->_big_blocks = $datasize/512; 00190 } 00191 else { 00192 $this->_big_blocks = floor($datasize/512) + 1; 00193 } 00194 // There are 127 list blocks and 1 marker blocks for each big block 00195 // depot + 1 end of chain block 00196 $this->_list_blocks = floor(($this->_big_blocks)/127) + 1; 00197 $this->_root_start = $this->_big_blocks; 00198 } 00199 00208 function close() 00209 { 00210 //return if not $this->{_size_allowed}; 00211 $this->_write_padding(); 00212 $this->_write_property_storage(); 00213 $this->_write_big_block_depot(); 00214 // Close the filehandle 00215 fclose($this->_filehandle); 00216 if(($this->_OLEfilename == '-') or ($this->_OLEfilename == '')) 00217 { 00218 $fh = fopen($this->_tmp_filename, "rb"); 00219 if ($fh == false) { 00220 die("Can't read temporary file."); 00221 } 00222 fpassthru($fh); 00223 // Delete the temporary file. 00224 @unlink($this->_tmp_filename); 00225 } 00226 $this->_fileclosed = 1; 00227 } 00228 00229 00235 function write($data) //por ahora s�lo a STDOUT 00236 { 00237 fwrite($this->_filehandle,$data,strlen($data)); 00238 } 00239 00240 00244 function write_header() 00245 { 00246 $this->_calculate_sizes(); 00247 $root_start = $this->_root_start; 00248 $num_lists = $this->_list_blocks; 00249 $id = pack("nnnn", 0xD0CF, 0x11E0, 0xA1B1, 0x1AE1); 00250 $unknown1 = pack("VVVV", 0x00, 0x00, 0x00, 0x00); 00251 $unknown2 = pack("vv", 0x3E, 0x03); 00252 $unknown3 = pack("v", -2); 00253 $unknown4 = pack("v", 0x09); 00254 $unknown5 = pack("VVV", 0x06, 0x00, 0x00); 00255 $num_bbd_blocks = pack("V", $num_lists); 00256 $root_startblock = pack("V", $root_start); 00257 $unknown6 = pack("VV", 0x00, 0x1000); 00258 $sbd_startblock = pack("V", -2); 00259 $unknown7 = pack("VVV", 0x00, -2 ,0x00); 00260 $unused = pack("V", -1); 00261 00262 fwrite($this->_filehandle,$id); 00263 fwrite($this->_filehandle,$unknown1); 00264 fwrite($this->_filehandle,$unknown2); 00265 fwrite($this->_filehandle,$unknown3); 00266 fwrite($this->_filehandle,$unknown4); 00267 fwrite($this->_filehandle,$unknown5); 00268 fwrite($this->_filehandle,$num_bbd_blocks); 00269 fwrite($this->_filehandle,$root_startblock); 00270 fwrite($this->_filehandle,$unknown6); 00271 fwrite($this->_filehandle,$sbd_startblock); 00272 fwrite($this->_filehandle,$unknown7); 00273 00274 for($i=1; $i <= $num_lists; $i++) 00275 { 00276 $root_start++; 00277 fwrite($this->_filehandle,pack("V",$root_start)); 00278 } 00279 for($i = $num_lists; $i <=108; $i++) 00280 { 00281 fwrite($this->_filehandle,$unused); 00282 } 00283 } 00284 00285 00289 function _write_big_block_depot() 00290 { 00291 $num_blocks = $this->_big_blocks; 00292 $num_lists = $this->_list_blocks; 00293 $total_blocks = $num_lists *128; 00294 $used_blocks = $num_blocks + $num_lists +2; 00295 00296 $marker = pack("V", -3); 00297 $end_of_chain = pack("V", -2); 00298 $unused = pack("V", -1); 00299 00300 for($i=1; $i < $num_blocks; $i++) 00301 { 00302 fwrite($this->_filehandle,pack("V",$i)); 00303 } 00304 fwrite($this->_filehandle,$end_of_chain); 00305 fwrite($this->_filehandle,$end_of_chain); 00306 for($i=0; $i < $num_lists; $i++) 00307 { 00308 fwrite($this->_filehandle,$marker); 00309 } 00310 for($i=$used_blocks; $i <= $total_blocks; $i++) 00311 { 00312 fwrite($this->_filehandle,$unused); 00313 } 00314 } 00315 00319 function _write_property_storage() 00320 { 00321 //$rootsize = -2; 00322 /*************** name type dir start size */ 00323 $this->_write_pps("Root Entry", 0x05, 1, -2, 0x00); 00324 $this->_write_pps("Book", 0x02, -1, 0x00, $this->_booksize); 00325 $this->_write_pps('', 0x00, -1, 0x00, 0x0000); 00326 $this->_write_pps('', 0x00, -1, 0x00, 0x0000); 00327 } 00328 00339 function _write_pps($name,$type,$dir,$start,$size) 00340 { 00341 $length = 0; 00342 $rawname = ''; 00343 00344 if ($name != '') 00345 { 00346 $name = $name . "\0"; 00347 for($i=0;$i<strlen($name);$i++) 00348 { 00349 // Simulate a Unicode string 00350 $rawname .= pack("H*",dechex(ord($name{$i}))).pack("C",0); 00351 } 00352 $length = strlen($name) * 2; 00353 } 00354 00355 $zero = pack("C", 0); 00356 $pps_sizeofname = pack("v", $length); // 0x40 00357 $pps_type = pack("v", $type); // 0x42 00358 $pps_prev = pack("V", -1); // 0x44 00359 $pps_next = pack("V", -1); // 0x48 00360 $pps_dir = pack("V", $dir); // 0x4c 00361 00362 $unknown1 = pack("V", 0); 00363 00364 $pps_ts1s = pack("V", 0); // 0x64 00365 $pps_ts1d = pack("V", 0); // 0x68 00366 $pps_ts2s = pack("V", 0); // 0x6c 00367 $pps_ts2d = pack("V", 0); // 0x70 00368 $pps_sb = pack("V", $start); // 0x74 00369 $pps_size = pack("V", $size); // 0x78 00370 00371 00372 fwrite($this->_filehandle,$rawname); 00373 for($i=0; $i < (64 -$length); $i++) { 00374 fwrite($this->_filehandle,$zero); 00375 } 00376 fwrite($this->_filehandle,$pps_sizeofname); 00377 fwrite($this->_filehandle,$pps_type); 00378 fwrite($this->_filehandle,$pps_prev); 00379 fwrite($this->_filehandle,$pps_next); 00380 fwrite($this->_filehandle,$pps_dir); 00381 for($i=0; $i < 5; $i++) { 00382 fwrite($this->_filehandle,$unknown1); 00383 } 00384 fwrite($this->_filehandle,$pps_ts1s); 00385 fwrite($this->_filehandle,$pps_ts1d); 00386 fwrite($this->_filehandle,$pps_ts2d); 00387 fwrite($this->_filehandle,$pps_ts2d); 00388 fwrite($this->_filehandle,$pps_sb); 00389 fwrite($this->_filehandle,$pps_size); 00390 fwrite($this->_filehandle,$unknown1); 00391 } 00392 00396 function _write_padding() 00397 { 00398 $biffsize = $this->_biffsize; 00399 if ($biffsize < 4096) { 00400 $min_size = 4096; 00401 } 00402 else { 00403 $min_size = 512; 00404 } 00405 if ($biffsize % $min_size != 0) 00406 { 00407 $padding = $min_size - ($biffsize % $min_size); 00408 for($i=0; $i < $padding; $i++) { 00409 fwrite($this->_filehandle,"\0"); 00410 } 00411 } 00412 } 00413 } 00414 ?>