00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 require_once('classes/Spreadsheet/Excel/Writer/Parser.php');
00036 require_once('classes/Spreadsheet/Excel/Writer/BIFFwriter.php');
00037
00046 class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwriter
00047 {
00052 var $name;
00053
00058 var $index;
00059
00064 var $_url_format;
00065
00070 var $_parser;
00071
00076 var $_filehandle;
00077
00082 var $_using_tmpfile;
00083
00088 var $_xls_rowmax;
00089
00094 var $_xls_colmax;
00095
00100 var $_xls_strmax;
00101
00107 var $_dim_rowmin;
00108
00114 var $_dim_rowmax;
00115
00121 var $_dim_colmin;
00122
00128 var $_dim_colmax;
00129
00134 var $_colinfo;
00135
00140 var $_selection;
00141
00146 var $_panes;
00147
00152 var $_active_pane;
00153
00158 var $_frozen;
00159
00164 var $selected;
00165
00170 var $_paper_size;
00171
00176 var $_orientation;
00177
00182 var $_header;
00183
00188 var $_footer;
00189
00194 var $_hcenter;
00195
00200 var $_vcenter;
00201
00206 var $_margin_head;
00207
00212 var $_margin_foot;
00213
00218 var $_margin_left;
00219
00224 var $_margin_right;
00225
00230 var $_margin_top;
00231
00236 var $_margin_bottom;
00237
00242 var $title_rowmin;
00243
00248 var $title_rowmax;
00249
00254 var $title_colmin;
00255
00260 var $print_rowmin;
00261
00266 var $print_rowmax;
00267
00272 var $print_colmin;
00273
00278 var $print_colmax;
00279
00284 var $_outline_on;
00285
00290 var $_outline_style;
00291
00296 var $_outline_below;
00297
00302 var $_outline_right;
00303
00308 var $_outline_row_level;
00309
00314 var $_fit_page;
00315
00320 var $_fit_width;
00321
00326 var $_fit_height;
00327
00332 var $_str_total;
00333
00338 var $_str_unique;
00339
00344 var $_str_table;
00345
00350 var $_merged_ranges;
00351
00363 function Spreadsheet_Excel_Writer_Worksheet($BIFF_version, $name,
00364 $index, &$activesheet,
00365 &$firstsheet, &$str_total,
00366 &$str_unique, &$str_table,
00367 &$url_format, &$parser)
00368 {
00369
00370 $this->Spreadsheet_Excel_Writer_BIFFwriter();
00371 $this->_BIFF_version = $BIFF_version;
00372 $rowmax = 65536;
00373 $colmax = 256;
00374
00375 $this->name = $name;
00376 $this->index = $index;
00377 $this->activesheet = &$activesheet;
00378 $this->firstsheet = &$firstsheet;
00379 $this->_str_total = &$str_total;
00380 $this->_str_unique = &$str_unique;
00381 $this->_str_table = &$str_table;
00382 $this->_url_format = &$url_format;
00383 $this->_parser = &$parser;
00384
00385
00386 $this->_filehandle = "";
00387 $this->_using_tmpfile = true;
00388
00389
00390 $this->_xls_rowmax = $rowmax;
00391 $this->_xls_colmax = $colmax;
00392 $this->_xls_strmax = 255;
00393 $this->_dim_rowmin = $rowmax + 1;
00394 $this->_dim_rowmax = 0;
00395 $this->_dim_colmin = $colmax + 1;
00396 $this->_dim_colmax = 0;
00397 $this->_colinfo = array();
00398 $this->_selection = array(0,0,0,0);
00399 $this->_panes = array();
00400 $this->_active_pane = 3;
00401 $this->_frozen = 0;
00402 $this->selected = 0;
00403
00404 $this->_paper_size = 0x0;
00405 $this->_orientation = 0x1;
00406 $this->_header = '';
00407 $this->_footer = '';
00408 $this->_hcenter = 0;
00409 $this->_vcenter = 0;
00410 $this->_margin_head = 0.50;
00411 $this->_margin_foot = 0.50;
00412 $this->_margin_left = 0.75;
00413 $this->_margin_right = 0.75;
00414 $this->_margin_top = 1.00;
00415 $this->_margin_bottom = 1.00;
00416
00417 $this->title_rowmin = NULL;
00418 $this->title_rowmax = NULL;
00419 $this->title_colmin = NULL;
00420 $this->title_colmax = NULL;
00421 $this->print_rowmin = NULL;
00422 $this->print_rowmax = NULL;
00423 $this->print_colmin = NULL;
00424 $this->print_colmax = NULL;
00425
00426 $this->_print_gridlines = 1;
00427 $this->_print_headers = 0;
00428
00429 $this->_fit_page = 0;
00430 $this->_fit_width = 0;
00431 $this->_fit_height = 0;
00432
00433 $this->_hbreaks = array();
00434 $this->_vbreaks = array();
00435
00436 $this->_protect = 0;
00437 $this->_password = NULL;
00438
00439 $this->col_sizes = array();
00440 $this->row_sizes = array();
00441
00442 $this->_zoom = 100;
00443 $this->_print_scale = 100;
00444
00445 $this->_outline_row_level = 0;
00446 $this->_outline_style = 0;
00447 $this->_outline_below = 1;
00448 $this->_outline_right = 1;
00449 $this->_outline_on = 1;
00450
00451 $this->_merged_ranges = array();
00452
00453 $this->_dv = array();
00454
00455 $this->_initialize();
00456 }
00457
00465 function _initialize()
00466 {
00467 if ($this->_using_tmpfile == false) {
00468 return;
00469 }
00470
00471 $tmp_filename = @tempnam("", "Worksheet_Data");
00472 $fh = @fopen($tmp_filename, "w+b");
00473 if ( $fh) {
00474
00475 $this->_filehandle = $fh;
00476 }
00477 else {
00478
00479 $this->_using_tmpfile = false;
00480 }
00481 }
00482
00492 function close($sheetnames)
00493 {
00494 $num_sheets = count($sheetnames);
00495
00496
00497
00498
00499
00500
00501 $this->_storeDimensions();
00502
00503
00504 $this->_storePassword();
00505
00506
00507 $this->_storeProtect();
00508
00509
00510 $this->_storeSetup();
00511
00512
00513
00514 $this->_storeMarginBottom();
00515
00516
00517 $this->_storeMarginTop();
00518
00519
00520 $this->_storeMarginRight();
00521
00522
00523 $this->_storeMarginLeft();
00524
00525
00526 $this->_storeVcenter();
00527
00528
00529 $this->_storeHcenter();
00530
00531
00532 $this->_storeFooter();
00533
00534
00535 $this->_storeHeader();
00536
00537
00538 $this->_storeVbreak();
00539
00540
00541 $this->_storeHbreak();
00542
00543
00544 $this->_storeWsbool();
00545
00546
00547 $this->_storeGridset();
00548
00549
00550 if ($this->_BIFF_version == 0x0500) {
00551 $this->_storeGuts();
00552 }
00553
00554
00555 $this->_storePrintGridlines();
00556
00557
00558 $this->_storePrintHeaders();
00559
00560
00561 if ($this->_BIFF_version == 0x0500) {
00562 for ($i = $num_sheets; $i > 0; $i--) {
00563 $sheetname = $sheetnames[$i-1];
00564 $this->_storeExternsheet($sheetname);
00565 }
00566 }
00567
00568
00569 if ($this->_BIFF_version == 0x0500) {
00570 $this->_storeExterncount($num_sheets);
00571 }
00572
00573
00574 if (!empty($this->_colinfo))
00575 {
00576 for ($i=0; $i < count($this->_colinfo); $i++) {
00577 $this->_storeColinfo($this->_colinfo[$i]);
00578 }
00579 $this->_storeDefcol();
00580 }
00581
00582
00583 $this->_storeBof(0x0010);
00584
00585
00586
00587
00588
00589
00590 $this->_storeWindow2();
00591 $this->_storeZoom();
00592 if (!empty($this->_panes)) {
00593 $this->_storePanes($this->_panes);
00594 }
00595 $this->_storeSelection($this->_selection);
00596 $this->_storeMergedCells();
00597
00598
00599
00600
00601 $this->_storeEof();
00602 }
00603
00611 function getName()
00612 {
00613 return $this->name;
00614 }
00615
00622 function getData()
00623 {
00624 $buffer = 4096;
00625
00626
00627 if (isset($this->_data))
00628 {
00629 $tmp = $this->_data;
00630 unset($this->_data);
00631 $fh = $this->_filehandle;
00632 if ($this->_using_tmpfile) {
00633 fseek($fh, 0);
00634 }
00635 return $tmp;
00636 }
00637
00638 if ($this->_using_tmpfile)
00639 {
00640 if ($tmp = fread($this->_filehandle, $buffer)) {
00641 return $tmp;
00642 }
00643 }
00644
00645
00646 return '';
00647 }
00648
00658 function setMerge($first_row, $first_col, $last_row, $last_col)
00659 {
00660 if (($last_row < $first_row) or ($last_col < $first_col)) {
00661 return;
00662 }
00663
00664
00665 $this->_merged_ranges[] = array($first_row, $first_col, $last_row, $last_col);
00666 }
00667
00674 function select()
00675 {
00676 $this->selected = 1;
00677 }
00678
00686 function activate()
00687 {
00688 $this->selected = 1;
00689 $this->activesheet = $this->index;
00690 }
00691
00699 function setFirstSheet()
00700 {
00701 $this->firstsheet = $this->index;
00702 }
00703
00712 function protect($password)
00713 {
00714 $this->_protect = 1;
00715 $this->_password = $this->_encodePassword($password);
00716 }
00717
00729 function setColumn($firstcol, $lastcol, $width, $format = 0, $hidden = 0, $level = 0)
00730 {
00731 $this->_colinfo[] = array($firstcol, $lastcol, $width, &$format, $hidden, $level);
00732
00733
00734 $width = ($hidden) ? 0 : $width;
00735
00736 for ($col = $firstcol; $col <= $lastcol; $col++) {
00737 $this->col_sizes[$col] = $width;
00738 }
00739 }
00740
00750 function setSelection($first_row,$first_column,$last_row,$last_column)
00751 {
00752 $this->_selection = array($first_row,$first_column,$last_row,$last_column);
00753 }
00754
00766 function freezePanes($panes)
00767 {
00768 $this->_frozen = 1;
00769 $this->_panes = $panes;
00770 }
00771
00783 function thawPanes($panes)
00784 {
00785 $this->_frozen = 0;
00786 $this->_panes = $panes;
00787 }
00788
00794 function setPortrait()
00795 {
00796 $this->_orientation = 1;
00797 }
00798
00804 function setLandscape()
00805 {
00806 $this->_orientation = 0;
00807 }
00808
00815 function setPaper($size = 0)
00816 {
00817 $this->_paper_size = $size;
00818 }
00819
00820
00828 function setHeader($string,$margin = 0.50)
00829 {
00830 if (strlen($string) >= 255) {
00831
00832 return;
00833 }
00834 $this->_header = $string;
00835 $this->_margin_head = $margin;
00836 }
00837
00845 function setFooter($string,$margin = 0.50)
00846 {
00847 if (strlen($string) >= 255) {
00848
00849 return;
00850 }
00851 $this->_footer = $string;
00852 $this->_margin_foot = $margin;
00853 }
00854
00861 function centerHorizontally($center = 1)
00862 {
00863 $this->_hcenter = $center;
00864 }
00865
00872 function centerVertically($center = 1)
00873 {
00874 $this->_vcenter = $center;
00875 }
00876
00883 function setMargins($margin)
00884 {
00885 $this->setMarginLeft($margin);
00886 $this->setMarginRight($margin);
00887 $this->setMarginTop($margin);
00888 $this->setMarginBottom($margin);
00889 }
00890
00897 function setMargins_LR($margin)
00898 {
00899 $this->setMarginLeft($margin);
00900 $this->setMarginRight($margin);
00901 }
00902
00909 function setMargins_TB($margin)
00910 {
00911 $this->setMarginTop($margin);
00912 $this->setMarginBottom($margin);
00913 }
00914
00921 function setMarginLeft($margin = 0.75)
00922 {
00923 $this->_margin_left = $margin;
00924 }
00925
00932 function setMarginRight($margin = 0.75)
00933 {
00934 $this->_margin_right = $margin;
00935 }
00936
00943 function setMarginTop($margin = 1.00)
00944 {
00945 $this->_margin_top = $margin;
00946 }
00947
00954 function setMarginBottom($margin = 1.00)
00955 {
00956 $this->_margin_bottom = $margin;
00957 }
00958
00966 function repeatRows($first_row, $last_row = NULL)
00967 {
00968 $this->title_rowmin = $first_row;
00969 if (isset($last_row)) {
00970 $this->title_rowmax = $last_row;
00971 }
00972 else {
00973 $this->title_rowmax = $first_row;
00974 }
00975 }
00976
00984 function repeatColumns($first_col, $last_col = NULL)
00985 {
00986 $this->title_colmin = $first_col;
00987 if (isset($last_col)) {
00988 $this->title_colmax = $last_col;
00989 }
00990 else {
00991 $this->title_colmax = $first_col;
00992 }
00993 }
00994
01004 function printArea($first_row, $first_col, $last_row, $last_col)
01005 {
01006 $this->print_rowmin = $first_row;
01007 $this->print_colmin = $first_col;
01008 $this->print_rowmax = $last_row;
01009 $this->print_colmax = $last_col;
01010 }
01011
01012
01018 function hideGridlines()
01019 {
01020 $this->_print_gridlines = 0;
01021 }
01022
01029 function printRowColHeaders($print = 1)
01030 {
01031 $this->_print_headers = $print;
01032 }
01033
01043 function fitToPages($width, $height)
01044 {
01045 $this->_fit_page = 1;
01046 $this->_fit_width = $width;
01047 $this->_fit_height = $height;
01048 }
01049
01057 function setHPagebreaks($breaks)
01058 {
01059 foreach($breaks as $break) {
01060 array_push($this->_hbreaks,$break);
01061 }
01062 }
01063
01071 function setVPagebreaks($breaks)
01072 {
01073 foreach($breaks as $break) {
01074 array_push($this->_vbreaks,$break);
01075 }
01076 }
01077
01078
01085 function setZoom($scale = 100)
01086 {
01087
01088 if ($scale < 10 or $scale > 400)
01089 {
01090 $this->raiseError("Zoom factor $scale outside range: 10 <= zoom <= 400");
01091 $scale = 100;
01092 }
01093
01094 $this->_zoom = floor($scale);
01095 }
01096
01104 function setPrintScale($scale = 100)
01105 {
01106
01107 if ($scale < 10 or $scale > 400)
01108 {
01109 $this->raiseError("Print scale $scale outside range: 10 <= zoom <= 400");
01110 $scale = 100;
01111 }
01112
01113
01114 $this->_fit_page = 0;
01115
01116 $this->_print_scale = floor($scale);
01117 }
01118
01128 function write($row, $col, $token, $format = 0)
01129 {
01130
01131
01132
01133
01134
01135
01136
01137 if (preg_match("/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/",$token)) {
01138 return $this->writeNumber($row,$col,$token,$format);
01139 }
01140
01141 elseif (preg_match("/^[fh]tt?p:\/\//",$token)) {
01142 return $this->writeUrl($row, $col, $token, '', $format);
01143 }
01144
01145 elseif (preg_match("/^mailto:/",$token)) {
01146 return $this->writeUrl($row, $col, $token, '', $format);
01147 }
01148
01149 elseif (preg_match("/^(?:in|ex)ternal:/",$token)) {
01150 return $this->writeUrl($row, $col, $token, '', $format);
01151 }
01152
01153 elseif (preg_match("/^=/",$token)) {
01154 return $this->writeFormula($row, $col, $token, $format);
01155 }
01156
01157 elseif (preg_match("/^@/",$token)) {
01158 return $this->writeFormula($row, $col, $token, $format);
01159 }
01160
01161 elseif ($token == '') {
01162 return $this->writeBlank($row,$col,$format);
01163 }
01164
01165 else {
01166 return $this->writeString($row,$col,$token,$format);
01167 }
01168 }
01169
01181 function writeRow($row, $col, $val, $format=0)
01182 {
01183 $retval = '';
01184 if (is_array($val)) {
01185 foreach($val as $v) {
01186 if (is_array($v)) {
01187 $this->writeCol($row, $col, $v, $format);
01188 } else {
01189 $this->write($row, $col, $v, $format);
01190 }
01191 $col++;
01192 }
01193 } else {
01194 $retval = new PEAR_Error('$val needs to be an array');
01195 }
01196 return($retval);
01197 }
01198
01210 function writeCol($row, $col, $val, $format=0)
01211 {
01212 $retval = '';
01213 if (is_array($val)) {
01214 foreach($val as $v) {
01215 $this->write($row, $col, $v, $format);
01216 $row++;
01217 }
01218 } else {
01219 $retval = new PEAR_Error('$val needs to be an array');
01220 }
01221 return($retval);
01222 }
01223
01231 function _XF(&$format)
01232 {
01233 if ($format != 0) {
01234 return($format->getXfIndex());
01235 }
01236 else {
01237 return(0x0F);
01238 }
01239 }
01240
01241
01242
01243
01244
01245
01246
01247
01248
01256 function _append($data)
01257 {
01258 if ($this->_using_tmpfile)
01259 {
01260
01261 if (strlen($data) > $this->_limit) {
01262 $data = $this->_addContinue($data);
01263 }
01264 fwrite($this->_filehandle,$data);
01265 $this->_datasize += strlen($data);
01266 }
01267 else {
01268 parent::_append($data);
01269 }
01270 }
01271
01282 function _substituteCellref($cell)
01283 {
01284 $cell = strtoupper($cell);
01285
01286
01287 if (preg_match("/([A-I]?[A-Z]):([A-I]?[A-Z])/",$cell,$match)) {
01288 list($no_use, $col1) = $this->_cellToRowcol($match[1] .'1');
01289 list($no_use, $col2) = $this->_cellToRowcol($match[2] .'1');
01290 return(array($col1, $col2));
01291 }
01292
01293
01294 if (preg_match("/\$?([A-I]?[A-Z]\$?\d+):\$?([A-I]?[A-Z]\$?\d+)/",$cell,$match)) {
01295 list($row1, $col1) = $this->_cellToRowcol($match[1]);
01296 list($row2, $col2) = $this->_cellToRowcol($match[2]);
01297 return(array($row1, $col1, $row2, $col2));
01298 }
01299
01300
01301 if (preg_match("/\$?([A-I]?[A-Z]\$?\d+)/",$cell)) {
01302 list($row1, $col1) = $this->_cellToRowcol($match[1]);
01303 return(array($row1, $col1));
01304 }
01305
01306
01307 $this->raiseError("Unknown cell reference $cell", 0, PEAR_ERROR_DIE);
01308 }
01309
01318 function _cellToRowcol($cell)
01319 {
01320 preg_match("/\$?([A-I]?[A-Z])\$?(\d+)/",$cell,$match);
01321 $col = $match[1];
01322 $row = $match[2];
01323
01324
01325 $chars = split('', $col);
01326 $expn = 0;
01327 $col = 0;
01328
01329 while ($chars) {
01330 $char = array_pop($chars);
01331 $col += (ord($char) -ord('A') +1) * pow(26,$expn);
01332 $expn++;
01333 }
01334
01335
01336 $row--;
01337 $col--;
01338
01339 return(array($row, $col));
01340 }
01341
01349 function _encodePassword($plaintext)
01350 {
01351 $password = 0x0000;
01352 $i = 1;
01353
01354
01355 $chars = preg_split('//', $plaintext, -1, PREG_SPLIT_NO_EMPTY);
01356 foreach($chars as $char)
01357 {
01358 $value = ord($char) << $i;
01359 $rotated_bits = $value >> 15;
01360 $value &= 0x7fff;
01361 $password ^= ($value | $rotated_bits);
01362 $i++;
01363 }
01364
01365 $password ^= strlen($plaintext);
01366 $password ^= 0xCE4B;
01367
01368 return($password);
01369 }
01370
01380 function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false)
01381 {
01382 $this->_outline_on = $visible;
01383 $this->_outline_below = $symbols_below;
01384 $this->_outline_right = $symbols_right;
01385 $this->_outline_style = $auto_style;
01386
01387
01388 if ($this->_outline_on) {
01389 $this->_outline_on = 1;
01390 }
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01415 function writeNumber($row, $col, $num, $format = 0)
01416 {
01417 $record = 0x0203;
01418 $length = 0x000E;
01419
01420 $xf = $this->_XF($format);
01421
01422
01423 if ($row >= $this->_xls_rowmax)
01424 {
01425 return(-2);
01426 }
01427 if ($col >= $this->_xls_colmax)
01428 {
01429 return(-2);
01430 }
01431 if ($row < $this->_dim_rowmin)
01432 {
01433 $this->_dim_rowmin = $row;
01434 }
01435 if ($row > $this->_dim_rowmax)
01436 {
01437 $this->_dim_rowmax = $row;
01438 }
01439 if ($col < $this->_dim_colmin)
01440 {
01441 $this->_dim_colmin = $col;
01442 }
01443 if ($col > $this->_dim_colmax)
01444 {
01445 $this->_dim_colmax = $col;
01446 }
01447
01448 $header = pack("vv", $record, $length);
01449 $data = pack("vvv", $row, $col, $xf);
01450 $xl_double = pack("d", $num);
01451 if ($this->_byte_order)
01452 {
01453 $xl_double = strrev($xl_double);
01454 }
01455
01456 $this->_append($header.$data.$xl_double);
01457 return(0);
01458 }
01459
01475 function writeString($row, $col, $str, $format = 0)
01476 {
01477 if ($this->_BIFF_version == 0x0600) {
01478 return $this->writeStringBIFF8($row, $col, $str, $format);
01479 }
01480 $strlen = strlen($str);
01481 $record = 0x0204;
01482 $length = 0x0008 + $strlen;
01483 $xf = $this->_XF($format);
01484
01485 $str_error = 0;
01486
01487
01488 if ($row >= $this->_xls_rowmax)
01489 {
01490 return(-2);
01491 }
01492 if ($col >= $this->_xls_colmax)
01493 {
01494 return(-2);
01495 }
01496 if ($row < $this->_dim_rowmin)
01497 {
01498 $this->_dim_rowmin = $row;
01499 }
01500 if ($row > $this->_dim_rowmax)
01501 {
01502 $this->_dim_rowmax = $row;
01503 }
01504 if ($col < $this->_dim_colmin)
01505 {
01506 $this->_dim_colmin = $col;
01507 }
01508 if ($col > $this->_dim_colmax)
01509 {
01510 $this->_dim_colmax = $col;
01511 }
01512
01513 if ($strlen > $this->_xls_strmax)
01514 {
01515 $str = substr($str, 0, $this->_xls_strmax);
01516 $length = 0x0008 + $this->_xls_strmax;
01517 $strlen = $this->_xls_strmax;
01518 $str_error = -3;
01519 }
01520
01521 $header = pack("vv", $record, $length);
01522 $data = pack("vvvv", $row, $col, $xf, $strlen);
01523 $this->_append($header.$data.$str);
01524 return($str_error);
01525 }
01526
01527 function writeStringBIFF8($row, $col, $str, $format = 0)
01528 {
01529 $strlen = strlen($str);
01530 $record = 0x00FD;
01531 $length = 0x000A;
01532 $xf = $this->_XF($format);
01533 $encoding = 0x0;
01534
01535 $str_error = 0;
01536
01537
01538 if ($this->_checkRowCol($row, $col) == false) {
01539 return -2;
01540 }
01541
01542 $str = pack('vC', $strlen, $encoding).$str;
01543
01544
01545 if (!isset($this->_str_table[$str])) {
01546 $this->_str_table[$str] = $this->_str_unique++;
01547 }
01548 $this->_str_total++;
01549
01550 $header = pack('vv', $record, $length);
01551 $data = pack('vvvV', $row, $col, $xf, $this->_str_table[$str]);
01552 $this->_append($header.$data);
01553 return $str_error;
01554 }
01555
01566 function _checkRowCol($row, $col)
01567 {
01568 if ($row >= $this->_xls_rowmax) {
01569 return false;
01570 }
01571 if ($col >= $this->_xls_colmax) {
01572 return false;
01573 }
01574 if ($row < $this->_dim_rowmin) {
01575 $this->_dim_rowmin = $row;
01576 }
01577 if ($row > $this->_dim_rowmax) {
01578 $this->_dim_rowmax = $row;
01579 }
01580 if ($col < $this->_dim_colmin) {
01581 $this->_dim_colmin = $col;
01582 }
01583 if ($col > $this->_dim_colmax) {
01584 $this->_dim_colmax = $col;
01585 }
01586 return true;
01587 }
01588
01598 function writeNote($row, $col, $note)
01599 {
01600 $note_length = strlen($note);
01601 $record = 0x001C;
01602 $max_length = 2048;
01603
01604
01605
01606 if ($row >= $this->_xls_rowmax)
01607 {
01608 return(-2);
01609 }
01610 if ($col >= $this->_xls_colmax)
01611 {
01612 return(-2);
01613 }
01614 if ($row < $this->_dim_rowmin)
01615 {
01616 $this->_dim_rowmin = $row;
01617 }
01618 if ($row > $this->_dim_rowmax)
01619 {
01620 $this->_dim_rowmax = $row;
01621 }
01622 if ($col < $this->_dim_colmin)
01623 {
01624 $this->_dim_colmin = $col;
01625 }
01626 if ($col > $this->_dim_colmax)
01627 {
01628 $this->_dim_colmax = $col;
01629 }
01630
01631
01632 $length = 0x0006 + min($note_length, 2048);
01633 $header = pack("vv", $record, $length);
01634 $data = pack("vvv", $row, $col, $note_length);
01635 $this->_append($header.$data.substr($note, 0, 2048));
01636
01637 for($i = $max_length; $i < $note_length; $i += $max_length)
01638 {
01639 $chunk = substr($note, $i, $max_length);
01640 $length = 0x0006 + strlen($chunk);
01641 $header = pack("vv", $record, $length);
01642 $data = pack("vvv", -1, 0, strlen($chunk));
01643 $this->_append($header.$data.$chunk);
01644 }
01645 return(0);
01646 }
01647
01665 function writeBlank($row, $col, $format)
01666 {
01667
01668 if ($format == 0)
01669 {
01670 return(0);
01671 }
01672
01673 $record = 0x0201;
01674 $length = 0x0006;
01675 $xf = $this->_XF($format);
01676
01677
01678 if ($row >= $this->_xls_rowmax)
01679 {
01680 return(-2);
01681 }
01682 if ($col >= $this->_xls_colmax)
01683 {
01684 return(-2);
01685 }
01686 if ($row < $this->_dim_rowmin)
01687 {
01688 $this->_dim_rowmin = $row;
01689 }
01690 if ($row > $this->_dim_rowmax)
01691 {
01692 $this->_dim_rowmax = $row;
01693 }
01694 if ($col < $this->_dim_colmin)
01695 {
01696 $this->_dim_colmin = $col;
01697 }
01698 if ($col > $this->_dim_colmax)
01699 {
01700 $this->_dim_colmax = $col;
01701 }
01702
01703 $header = pack("vv", $record, $length);
01704 $data = pack("vvv", $row, $col, $xf);
01705 $this->_append($header.$data);
01706 return 0;
01707 }
01708
01725 function writeFormula($row, $col, $formula, $format = 0)
01726 {
01727 $record = 0x0006;
01728
01729
01730
01731
01732
01733
01734 $xf = $this->_XF($format);
01735 $num = 0x00;
01736 $grbit = 0x03;
01737 $unknown = 0x0000;
01738
01739
01740
01741 if ($this->_checkRowCol($row, $col) == false) {
01742 return -2;
01743 }
01744
01745
01746 if (preg_match("/^=/",$formula)) {
01747 $formula = preg_replace("/(^=)/","",$formula);
01748 }
01749 elseif (preg_match("/^@/",$formula)) {
01750 $formula = preg_replace("/(^@)/","",$formula);
01751 }
01752 else
01753 {
01754
01755 $this->writeString($row, $col, 'Unrecognised character for formula');
01756 return -1;
01757 }
01758
01759
01760 $error = $this->_parser->parse($formula);
01761 if ($this->isError($error))
01762 {
01763 $this->writeString($row, $col, $error->getMessage());
01764 return -1;
01765 }
01766
01767 $formula = $this->_parser->toReversePolish();
01768 if ($this->isError($formula))
01769 {
01770 $this->writeString($row, $col, $formula->getMessage());
01771 return -1;
01772 }
01773
01774 $formlen = strlen($formula);
01775 $length = 0x16 + $formlen;
01776
01777 $header = pack("vv", $record, $length);
01778 $data = pack("vvvdvVv", $row, $col, $xf, $num,
01779 $grbit, $unknown, $formlen);
01780
01781 $this->_append($header.$data.$formula);
01782 return 0;
01783 }
01784
01808 function writeUrl($row, $col, $url, $string = '', $format = 0)
01809 {
01810
01811 return($this->_writeUrlRange($row, $col, $row, $col, $url, $string, $format));
01812 }
01813
01832 function _writeUrlRange($row1, $col1, $row2, $col2, $url, $string = '', $format = 0)
01833 {
01834
01835
01836 if (preg_match('[^internal:]', $url)) {
01837 return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url, $string, $format));
01838 }
01839 if (preg_match('[^external:]', $url)) {
01840 return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url, $string, $format));
01841 }
01842 return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url, $string, $format));
01843 }
01844
01845
01862 function _writeUrlWeb($row1, $col1, $row2, $col2, $url, $str, $format = 0)
01863 {
01864 $record = 0x01B8;
01865 $length = 0x00000;
01866
01867 if ($format == 0) {
01868 $format = $this->_url_format;
01869 }
01870
01871
01872 if ($str == '') {
01873 $str = $url;
01874 }
01875 $str_error = $this->writeString($row1, $col1, $str, $format);
01876 if (($str_error == -2) or ($str_error == -3)) {
01877 return $str_error;
01878 }
01879
01880
01881 $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000");
01882 $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B");
01883
01884
01885 $options = pack("V", 0x03);
01886
01887
01888 $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY));
01889 $url = $url . "\0\0\0";
01890
01891
01892 $url_len = pack("V", strlen($url));
01893
01894
01895 $length = 0x34 + strlen($url);
01896
01897
01898 $header = pack("vv", $record, $length);
01899 $data = pack("vvvv", $row1, $row2, $col1, $col2);
01900
01901
01902 $this->_append( $header. $data.
01903 $unknown1. $options.
01904 $unknown2. $url_len. $url);
01905 return($str_error);
01906 }
01907
01922 function _writeUrlInternal($row1, $col1, $row2, $col2, $url, $str, $format = 0)
01923 {
01924 $record = 0x01B8;
01925 $length = 0x00000;
01926
01927 if ($format == 0) {
01928 $format = $this->_url_format;
01929 }
01930
01931
01932 $url = preg_replace('s[^internal:]', '', $url);
01933
01934
01935 if ($str == '') {
01936 $str = $url;
01937 }
01938 $str_error = $this->writeString($row1, $col1, $str, $format);
01939 if (($str_error == -2) or ($str_error == -3)) {
01940 return $str_error;
01941 }
01942
01943
01944 $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000");
01945
01946
01947 $options = pack("V", 0x08);
01948
01949
01950 $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY));
01951 $url = $url . "\0\0\0";
01952
01953
01954 $url_len = pack("V", floor(strlen($url)/2));
01955
01956
01957 $length = 0x24 + strlen($url);
01958
01959
01960 $header = pack("vv", $record, $length);
01961 $data = pack("vvvv", $row1, $row2, $col1, $col2);
01962
01963
01964 $this->_append($header. $data.
01965 $unknown1. $options.
01966 $url_len. $url);
01967 return($str_error);
01968 }
01969
01988 function _writeUrlExternal($row1, $col1, $row2, $col2, $url, $str, $format = 0)
01989 {
01990
01991
01992
01993 return;
01994 }
01995
01996 $record = 0x01B8;
01997 $length = 0x00000;
01998
01999 if ($format == 0) {
02000 $format = $this->_url_format;
02001 }
02002
02003
02004
02005 $url = preg_replace('[^external:]', '', $url);
02006 $url = preg_replace('[/]', "\\", $url);
02007
02008
02009 if ($str == '') {
02010 $str = preg_replace('[\#]', ' - ', $url);
02011 }
02012 $str_error = $this->writeString($row1, $col1, $str, $format);
02013 if (($str_error == -2) or ($str_error == -3)) {
02014 return $str_error;
02015 }
02016
02017
02018
02019
02020
02021
02022 $absolute = 0x02;
02023 if (!preg_match('[\\]', $url)) {
02024 $absolute = 0x00;
02025 }
02026 if (preg_match('[^\.\.\\]', $url)) {
02027 $absolute = 0x00;
02028 }
02029
02030
02031
02032
02033 list($dir_long , $sheet) = split('/\#/', $url);
02034 $link_type = 0x01 | $absolute;
02035
02036 if (isset($sheet)) {
02037 $link_type |= 0x08;
02038 $sheet_len = pack("V", strlen($sheet) + 0x01);
02039 $sheet = join("\0", split('', $sheet));
02040 $sheet .= "\0\0\0";
02041 }
02042 else {
02043 $sheet_len = '';
02044 $sheet = '';
02045 }
02046
02047
02048 $link_type = pack("V", $link_type);
02049
02050
02051 $up_count = preg_match_all("/\.\.\\/", $dir_long, $useless);
02052 $up_count = pack("v", $up_count);
02053
02054
02055 $dir_short = preg_replace('/\.\.\\/', '', $dir_long) . "\0";
02056
02057
02058 $dir_long = join("\0", split('', $dir_long));
02059 $dir_long = $dir_long . "\0";
02060
02061
02062 $dir_short_len = pack("V", strlen($dir_short) );
02063 $dir_long_len = pack("V", strlen($dir_long) );
02064 $stream_len = pack("V", strlen($dir_long) + 0x06);
02065
02066
02067 $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' );
02068 $unknown2 = pack("H*",'0303000000000000C000000000000046' );
02069 $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000');
02070 $unknown4 = pack("v", 0x03 );
02071
02072
02073 $data = pack("vvvv", $row1, $row2, $col1, $col2) .
02074 $unknown1 .
02075 $link_type .
02076 $unknown2 .
02077 $up_count .
02078 $dir_short_len.
02079 $dir_short .
02080 $unknown3 .
02081 $stream_len .
02082 $dir_long_len .
02083 $unknown4 .
02084 $dir_long .
02085 $sheet_len .
02086 $sheet ;
02087
02088
02089 $length = strlen($data);
02090 $header = pack("vv", $record, $length);
02091
02092
02093 $this->_append($header. $data);
02094 return($str_error);
02095 }
02096
02097
02109 function setRow($row, $height, $format = 0, $hidden = false, $level = 0)
02110 {
02111 $record = 0x0208;
02112 $length = 0x0010;
02113
02114 $colMic = 0x0000;
02115 $colMac = 0x0000;
02116 $irwMac = 0x0000;
02117 $reserved = 0x0000;
02118 $grbit = 0x0000;
02119 $ixfe = $this->_XF($format);
02120
02121
02122 if ($height != NULL) {
02123 $miyRw = $height * 20;
02124 }
02125 else {
02126 $miyRw = 0xff;
02127 }
02128
02129 $level = max(0, min($level, 7));
02130 $this->_outline_row_level = max($level, $this->_outline_row_level);
02131
02132
02133
02134
02135
02136
02137
02138
02139 $grbit |= $level;
02140 if ($hidden) {
02141 $grbit |= 0x0020;
02142 }
02143 $grbit |= 0x0040;
02144 if ($format) {
02145 $grbit |= 0x0080;
02146 }
02147 $grbit |= 0x0100;
02148
02149 $header = pack("vv", $record, $length);
02150 $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw,
02151 $irwMac,$reserved, $grbit, $ixfe);
02152 $this->_append($header.$data);
02153 }
02154
02160 function _storeDimensions()
02161 {
02162 $record = 0x0200;
02163 $row_min = $this->_dim_rowmin;
02164 $row_max = $this->_dim_rowmax + 1;
02165 $col_min = $this->_dim_colmin;
02166 $col_max = $this->_dim_colmax + 1;
02167 $reserved = 0x0000;
02168
02169 if ($this->_BIFF_version == 0x0500) {
02170 $length = 0x000A;
02171 $data = pack("vvvvv", $row_min, $row_max,
02172 $col_min, $col_max, $reserved);
02173 }
02174 elseif ($this->_BIFF_version == 0x0600) {
02175 $length = 0x000E;
02176 $data = pack("VVvvv", $row_min, $row_max,
02177 $col_min, $col_max, $reserved);
02178 }
02179 $header = pack("vv", $record, $length);
02180 $this->_prepend($header.$data);
02181 }
02182
02188 function _storeWindow2()
02189 {
02190 $record = 0x023E;
02191 if ($this->_BIFF_version == 0x0500) {
02192 $length = 0x000A;
02193 }
02194 elseif ($this->_BIFF_version == 0x0600) {
02195 $length = 0x0012;
02196 }
02197
02198 $grbit = 0x00B6;
02199 $rwTop = 0x0000;
02200 $colLeft = 0x0000;
02201
02202
02203
02204 $fDspFmla = 0;
02205 $fDspGrid = 1;
02206 $fDspRwCol = 1;
02207 $fFrozen = $this->_frozen;
02208 $fDspZeros = 1;
02209 $fDefaultHdr = 1;
02210 $fArabic = 0;
02211 $fDspGuts = $this->_outline_on;
02212 $fFrozenNoSplit = 0;
02213 $fSelected = $this->selected;
02214 $fPaged = 1;
02215
02216 $grbit = $fDspFmla;
02217 $grbit |= $fDspGrid << 1;
02218 $grbit |= $fDspRwCol << 2;
02219 $grbit |= $fFrozen << 3;
02220 $grbit |= $fDspZeros << 4;
02221 $grbit |= $fDefaultHdr << 5;
02222 $grbit |= $fArabic << 6;
02223 $grbit |= $fDspGuts << 7;
02224 $grbit |= $fFrozenNoSplit << 8;
02225 $grbit |= $fSelected << 9;
02226 $grbit |= $fPaged << 10;
02227
02228 $header = pack("vv", $record, $length);
02229 $data = pack("vvv", $grbit, $rwTop, $colLeft);
02230
02231 if ($this->_BIFF_version == 0x0500) {
02232 $rgbHdr = 0x00000000;
02233 $data .= pack("V", $rgbHdr);
02234 }
02235 elseif ($this->_BIFF_version == 0x0600) {
02236 $rgbHdr = 0x0040;
02237 $zoom_factor_page_break = 0x0000;
02238 $zoom_factor_normal = 0x0000;
02239 $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000);
02240 }
02241 $this->_append($header.$data);
02242 }
02243
02249 function _storeDefcol()
02250 {
02251 $record = 0x0055;
02252 $length = 0x0002;
02253 $colwidth = 0x0008;
02254
02255 $header = pack("vv", $record, $length);
02256 $data = pack("v", $colwidth);
02257 $this->_prepend($header.$data);
02258 }
02259
02275 function _storeColinfo($col_array)
02276 {
02277 if (isset($col_array[0])) {
02278 $colFirst = $col_array[0];
02279 }
02280 if (isset($col_array[1])) {
02281 $colLast = $col_array[1];
02282 }
02283 if (isset($col_array[2])) {
02284 $coldx = $col_array[2];
02285 }
02286 else {
02287 $coldx = 8.43;
02288 }
02289 if (isset($col_array[3])) {
02290 $format = $col_array[3];
02291 }
02292 else {
02293 $format = 0;
02294 }
02295 if (isset($col_array[4])) {
02296 $grbit = $col_array[4];
02297 }
02298 else {
02299 $grbit = 0;
02300 }
02301 if (isset($col_array[5])) {
02302 $level = $col_array[5];
02303 }
02304 else {
02305 $level = 0;
02306 }
02307 $record = 0x007D;
02308 $length = 0x000B;
02309
02310 $coldx += 0.72;
02311 $coldx *= 256;
02312
02313 $ixfe = $this->_XF($format);
02314 $reserved = 0x00;
02315
02316 $level = max(0, min($level, 7));
02317 $grbit |= $level << 8;
02318
02319 $header = pack("vv", $record, $length);
02320 $data = pack("vvvvvC", $colFirst, $colLast, $coldx,
02321 $ixfe, $grbit, $reserved);
02322 $this->_prepend($header.$data);
02323 }
02324
02332 function _storeSelection($array)
02333 {
02334 list($rwFirst,$colFirst,$rwLast,$colLast) = $array;
02335 $record = 0x001D;
02336 $length = 0x000F;
02337
02338 $pnn = $this->_active_pane;
02339 $rwAct = $rwFirst;
02340 $colAct = $colFirst;
02341 $irefAct = 0;
02342 $cref = 1;
02343
02344 if (!isset($rwLast)) {
02345 $rwLast = $rwFirst;
02346 }
02347 if (!isset($colLast)) {
02348 $colLast = $colFirst;
02349 }
02350
02351
02352 if ($rwFirst > $rwLast)
02353 {
02354 list($rwFirst, $rwLast) = array($rwLast, $rwFirst);
02355 }
02356
02357 if ($colFirst > $colLast)
02358 {
02359 list($colFirst, $colLast) = array($colLast, $colFirst);
02360 }
02361
02362 $header = pack("vv", $record, $length);
02363 $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct,
02364 $irefAct, $cref,
02365 $rwFirst, $rwLast,
02366 $colFirst, $colLast);
02367 $this->_append($header.$data);
02368 }
02369
02375 function _storeMergedCells()
02376 {
02377
02378 if (count($this->_merged_ranges) == 0) {
02379 return;
02380 }
02381 $record = 0x00E5;
02382 $length = 2 + count($this->_merged_ranges) * 8;
02383
02384 $header = pack('vv', $record, $length);
02385 $data = pack('v', count($this->_merged_ranges));
02386 foreach ($this->_merged_ranges as $range) {
02387 $data .= pack('vvvv', $range[0], $range[2], $range[1], $range[3]);
02388 }
02389 $this->_append($header.$data);
02390 }
02391
02405 function _storeExterncount($count)
02406 {
02407 $record = 0x0016;
02408 $length = 0x0002;
02409
02410 $header = pack("vv", $record, $length);
02411 $data = pack("v", $count);
02412 $this->_prepend($header.$data);
02413 }
02414
02424 function _storeExternsheet($sheetname)
02425 {
02426 $record = 0x0017;
02427
02428
02429
02430
02431 if ($this->name == $sheetname) {
02432 $sheetname = '';
02433 $length = 0x02;
02434 $cch = 1;
02435 $rgch = 0x02;
02436 }
02437 else {
02438 $length = 0x02 + strlen($sheetname);
02439 $cch = strlen($sheetname);
02440 $rgch = 0x03;
02441 }
02442
02443 $header = pack("vv", $record, $length);
02444 $data = pack("CC", $cch, $rgch);
02445 $this->_prepend($header.$data.$sheetname);
02446 }
02447
02462 function _storePanes($panes)
02463 {
02464 $y = $panes[0];
02465 $x = $panes[1];
02466 $rwTop = $panes[2];
02467 $colLeft = $panes[3];
02468 if (count($panes) > 4) {
02469 $pnnAct = $panes[4];
02470 }
02471 else {
02472 $pnnAct = NULL;
02473 }
02474 $record = 0x0041;
02475 $length = 0x000A;
02476
02477
02478 if ($this->_frozen)
02479 {
02480
02481 if (!isset($rwTop)) {
02482 $rwTop = $y;
02483 }
02484 if (!isset($colLeft)) {
02485 $colLeft = $x;
02486 }
02487 }
02488 else
02489 {
02490
02491 if (!isset($rwTop)) {
02492 $rwTop = 0;
02493 }
02494 if (!isset($colLeft)) {
02495 $colLeft = 0;
02496 }
02497
02498
02499
02500
02501
02502
02503 $y = 20*$y + 255;
02504 $x = 113.879*$x + 390;
02505 }
02506
02507
02508
02509
02510
02511 if (!isset($pnnAct))
02512 {
02513 if ($x != 0 and $y != 0)
02514 $pnnAct = 0;
02515 if ($x != 0 and $y == 0)
02516 $pnnAct = 1;
02517 if ($x == 0 and $y != 0)
02518 $pnnAct = 2;
02519 if ($x == 0 and $y == 0)
02520 $pnnAct = 3;
02521 }
02522
02523 $this->_active_pane = $pnnAct;
02524
02525 $header = pack("vv", $record, $length);
02526 $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct);
02527 $this->_append($header.$data);
02528 }
02529
02535 function _storeSetup()
02536 {
02537 $record = 0x00A1;
02538 $length = 0x0022;
02539
02540 $iPaperSize = $this->_paper_size;
02541 $iScale = $this->_print_scale;
02542 $iPageStart = 0x01;
02543 $iFitWidth = $this->_fit_width;
02544 $iFitHeight = $this->_fit_height;
02545 $grbit = 0x00;
02546 $iRes = 0x0258;
02547 $iVRes = 0x0258;
02548 $numHdr = $this->_margin_head;
02549 $numFtr = $this->_margin_foot;
02550 $iCopies = 0x01;
02551
02552 $fLeftToRight = 0x0;
02553 $fLandscape = $this->_orientation;
02554 $fNoPls = 0x0;
02555 $fNoColor = 0x0;
02556 $fDraft = 0x0;
02557 $fNotes = 0x0;
02558 $fNoOrient = 0x0;
02559 $fUsePage = 0x0;
02560
02561 $grbit = $fLeftToRight;
02562 $grbit |= $fLandscape << 1;
02563 $grbit |= $fNoPls << 2;
02564 $grbit |= $fNoColor << 3;
02565 $grbit |= $fDraft << 4;
02566 $grbit |= $fNotes << 5;
02567 $grbit |= $fNoOrient << 6;
02568 $grbit |= $fUsePage << 7;
02569
02570 $numHdr = pack("d", $numHdr);
02571 $numFtr = pack("d", $numFtr);
02572 if ($this->_byte_order)
02573 {
02574 $numHdr = strrev($numHdr);
02575 $numFtr = strrev($numFtr);
02576 }
02577
02578 $header = pack("vv", $record, $length);
02579 $data1 = pack("vvvvvvvv", $iPaperSize,
02580 $iScale,
02581 $iPageStart,
02582 $iFitWidth,
02583 $iFitHeight,
02584 $grbit,
02585 $iRes,
02586 $iVRes);
02587 $data2 = $numHdr.$numFtr;
02588 $data3 = pack("v", $iCopies);
02589 $this->_prepend($header.$data1.$data2.$data3);
02590 }
02591
02597 function _storeHeader()
02598 {
02599 $record = 0x0014;
02600
02601 $str = $this->_header;
02602 $cch = strlen($str);
02603 if ($this->_BIFF_version == 0x0600) {
02604 $encoding = 0x0;
02605 $length = 3 + $cch;
02606 }
02607 else {
02608 $length = 1 + $cch;
02609 }
02610 $header = pack("vv", $record, $length);
02611 if ($this->_BIFF_version == 0x0600) {
02612 $data = pack("vC", $cch, $encoding);
02613 }
02614 else {
02615 $data = pack("C", $cch);
02616 }
02617
02618 $this->_append($header.$data.$str);
02619 }
02620
02626 function _storeFooter()
02627 {
02628 $record = 0x0015;
02629
02630 $str = $this->_footer;
02631 $cch = strlen($str);
02632 if ($this->_BIFF_version == 0x0600) {
02633 $encoding = 0x0;
02634 $length = 3 + $cch;
02635 }
02636 else {
02637 $length = 1 + $cch;
02638 }
02639 $header = pack("vv", $record, $length);
02640 if ($this->_BIFF_version == 0x0600) {
02641 $data = pack("vC", $cch, $encoding);
02642 }
02643 else {
02644 $data = pack("C", $cch);
02645 }
02646
02647 $this->_append($header.$data.$str);
02648 }
02649
02655 function _storeHcenter()
02656 {
02657 $record = 0x0083;
02658 $length = 0x0002;
02659
02660 $fHCenter = $this->_hcenter;
02661
02662 $header = pack("vv", $record, $length);
02663 $data = pack("v", $fHCenter);
02664
02665 $this->_append($header.$data);
02666 }
02667
02673 function _storeVcenter()
02674 {
02675 $record = 0x0084;
02676 $length = 0x0002;
02677
02678 $fVCenter = $this->_vcenter;
02679
02680 $header = pack("vv", $record, $length);
02681 $data = pack("v", $fVCenter);
02682 $this->_append($header.$data);
02683 }
02684
02690 function _storeMarginLeft()
02691 {
02692 $record = 0x0026;
02693 $length = 0x0008;
02694
02695 $margin = $this->_margin_left;
02696
02697 $header = pack("vv", $record, $length);
02698 $data = pack("d", $margin);
02699 if ($this->_byte_order)
02700 {
02701 $data = strrev($data);
02702 }
02703
02704 $this->_append($header.$data);
02705 }
02706
02712 function _storeMarginRight()
02713 {
02714 $record = 0x0027;
02715 $length = 0x0008;
02716
02717 $margin = $this->_margin_right;
02718
02719 $header = pack("vv", $record, $length);
02720 $data = pack("d", $margin);
02721 if ($this->_byte_order)
02722 {
02723 $data = strrev($data);
02724 }
02725
02726 $this->_append($header.$data);
02727 }
02728
02734 function _storeMarginTop()
02735 {
02736 $record = 0x0028;
02737 $length = 0x0008;
02738
02739 $margin = $this->_margin_top;
02740
02741 $header = pack("vv", $record, $length);
02742 $data = pack("d", $margin);
02743 if ($this->_byte_order)
02744 {
02745 $data = strrev($data);
02746 }
02747
02748 $this->_append($header.$data);
02749 }
02750
02756 function _storeMarginBottom()
02757 {
02758 $record = 0x0029;
02759 $length = 0x0008;
02760
02761 $margin = $this->_margin_bottom;
02762
02763 $header = pack("vv", $record, $length);
02764 $data = pack("d", $margin);
02765 if ($this->_byte_order)
02766 {
02767 $data = strrev($data);
02768 }
02769
02770 $this->_append($header.$data);
02771 }
02772
02784 function mergeCells($first_row, $first_col, $last_row, $last_col)
02785 {
02786 $record = 0x00E5;
02787 $length = 0x000A;
02788 $cref = 1;
02789
02790
02791 if ($first_row > $last_row) {
02792 list($first_row, $last_row) = array($last_row, $first_row);
02793 }
02794
02795 if ($first_col > $last_col) {
02796 list($first_col, $last_col) = array($last_col, $first_col);
02797 }
02798
02799 $header = pack("vv", $record, $length);
02800 $data = pack("vvvvv", $cref, $first_row, $last_row,
02801 $first_col, $last_col);
02802
02803 $this->_append($header.$data);
02804 }
02805
02811 function _storePrintHeaders()
02812 {
02813 $record = 0x002a;
02814 $length = 0x0002;
02815
02816 $fPrintRwCol = $this->_print_headers;
02817
02818 $header = pack("vv", $record, $length);
02819 $data = pack("v", $fPrintRwCol);
02820 $this->_prepend($header.$data);
02821 }
02822
02829 function _storePrintGridlines()
02830 {
02831 $record = 0x002b;
02832 $length = 0x0002;
02833
02834 $fPrintGrid = $this->_print_gridlines;
02835
02836 $header = pack("vv", $record, $length);
02837 $data = pack("v", $fPrintGrid);
02838 $this->_prepend($header.$data);
02839 }
02840
02847 function _storeGridset()
02848 {
02849 $record = 0x0082;
02850 $length = 0x0002;
02851
02852 $fGridSet = !($this->_print_gridlines);
02853
02854 $header = pack("vv", $record, $length);
02855 $data = pack("v", $fGridSet);
02856 $this->_prepend($header.$data);
02857 }
02858
02867 function _storeGuts()
02868 {
02869 $record = 0x0080;
02870 $length = 0x0008;
02871
02872 $dxRwGut = 0x0000;
02873 $dxColGut = 0x0000;
02874
02875 $row_level = $this->_outline_row_level;
02876 $col_level = 0;
02877
02878
02879
02880 for ($i=0; $i < count($this->_colinfo); $i++)
02881 {
02882
02883 if (count($col_level) >= 6) {
02884 $col_level = max($this->_colinfo[$i][5], $col_level);
02885 }
02886 }
02887
02888
02889 $col_level = max(0, min($col_level, 7));
02890
02891
02892 if ($row_level) {
02893 $row_level++;
02894 }
02895 if ($col_level) {
02896 $col_level++;
02897 }
02898
02899 $header = pack("vv", $record, $length);
02900 $data = pack("vvvv", $dxRwGut, $dxColGut, $row_level, $col_level);
02901
02902 $this->_prepend($header.$data);
02903 }
02904
02905
02912 function _storeWsbool()
02913 {
02914 $record = 0x0081;
02915 $length = 0x0002;
02916 $grbit = 0x0000;
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928 $grbit |= 0x0001;
02929 if ($this->_outline_style) {
02930 $grbit |= 0x0020;
02931 }
02932 if ($this->_outline_below) {
02933 $grbit |= 0x0040;
02934 }
02935 if ($this->_outline_right) {
02936 $grbit |= 0x0080;
02937 }
02938 if ($this->_fit_page) {
02939 $grbit |= 0x0100;
02940 }
02941 if ($this->_outline_on) {
02942 $grbit |= 0x0400;
02943 }
02944
02945 $header = pack("vv", $record, $length);
02946 $data = pack("v", $grbit);
02947 $this->_prepend($header.$data);
02948 }
02949
02955 function _storeHbreak()
02956 {
02957
02958 if (empty($this->_hbreaks)) {
02959 return;
02960 }
02961
02962
02963 $breaks = $this->_hbreaks;
02964 sort($breaks, SORT_NUMERIC);
02965 if ($breaks[0] == 0) {
02966 array_shift($breaks);
02967 }
02968
02969 $record = 0x001b;
02970 $cbrk = count($breaks);
02971 $length = 2 + 6*$cbrk;
02972
02973 $header = pack("vv", $record, $length);
02974 $data = pack("v", $cbrk);
02975
02976
02977 foreach($breaks as $break) {
02978 $data .= pack("vvv", $break, 0x0000, 0x00ff);
02979 }
02980
02981 $this->_prepend($header.$data);
02982 }
02983
02984
02990 function _storeVbreak()
02991 {
02992
02993 if (empty($this->_vbreaks)) {
02994 return;
02995 }
02996
02997
02998
02999 $breaks = array_slice($this->_vbreaks,0,1000);
03000
03001
03002 sort($breaks, SORT_NUMERIC);
03003 if ($breaks[0] == 0) {
03004 array_shift($breaks);
03005 }
03006
03007 $record = 0x001a;
03008 $cbrk = count($breaks);
03009 $length = 2 + 6*$cbrk;
03010
03011 $header = pack("vv", $record, $length);
03012 $data = pack("v", $cbrk);
03013
03014
03015 foreach ($breaks as $break) {
03016 $data .= pack("vvv", $break, 0x0000, 0xffff);
03017 }
03018
03019 $this->_prepend($header.$data);
03020 }
03021
03027 function _storeProtect()
03028 {
03029
03030 if ($this->_protect == 0) {
03031 return;
03032 }
03033
03034 $record = 0x0012;
03035 $length = 0x0002;
03036
03037 $fLock = $this->_protect;
03038
03039 $header = pack("vv", $record, $length);
03040 $data = pack("v", $fLock);
03041
03042 $this->_prepend($header.$data);
03043 }
03044
03050 function _storePassword()
03051 {
03052
03053 if (($this->_protect == 0) or (!isset($this->_password))) {
03054 return;
03055 }
03056
03057 $record = 0x0013;
03058 $length = 0x0002;
03059
03060 $wPassword = $this->_password;
03061
03062 $header = pack("vv", $record, $length);
03063 $data = pack("v", $wPassword);
03064
03065 $this->_prepend($header.$data);
03066 }
03067
03068
03081 function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1)
03082 {
03083 $bitmap_array = $this->_processBitmap($bitmap);
03084 if ($this->isError($bitmap_array))
03085 {
03086 $this->writeString($row, $col, $bitmap_array->getMessage());
03087 return;
03088 }
03089 list($width, $height, $size, $data) = $bitmap_array;
03090
03091
03092 $width *= $scale_x;
03093 $height *= $scale_y;
03094
03095
03096 $this->_positionImage($col, $row, $x, $y, $width, $height);
03097
03098
03099 $record = 0x007f;
03100 $length = 8 + $size;
03101 $cf = 0x09;
03102 $env = 0x01;
03103 $lcb = $size;
03104
03105 $header = pack("vvvvV", $record, $length, $cf, $env, $lcb);
03106 $this->_append($header.$data);
03107 }
03108
03160 function _positionImage($col_start, $row_start, $x1, $y1, $width, $height)
03161 {
03162
03163 $col_end = $col_start;
03164 $row_end = $row_start;
03165
03166
03167 if ($x1 >= $this->_sizeCol($col_start))
03168 {
03169 $x1 = 0;
03170 }
03171 if ($y1 >= $this->_sizeRow($row_start))
03172 {
03173 $y1 = 0;
03174 }
03175
03176 $width = $width + $x1 -1;
03177 $height = $height + $y1 -1;
03178
03179
03180 while ($width >= $this->_sizeCol($col_end)) {
03181 $width -= $this->_sizeCol($col_end);
03182 $col_end++;
03183 }
03184
03185
03186 while ($height >= $this->_sizeRow($row_end)) {
03187 $height -= $this->_sizeRow($row_end);
03188 $row_end++;
03189 }
03190
03191
03192
03193
03194 if ($this->_sizeCol($col_start) == 0)
03195 return;
03196 if ($this->_sizeCol($col_end) == 0)
03197 return;
03198 if ($this->_sizeRow($row_start) == 0)
03199 return;
03200 if ($this->_sizeRow($row_end) == 0)
03201 return;
03202
03203
03204 $x1 = $x1 / $this->_sizeCol($col_start) * 1024;
03205 $y1 = $y1 / $this->_sizeRow($row_start) * 256;
03206 $x2 = $width / $this->_sizeCol($col_end) * 1024;
03207 $y2 = $height / $this->_sizeRow($row_end) * 256;
03208
03209 $this->_storeObjPicture( $col_start, $x1,
03210 $row_start, $y1,
03211 $col_end, $x2,
03212 $row_end, $y2
03213 );
03214 }
03215
03225 function _sizeCol($col)
03226 {
03227
03228 if (isset($this->col_sizes[$col])) {
03229 if ($this->col_sizes[$col] == 0) {
03230 return(0);
03231 }
03232 else {
03233 return(floor(7 * $this->col_sizes[$col] + 5));
03234 }
03235 }
03236 else {
03237 return(64);
03238 }
03239 }
03240
03251 function _sizeRow($row)
03252 {
03253
03254 if (isset($this->row_sizes[$row])) {
03255 if ($this->row_sizes[$row] == 0) {
03256 return(0);
03257 }
03258 else {
03259 return(floor(4/3 * $this->row_sizes[$row]));
03260 }
03261 }
03262 else {
03263 return(17);
03264 }
03265 }
03266
03281 function _storeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB)
03282 {
03283 $record = 0x005d;
03284 $length = 0x003c;
03285
03286 $cObj = 0x0001;
03287 $OT = 0x0008;
03288 $id = 0x0001;
03289 $grbit = 0x0614;
03290
03291 $cbMacro = 0x0000;
03292 $Reserved1 = 0x0000;
03293 $Reserved2 = 0x0000;
03294
03295 $icvBack = 0x09;
03296 $icvFore = 0x09;
03297 $fls = 0x00;
03298 $fAuto = 0x00;
03299 $icv = 0x08;
03300 $lns = 0xff;
03301 $lnw = 0x01;
03302 $fAutoB = 0x00;
03303 $frs = 0x0000;
03304 $cf = 0x0009;
03305 $Reserved3 = 0x0000;
03306 $cbPictFmla = 0x0000;
03307 $Reserved4 = 0x0000;
03308 $grbit2 = 0x0001;
03309 $Reserved5 = 0x0000;
03310
03311
03312 $header = pack("vv", $record, $length);
03313 $data = pack("V", $cObj);
03314 $data .= pack("v", $OT);
03315 $data .= pack("v", $id);
03316 $data .= pack("v", $grbit);
03317 $data .= pack("v", $colL);
03318 $data .= pack("v", $dxL);
03319 $data .= pack("v", $rwT);
03320 $data .= pack("v", $dyT);
03321 $data .= pack("v", $colR);
03322 $data .= pack("v", $dxR);
03323 $data .= pack("v", $rwB);
03324 $data .= pack("v", $dyB);
03325 $data .= pack("v", $cbMacro);
03326 $data .= pack("V", $Reserved1);
03327 $data .= pack("v", $Reserved2);
03328 $data .= pack("C", $icvBack);
03329 $data .= pack("C", $icvFore);
03330 $data .= pack("C", $fls);
03331 $data .= pack("C", $fAuto);
03332 $data .= pack("C", $icv);
03333 $data .= pack("C", $lns);
03334 $data .= pack("C", $lnw);
03335 $data .= pack("C", $fAutoB);
03336 $data .= pack("v", $frs);
03337 $data .= pack("V", $cf);
03338 $data .= pack("v", $Reserved3);
03339 $data .= pack("v", $cbPictFmla);
03340 $data .= pack("v", $Reserved4);
03341 $data .= pack("v", $grbit2);
03342 $data .= pack("V", $Reserved5);
03343
03344 $this->_append($header.$data);
03345 }
03346
03356 function _processBitmap($bitmap)
03357 {
03358
03359 $bmp_fd = @fopen($bitmap,"rb");
03360 if (!$bmp_fd) {
03361 $this->raiseError("Couldn't import $bitmap");
03362 }
03363
03364
03365 $data = fread($bmp_fd, filesize($bitmap));
03366
03367
03368 if (strlen($data) <= 0x36) {
03369 $this->raiseError("$bitmap doesn't contain enough data.\n");
03370 }
03371
03372
03373 $identity = unpack("A2", $data);
03374 if ($identity[''] != "BM") {
03375 $this->raiseError("$bitmap doesn't appear to be a valid bitmap image.\n");
03376 }
03377
03378
03379 $data = substr($data, 2);
03380
03381
03382
03383
03384 $size_array = unpack("V", substr($data, 0, 4));
03385 $size = $size_array[''];
03386 $data = substr($data, 4);
03387 $size -= 0x36;
03388 $size += 0x0C;
03389
03390
03391 $data = substr($data, 12);
03392
03393
03394 $width_and_height = unpack("V2", substr($data, 0, 8));
03395 $width = $width_and_height[1];
03396 $height = $width_and_height[2];
03397 $data = substr($data, 8);
03398 if ($width > 0xFFFF) {
03399 $this->raiseError("$bitmap: largest image width supported is 65k.\n");
03400 }
03401 if ($height > 0xFFFF) {
03402 $this->raiseError("$bitmap: largest image height supported is 65k.\n");
03403 }
03404
03405
03406 $planes_and_bitcount = unpack("v2", substr($data, 0, 4));
03407 $data = substr($data, 4);
03408 if ($planes_and_bitcount[2] != 24) {
03409 $this->raiseError("$bitmap isn't a 24bit true color bitmap.\n");
03410 }
03411 if ($planes_and_bitcount[1] != 1) {
03412 $this->raiseError("$bitmap: only 1 plane nupported in bitmap image.\n");
03413 }
03414
03415
03416 $compression = unpack("V", substr($data, 0, 4));
03417 $data = substr($data, 4);
03418
03419
03420 if ($compression[""] != 0) {
03421 $this->raiseError("$bitmap: compression not supported in bitmap image.\n");
03422 }
03423
03424
03425 $data = substr($data, 20);
03426
03427
03428 $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18);
03429 $data = $header . $data;
03430
03431 return (array($width, $height, $size, $data));
03432 }
03433
03440 function _storeZoom()
03441 {
03442
03443 if ($this->_zoom == 100) {
03444 return;
03445 }
03446
03447 $record = 0x00A0;
03448 $length = 0x0004;
03449
03450 $header = pack("vv", $record, $length);
03451 $data = pack("vv", $this->_zoom, 100);
03452 $this->_append($header.$data);
03453 }
03454
03458 function setValidation($row1, $col1, $row2, $col2, &$validator)
03459 {
03460 $this->_dv[] = $validator->_getData() .
03461 pack("vvvvv", 1, $row1, $row2, $col1, $col2);
03462 }
03463
03469 function _storeDataValidity()
03470 {
03471 $record = 0x01b2;
03472 $length = 0x0012;
03473
03474 $grbit = 0x0002;
03475 $horPos = 0x00000000;
03476 $verPos = 0x00000000;
03477 $objId = 0xffffffff;
03478
03479 $header = pack('vv', $record, $length);
03480 $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId,
03481 count($this->_dv));
03482 $this->_append($header.$data);
03483
03484 $record = 0x01be;
03485 foreach($this->_dv as $dv)
03486 {
03487 $length = strlen($dv);
03488 $header = pack("vv", $record, $length);
03489 $this->_append($header.$dv);
03490 }
03491 }
03492 }
03493 ?>