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
00468 $fh = tmpfile();
00469 if ( $fh) {
00470
00471 $this->_filehandle = $fh;
00472 }
00473 else {
00474
00475 $this->_using_tmpfile = false;
00476 }
00477 }
00478
00488 function close($sheetnames)
00489 {
00490 $num_sheets = count($sheetnames);
00491
00492
00493
00494
00495
00496
00497 $this->_storeDimensions();
00498
00499
00500 $this->_storePassword();
00501
00502
00503 $this->_storeProtect();
00504
00505
00506 $this->_storeSetup();
00507
00508
00509
00510 $this->_storeMarginBottom();
00511
00512
00513 $this->_storeMarginTop();
00514
00515
00516 $this->_storeMarginRight();
00517
00518
00519 $this->_storeMarginLeft();
00520
00521
00522 $this->_storeVcenter();
00523
00524
00525 $this->_storeHcenter();
00526
00527
00528 $this->_storeFooter();
00529
00530
00531 $this->_storeHeader();
00532
00533
00534 $this->_storeVbreak();
00535
00536
00537 $this->_storeHbreak();
00538
00539
00540 $this->_storeWsbool();
00541
00542
00543 $this->_storeGridset();
00544
00545
00546 if ($this->_BIFF_version == 0x0500) {
00547 $this->_storeGuts();
00548 }
00549
00550
00551 $this->_storePrintGridlines();
00552
00553
00554 $this->_storePrintHeaders();
00555
00556
00557 if ($this->_BIFF_version == 0x0500) {
00558 for ($i = $num_sheets; $i > 0; $i--) {
00559 $sheetname = $sheetnames[$i-1];
00560 $this->_storeExternsheet($sheetname);
00561 }
00562 }
00563
00564
00565 if ($this->_BIFF_version == 0x0500) {
00566 $this->_storeExterncount($num_sheets);
00567 }
00568
00569
00570 if (!empty($this->_colinfo))
00571 {
00572 for ($i=0; $i < count($this->_colinfo); $i++) {
00573 $this->_storeColinfo($this->_colinfo[$i]);
00574 }
00575 $this->_storeDefcol();
00576 }
00577
00578
00579 $this->_storeBof(0x0010);
00580
00581
00582
00583
00584
00585
00586 $this->_storeWindow2();
00587 $this->_storeZoom();
00588 if (!empty($this->_panes)) {
00589 $this->_storePanes($this->_panes);
00590 }
00591 $this->_storeSelection($this->_selection);
00592 $this->_storeMergedCells();
00593
00594
00595
00596
00597 $this->_storeEof();
00598 }
00599
00607 function getName()
00608 {
00609 return $this->name;
00610 }
00611
00618 function getData()
00619 {
00620 $buffer = 4096;
00621
00622
00623 if (isset($this->_data))
00624 {
00625 $tmp = $this->_data;
00626 unset($this->_data);
00627 $fh = $this->_filehandle;
00628 if ($this->_using_tmpfile) {
00629 fseek($fh, 0);
00630 }
00631 return $tmp;
00632 }
00633
00634 if ($this->_using_tmpfile)
00635 {
00636 if ($tmp = fread($this->_filehandle, $buffer)) {
00637 return $tmp;
00638 }
00639 }
00640
00641
00642 return '';
00643 }
00644
00654 function setMerge($first_row, $first_col, $last_row, $last_col)
00655 {
00656 if (($last_row < $first_row) or ($last_col < $first_col)) {
00657 return;
00658 }
00659
00660
00661 $this->_merged_ranges[] = array($first_row, $first_col, $last_row, $last_col);
00662 }
00663
00670 function select()
00671 {
00672 $this->selected = 1;
00673 }
00674
00682 function activate()
00683 {
00684 $this->selected = 1;
00685 $this->activesheet = $this->index;
00686 }
00687
00695 function setFirstSheet()
00696 {
00697 $this->firstsheet = $this->index;
00698 }
00699
00708 function protect($password)
00709 {
00710 $this->_protect = 1;
00711 $this->_password = $this->_encodePassword($password);
00712 }
00713
00725 function setColumn($firstcol, $lastcol, $width, $format = 0, $hidden = 0, $level = 0)
00726 {
00727 $this->_colinfo[] = array($firstcol, $lastcol, $width, &$format, $hidden, $level);
00728
00729
00730 $width = ($hidden) ? 0 : $width;
00731
00732 for ($col = $firstcol; $col <= $lastcol; $col++) {
00733 $this->col_sizes[$col] = $width;
00734 }
00735 }
00736
00746 function setSelection($first_row,$first_column,$last_row,$last_column)
00747 {
00748 $this->_selection = array($first_row,$first_column,$last_row,$last_column);
00749 }
00750
00762 function freezePanes($panes)
00763 {
00764 $this->_frozen = 1;
00765 $this->_panes = $panes;
00766 }
00767
00779 function thawPanes($panes)
00780 {
00781 $this->_frozen = 0;
00782 $this->_panes = $panes;
00783 }
00784
00790 function setPortrait()
00791 {
00792 $this->_orientation = 1;
00793 }
00794
00800 function setLandscape()
00801 {
00802 $this->_orientation = 0;
00803 }
00804
00811 function setPaper($size = 0)
00812 {
00813 $this->_paper_size = $size;
00814 }
00815
00816
00824 function setHeader($string,$margin = 0.50)
00825 {
00826 if (strlen($string) >= 255) {
00827
00828 return;
00829 }
00830 $this->_header = $string;
00831 $this->_margin_head = $margin;
00832 }
00833
00841 function setFooter($string,$margin = 0.50)
00842 {
00843 if (strlen($string) >= 255) {
00844
00845 return;
00846 }
00847 $this->_footer = $string;
00848 $this->_margin_foot = $margin;
00849 }
00850
00857 function centerHorizontally($center = 1)
00858 {
00859 $this->_hcenter = $center;
00860 }
00861
00868 function centerVertically($center = 1)
00869 {
00870 $this->_vcenter = $center;
00871 }
00872
00879 function setMargins($margin)
00880 {
00881 $this->setMarginLeft($margin);
00882 $this->setMarginRight($margin);
00883 $this->setMarginTop($margin);
00884 $this->setMarginBottom($margin);
00885 }
00886
00893 function setMargins_LR($margin)
00894 {
00895 $this->setMarginLeft($margin);
00896 $this->setMarginRight($margin);
00897 }
00898
00905 function setMargins_TB($margin)
00906 {
00907 $this->setMarginTop($margin);
00908 $this->setMarginBottom($margin);
00909 }
00910
00917 function setMarginLeft($margin = 0.75)
00918 {
00919 $this->_margin_left = $margin;
00920 }
00921
00928 function setMarginRight($margin = 0.75)
00929 {
00930 $this->_margin_right = $margin;
00931 }
00932
00939 function setMarginTop($margin = 1.00)
00940 {
00941 $this->_margin_top = $margin;
00942 }
00943
00950 function setMarginBottom($margin = 1.00)
00951 {
00952 $this->_margin_bottom = $margin;
00953 }
00954
00962 function repeatRows($first_row, $last_row = NULL)
00963 {
00964 $this->title_rowmin = $first_row;
00965 if (isset($last_row)) {
00966 $this->title_rowmax = $last_row;
00967 }
00968 else {
00969 $this->title_rowmax = $first_row;
00970 }
00971 }
00972
00980 function repeatColumns($first_col, $last_col = NULL)
00981 {
00982 $this->title_colmin = $first_col;
00983 if (isset($last_col)) {
00984 $this->title_colmax = $last_col;
00985 }
00986 else {
00987 $this->title_colmax = $first_col;
00988 }
00989 }
00990
01000 function printArea($first_row, $first_col, $last_row, $last_col)
01001 {
01002 $this->print_rowmin = $first_row;
01003 $this->print_colmin = $first_col;
01004 $this->print_rowmax = $last_row;
01005 $this->print_colmax = $last_col;
01006 }
01007
01008
01014 function hideGridlines()
01015 {
01016 $this->_print_gridlines = 0;
01017 }
01018
01025 function printRowColHeaders($print = 1)
01026 {
01027 $this->_print_headers = $print;
01028 }
01029
01039 function fitToPages($width, $height)
01040 {
01041 $this->_fit_page = 1;
01042 $this->_fit_width = $width;
01043 $this->_fit_height = $height;
01044 }
01045
01053 function setHPagebreaks($breaks)
01054 {
01055 foreach($breaks as $break) {
01056 array_push($this->_hbreaks,$break);
01057 }
01058 }
01059
01067 function setVPagebreaks($breaks)
01068 {
01069 foreach($breaks as $break) {
01070 array_push($this->_vbreaks,$break);
01071 }
01072 }
01073
01074
01081 function setZoom($scale = 100)
01082 {
01083
01084 if ($scale < 10 or $scale > 400)
01085 {
01086 $this->raiseError("Zoom factor $scale outside range: 10 <= zoom <= 400");
01087 $scale = 100;
01088 }
01089
01090 $this->_zoom = floor($scale);
01091 }
01092
01100 function setPrintScale($scale = 100)
01101 {
01102
01103 if ($scale < 10 or $scale > 400)
01104 {
01105 $this->raiseError("Print scale $scale outside range: 10 <= zoom <= 400");
01106 $scale = 100;
01107 }
01108
01109
01110 $this->_fit_page = 0;
01111
01112 $this->_print_scale = floor($scale);
01113 }
01114
01124 function write($row, $col, $token, $format = 0)
01125 {
01126
01127
01128
01129
01130
01131
01132
01133 if (preg_match("/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/",$token)) {
01134 return $this->writeNumber($row,$col,$token,$format);
01135 }
01136
01137 elseif (preg_match("/^[fh]tt?p:\/\//",$token)) {
01138 return $this->writeUrl($row, $col, $token, '', $format);
01139 }
01140
01141 elseif (preg_match("/^mailto:/",$token)) {
01142 return $this->writeUrl($row, $col, $token, '', $format);
01143 }
01144
01145 elseif (preg_match("/^(?:in|ex)ternal:/",$token)) {
01146 return $this->writeUrl($row, $col, $token, '', $format);
01147 }
01148
01149 elseif (preg_match("/^=/",$token)) {
01150 return $this->writeFormula($row, $col, $token, $format);
01151 }
01152
01153 elseif (preg_match("/^@/",$token)) {
01154 return $this->writeFormula($row, $col, $token, $format);
01155 }
01156
01157 elseif ($token == '') {
01158 return $this->writeBlank($row,$col,$format);
01159 }
01160
01161 else {
01162 return $this->writeString($row,$col,$token,$format);
01163 }
01164 }
01165
01177 function writeRow($row, $col, $val, $format=0)
01178 {
01179 $retval = '';
01180 if (is_array($val)) {
01181 foreach($val as $v) {
01182 if (is_array($v)) {
01183 $this->writeCol($row, $col, $v, $format);
01184 } else {
01185 $this->write($row, $col, $v, $format);
01186 }
01187 $col++;
01188 }
01189 } else {
01190 $retval = new PEAR_Error('$val needs to be an array');
01191 }
01192 return($retval);
01193 }
01194
01206 function writeCol($row, $col, $val, $format=0)
01207 {
01208 $retval = '';
01209 if (is_array($val)) {
01210 foreach($val as $v) {
01211 $this->write($row, $col, $v, $format);
01212 $row++;
01213 }
01214 } else {
01215 $retval = new PEAR_Error('$val needs to be an array');
01216 }
01217 return($retval);
01218 }
01219
01227 function _XF(&$format)
01228 {
01229 if ($format != 0) {
01230 return($format->getXfIndex());
01231 }
01232 else {
01233 return(0x0F);
01234 }
01235 }
01236
01237
01238
01239
01240
01241
01242
01243
01244
01252 function _append($data)
01253 {
01254 if ($this->_using_tmpfile)
01255 {
01256
01257 if (strlen($data) > $this->_limit) {
01258 $data = $this->_addContinue($data);
01259 }
01260 fwrite($this->_filehandle,$data);
01261 $this->_datasize += strlen($data);
01262 }
01263 else {
01264 parent::_append($data);
01265 }
01266 }
01267
01278 function _substituteCellref($cell)
01279 {
01280 $cell = strtoupper($cell);
01281
01282
01283 if (preg_match("/([A-I]?[A-Z]):([A-I]?[A-Z])/",$cell,$match)) {
01284 list($no_use, $col1) = $this->_cellToRowcol($match[1] .'1');
01285 list($no_use, $col2) = $this->_cellToRowcol($match[2] .'1');
01286 return(array($col1, $col2));
01287 }
01288
01289
01290 if (preg_match("/\$?([A-I]?[A-Z]\$?\d+):\$?([A-I]?[A-Z]\$?\d+)/",$cell,$match)) {
01291 list($row1, $col1) = $this->_cellToRowcol($match[1]);
01292 list($row2, $col2) = $this->_cellToRowcol($match[2]);
01293 return(array($row1, $col1, $row2, $col2));
01294 }
01295
01296
01297 if (preg_match("/\$?([A-I]?[A-Z]\$?\d+)/",$cell)) {
01298 list($row1, $col1) = $this->_cellToRowcol($match[1]);
01299 return(array($row1, $col1));
01300 }
01301
01302
01303 $this->raiseError("Unknown cell reference $cell", 0, PEAR_ERROR_DIE);
01304 }
01305
01314 function _cellToRowcol($cell)
01315 {
01316 preg_match("/\$?([A-I]?[A-Z])\$?(\d+)/",$cell,$match);
01317 $col = $match[1];
01318 $row = $match[2];
01319
01320
01321 $chars = split('', $col);
01322 $expn = 0;
01323 $col = 0;
01324
01325 while ($chars) {
01326 $char = array_pop($chars);
01327 $col += (ord($char) -ord('A') +1) * pow(26,$expn);
01328 $expn++;
01329 }
01330
01331
01332 $row--;
01333 $col--;
01334
01335 return(array($row, $col));
01336 }
01337
01345 function _encodePassword($plaintext)
01346 {
01347 $password = 0x0000;
01348 $i = 1;
01349
01350
01351 $chars = preg_split('//', $plaintext, -1, PREG_SPLIT_NO_EMPTY);
01352 foreach($chars as $char)
01353 {
01354 $value = ord($char) << $i;
01355 $rotated_bits = $value >> 15;
01356 $value &= 0x7fff;
01357 $password ^= ($value | $rotated_bits);
01358 $i++;
01359 }
01360
01361 $password ^= strlen($plaintext);
01362 $password ^= 0xCE4B;
01363
01364 return($password);
01365 }
01366
01376 function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false)
01377 {
01378 $this->_outline_on = $visible;
01379 $this->_outline_below = $symbols_below;
01380 $this->_outline_right = $symbols_right;
01381 $this->_outline_style = $auto_style;
01382
01383
01384 if ($this->_outline_on) {
01385 $this->_outline_on = 1;
01386 }
01387 }
01388
01389
01390
01391
01392
01393
01394
01395
01411 function writeNumber($row, $col, $num, $format = 0)
01412 {
01413 $record = 0x0203;
01414 $length = 0x000E;
01415
01416 $xf = $this->_XF($format);
01417
01418
01419 if ($row >= $this->_xls_rowmax)
01420 {
01421 return(-2);
01422 }
01423 if ($col >= $this->_xls_colmax)
01424 {
01425 return(-2);
01426 }
01427 if ($row < $this->_dim_rowmin)
01428 {
01429 $this->_dim_rowmin = $row;
01430 }
01431 if ($row > $this->_dim_rowmax)
01432 {
01433 $this->_dim_rowmax = $row;
01434 }
01435 if ($col < $this->_dim_colmin)
01436 {
01437 $this->_dim_colmin = $col;
01438 }
01439 if ($col > $this->_dim_colmax)
01440 {
01441 $this->_dim_colmax = $col;
01442 }
01443
01444 $header = pack("vv", $record, $length);
01445 $data = pack("vvv", $row, $col, $xf);
01446 $xl_double = pack("d", $num);
01447 if ($this->_byte_order)
01448 {
01449 $xl_double = strrev($xl_double);
01450 }
01451
01452 $this->_append($header.$data.$xl_double);
01453 return(0);
01454 }
01455
01471 function writeString($row, $col, $str, $format = 0)
01472 {
01473 if ($this->_BIFF_version == 0x0600) {
01474 return $this->writeStringBIFF8($row, $col, $str, $format);
01475 }
01476 $strlen = strlen($str);
01477 $record = 0x0204;
01478 $length = 0x0008 + $strlen;
01479 $xf = $this->_XF($format);
01480
01481 $str_error = 0;
01482
01483
01484 if ($row >= $this->_xls_rowmax)
01485 {
01486 return(-2);
01487 }
01488 if ($col >= $this->_xls_colmax)
01489 {
01490 return(-2);
01491 }
01492 if ($row < $this->_dim_rowmin)
01493 {
01494 $this->_dim_rowmin = $row;
01495 }
01496 if ($row > $this->_dim_rowmax)
01497 {
01498 $this->_dim_rowmax = $row;
01499 }
01500 if ($col < $this->_dim_colmin)
01501 {
01502 $this->_dim_colmin = $col;
01503 }
01504 if ($col > $this->_dim_colmax)
01505 {
01506 $this->_dim_colmax = $col;
01507 }
01508
01509 if ($strlen > $this->_xls_strmax)
01510 {
01511 $str = substr($str, 0, $this->_xls_strmax);
01512 $length = 0x0008 + $this->_xls_strmax;
01513 $strlen = $this->_xls_strmax;
01514 $str_error = -3;
01515 }
01516
01517 $header = pack("vv", $record, $length);
01518 $data = pack("vvvv", $row, $col, $xf, $strlen);
01519 $this->_append($header.$data.$str);
01520 return($str_error);
01521 }
01522
01523 function writeStringBIFF8($row, $col, $str, $format = 0)
01524 {
01525 $strlen = strlen($str);
01526 $record = 0x00FD;
01527 $length = 0x000A;
01528 $xf = $this->_XF($format);
01529 $encoding = 0x0;
01530
01531 $str_error = 0;
01532
01533
01534 if ($this->_checkRowCol($row, $col) == false) {
01535 return -2;
01536 }
01537
01538 $str = pack('vC', $strlen, $encoding).$str;
01539
01540
01541 if (!isset($this->_str_table[$str])) {
01542 $this->_str_table[$str] = $this->_str_unique++;
01543 }
01544 $this->_str_total++;
01545
01546 $header = pack('vv', $record, $length);
01547 $data = pack('vvvV', $row, $col, $xf, $this->_str_table[$str]);
01548 $this->_append($header.$data);
01549 return $str_error;
01550 }
01551
01562 function _checkRowCol($row, $col)
01563 {
01564 if ($row >= $this->_xls_rowmax) {
01565 return false;
01566 }
01567 if ($col >= $this->_xls_colmax) {
01568 return false;
01569 }
01570 if ($row < $this->_dim_rowmin) {
01571 $this->_dim_rowmin = $row;
01572 }
01573 if ($row > $this->_dim_rowmax) {
01574 $this->_dim_rowmax = $row;
01575 }
01576 if ($col < $this->_dim_colmin) {
01577 $this->_dim_colmin = $col;
01578 }
01579 if ($col > $this->_dim_colmax) {
01580 $this->_dim_colmax = $col;
01581 }
01582 return true;
01583 }
01584
01594 function writeNote($row, $col, $note)
01595 {
01596 $note_length = strlen($note);
01597 $record = 0x001C;
01598 $max_length = 2048;
01599
01600
01601
01602 if ($row >= $this->_xls_rowmax)
01603 {
01604 return(-2);
01605 }
01606 if ($col >= $this->_xls_colmax)
01607 {
01608 return(-2);
01609 }
01610 if ($row < $this->_dim_rowmin)
01611 {
01612 $this->_dim_rowmin = $row;
01613 }
01614 if ($row > $this->_dim_rowmax)
01615 {
01616 $this->_dim_rowmax = $row;
01617 }
01618 if ($col < $this->_dim_colmin)
01619 {
01620 $this->_dim_colmin = $col;
01621 }
01622 if ($col > $this->_dim_colmax)
01623 {
01624 $this->_dim_colmax = $col;
01625 }
01626
01627
01628 $length = 0x0006 + min($note_length, 2048);
01629 $header = pack("vv", $record, $length);
01630 $data = pack("vvv", $row, $col, $note_length);
01631 $this->_append($header.$data.substr($note, 0, 2048));
01632
01633 for($i = $max_length; $i < $note_length; $i += $max_length)
01634 {
01635 $chunk = substr($note, $i, $max_length);
01636 $length = 0x0006 + strlen($chunk);
01637 $header = pack("vv", $record, $length);
01638 $data = pack("vvv", -1, 0, strlen($chunk));
01639 $this->_append($header.$data.$chunk);
01640 }
01641 return(0);
01642 }
01643
01661 function writeBlank($row, $col, $format)
01662 {
01663
01664 if ($format == 0)
01665 {
01666 return(0);
01667 }
01668
01669 $record = 0x0201;
01670 $length = 0x0006;
01671 $xf = $this->_XF($format);
01672
01673
01674 if ($row >= $this->_xls_rowmax)
01675 {
01676 return(-2);
01677 }
01678 if ($col >= $this->_xls_colmax)
01679 {
01680 return(-2);
01681 }
01682 if ($row < $this->_dim_rowmin)
01683 {
01684 $this->_dim_rowmin = $row;
01685 }
01686 if ($row > $this->_dim_rowmax)
01687 {
01688 $this->_dim_rowmax = $row;
01689 }
01690 if ($col < $this->_dim_colmin)
01691 {
01692 $this->_dim_colmin = $col;
01693 }
01694 if ($col > $this->_dim_colmax)
01695 {
01696 $this->_dim_colmax = $col;
01697 }
01698
01699 $header = pack("vv", $record, $length);
01700 $data = pack("vvv", $row, $col, $xf);
01701 $this->_append($header.$data);
01702 return 0;
01703 }
01704
01721 function writeFormula($row, $col, $formula, $format = 0)
01722 {
01723 $record = 0x0006;
01724
01725
01726
01727
01728
01729
01730 $xf = $this->_XF($format);
01731 $num = 0x00;
01732 $grbit = 0x03;
01733 $unknown = 0x0000;
01734
01735
01736
01737 if ($this->_checkRowCol($row, $col) == false) {
01738 return -2;
01739 }
01740
01741
01742 if (preg_match("/^=/",$formula)) {
01743 $formula = preg_replace("/(^=)/","",$formula);
01744 }
01745 elseif (preg_match("/^@/",$formula)) {
01746 $formula = preg_replace("/(^@)/","",$formula);
01747 }
01748 else
01749 {
01750
01751 $this->writeString($row, $col, 'Unrecognised character for formula');
01752 return -1;
01753 }
01754
01755
01756 $error = $this->_parser->parse($formula);
01757 if ($this->isError($error))
01758 {
01759 $this->writeString($row, $col, $error->getMessage());
01760 return -1;
01761 }
01762
01763 $formula = $this->_parser->toReversePolish();
01764 if ($this->isError($formula))
01765 {
01766 $this->writeString($row, $col, $formula->getMessage());
01767 return -1;
01768 }
01769
01770 $formlen = strlen($formula);
01771 $length = 0x16 + $formlen;
01772
01773 $header = pack("vv", $record, $length);
01774 $data = pack("vvvdvVv", $row, $col, $xf, $num,
01775 $grbit, $unknown, $formlen);
01776
01777 $this->_append($header.$data.$formula);
01778 return 0;
01779 }
01780
01804 function writeUrl($row, $col, $url, $string = '', $format = 0)
01805 {
01806
01807 return($this->_writeUrlRange($row, $col, $row, $col, $url, $string, $format));
01808 }
01809
01828 function _writeUrlRange($row1, $col1, $row2, $col2, $url, $string = '', $format = 0)
01829 {
01830
01831
01832 if (preg_match('[^internal:]', $url)) {
01833 return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url, $string, $format));
01834 }
01835 if (preg_match('[^external:]', $url)) {
01836 return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url, $string, $format));
01837 }
01838 return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url, $string, $format));
01839 }
01840
01841
01858 function _writeUrlWeb($row1, $col1, $row2, $col2, $url, $str, $format = 0)
01859 {
01860 $record = 0x01B8;
01861 $length = 0x00000;
01862
01863 if ($format == 0) {
01864 $format = $this->_url_format;
01865 }
01866
01867
01868 if ($str == '') {
01869 $str = $url;
01870 }
01871 $str_error = $this->writeString($row1, $col1, $str, $format);
01872 if (($str_error == -2) or ($str_error == -3)) {
01873 return $str_error;
01874 }
01875
01876
01877 $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000");
01878 $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B");
01879
01880
01881 $options = pack("V", 0x03);
01882
01883
01884 $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY));
01885 $url = $url . "\0\0\0";
01886
01887
01888 $url_len = pack("V", strlen($url));
01889
01890
01891 $length = 0x34 + strlen($url);
01892
01893
01894 $header = pack("vv", $record, $length);
01895 $data = pack("vvvv", $row1, $row2, $col1, $col2);
01896
01897
01898 $this->_append( $header. $data.
01899 $unknown1. $options.
01900 $unknown2. $url_len. $url);
01901 return($str_error);
01902 }
01903
01918 function _writeUrlInternal($row1, $col1, $row2, $col2, $url, $str, $format = 0)
01919 {
01920 $record = 0x01B8;
01921 $length = 0x00000;
01922
01923 if ($format == 0) {
01924 $format = $this->_url_format;
01925 }
01926
01927
01928 $url = preg_replace('s[^internal:]', '', $url);
01929
01930
01931 if ($str == '') {
01932 $str = $url;
01933 }
01934 $str_error = $this->writeString($row1, $col1, $str, $format);
01935 if (($str_error == -2) or ($str_error == -3)) {
01936 return $str_error;
01937 }
01938
01939
01940 $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000");
01941
01942
01943 $options = pack("V", 0x08);
01944
01945
01946 $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY));
01947 $url = $url . "\0\0\0";
01948
01949
01950 $url_len = pack("V", floor(strlen($url)/2));
01951
01952
01953 $length = 0x24 + strlen($url);
01954
01955
01956 $header = pack("vv", $record, $length);
01957 $data = pack("vvvv", $row1, $row2, $col1, $col2);
01958
01959
01960 $this->_append($header. $data.
01961 $unknown1. $options.
01962 $url_len. $url);
01963 return($str_error);
01964 }
01965
01984 function _writeUrlExternal($row1, $col1, $row2, $col2, $url, $str, $format = 0)
01985 {
01986
01987
01988
01989 return;
01990 }
01991
01992 $record = 0x01B8;
01993 $length = 0x00000;
01994
01995 if ($format == 0) {
01996 $format = $this->_url_format;
01997 }
01998
01999
02000
02001 $url = preg_replace('[^external:]', '', $url);
02002 $url = preg_replace('[/]', "\\", $url);
02003
02004
02005 if ($str == '') {
02006 $str = preg_replace('[\#]', ' - ', $url);
02007 }
02008 $str_error = $this->writeString($row1, $col1, $str, $format);
02009 if (($str_error == -2) or ($str_error == -3)) {
02010 return $str_error;
02011 }
02012
02013
02014
02015
02016
02017
02018 $absolute = 0x02;
02019 if (!preg_match('[\\]', $url)) {
02020 $absolute = 0x00;
02021 }
02022 if (preg_match('[^\.\.\\]', $url)) {
02023 $absolute = 0x00;
02024 }
02025
02026
02027
02028
02029 list($dir_long , $sheet) = split('/\#/', $url);
02030 $link_type = 0x01 | $absolute;
02031
02032 if (isset($sheet)) {
02033 $link_type |= 0x08;
02034 $sheet_len = pack("V", strlen($sheet) + 0x01);
02035 $sheet = join("\0", split('', $sheet));
02036 $sheet .= "\0\0\0";
02037 }
02038 else {
02039 $sheet_len = '';
02040 $sheet = '';
02041 }
02042
02043
02044 $link_type = pack("V", $link_type);
02045
02046
02047 $up_count = preg_match_all("/\.\.\\/", $dir_long, $useless);
02048 $up_count = pack("v", $up_count);
02049
02050
02051 $dir_short = preg_replace('/\.\.\\/', '', $dir_long) . "\0";
02052
02053
02054 $dir_long = join("\0", split('', $dir_long));
02055 $dir_long = $dir_long . "\0";
02056
02057
02058 $dir_short_len = pack("V", strlen($dir_short) );
02059 $dir_long_len = pack("V", strlen($dir_long) );
02060 $stream_len = pack("V", strlen($dir_long) + 0x06);
02061
02062
02063 $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' );
02064 $unknown2 = pack("H*",'0303000000000000C000000000000046' );
02065 $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000');
02066 $unknown4 = pack("v", 0x03 );
02067
02068
02069 $data = pack("vvvv", $row1, $row2, $col1, $col2) .
02070 $unknown1 .
02071 $link_type .
02072 $unknown2 .
02073 $up_count .
02074 $dir_short_len.
02075 $dir_short .
02076 $unknown3 .
02077 $stream_len .
02078 $dir_long_len .
02079 $unknown4 .
02080 $dir_long .
02081 $sheet_len .
02082 $sheet ;
02083
02084
02085 $length = strlen($data);
02086 $header = pack("vv", $record, $length);
02087
02088
02089 $this->_append($header. $data);
02090 return($str_error);
02091 }
02092
02093
02105 function setRow($row, $height, $format = 0, $hidden = false, $level = 0)
02106 {
02107 $record = 0x0208;
02108 $length = 0x0010;
02109
02110 $colMic = 0x0000;
02111 $colMac = 0x0000;
02112 $irwMac = 0x0000;
02113 $reserved = 0x0000;
02114 $grbit = 0x0000;
02115 $ixfe = $this->_XF($format);
02116
02117
02118 if ($height != NULL) {
02119 $miyRw = $height * 20;
02120 }
02121 else {
02122 $miyRw = 0xff;
02123 }
02124
02125 $level = max(0, min($level, 7));
02126 $this->_outline_row_level = max($level, $this->_outline_row_level);
02127
02128
02129
02130
02131
02132
02133
02134
02135 $grbit |= $level;
02136 if ($hidden) {
02137 $grbit |= 0x0020;
02138 }
02139 $grbit |= 0x0040;
02140 if ($format) {
02141 $grbit |= 0x0080;
02142 }
02143 $grbit |= 0x0100;
02144
02145 $header = pack("vv", $record, $length);
02146 $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw,
02147 $irwMac,$reserved, $grbit, $ixfe);
02148 $this->_append($header.$data);
02149 }
02150
02156 function _storeDimensions()
02157 {
02158 $record = 0x0200;
02159 $row_min = $this->_dim_rowmin;
02160 $row_max = $this->_dim_rowmax + 1;
02161 $col_min = $this->_dim_colmin;
02162 $col_max = $this->_dim_colmax + 1;
02163 $reserved = 0x0000;
02164
02165 if ($this->_BIFF_version == 0x0500) {
02166 $length = 0x000A;
02167 $data = pack("vvvvv", $row_min, $row_max,
02168 $col_min, $col_max, $reserved);
02169 }
02170 elseif ($this->_BIFF_version == 0x0600) {
02171 $length = 0x000E;
02172 $data = pack("VVvvv", $row_min, $row_max,
02173 $col_min, $col_max, $reserved);
02174 }
02175 $header = pack("vv", $record, $length);
02176 $this->_prepend($header.$data);
02177 }
02178
02184 function _storeWindow2()
02185 {
02186 $record = 0x023E;
02187 if ($this->_BIFF_version == 0x0500) {
02188 $length = 0x000A;
02189 }
02190 elseif ($this->_BIFF_version == 0x0600) {
02191 $length = 0x0012;
02192 }
02193
02194 $grbit = 0x00B6;
02195 $rwTop = 0x0000;
02196 $colLeft = 0x0000;
02197
02198
02199
02200 $fDspFmla = 0;
02201 $fDspGrid = 1;
02202 $fDspRwCol = 1;
02203 $fFrozen = $this->_frozen;
02204 $fDspZeros = 1;
02205 $fDefaultHdr = 1;
02206 $fArabic = 0;
02207 $fDspGuts = $this->_outline_on;
02208 $fFrozenNoSplit = 0;
02209 $fSelected = $this->selected;
02210 $fPaged = 1;
02211
02212 $grbit = $fDspFmla;
02213 $grbit |= $fDspGrid << 1;
02214 $grbit |= $fDspRwCol << 2;
02215 $grbit |= $fFrozen << 3;
02216 $grbit |= $fDspZeros << 4;
02217 $grbit |= $fDefaultHdr << 5;
02218 $grbit |= $fArabic << 6;
02219 $grbit |= $fDspGuts << 7;
02220 $grbit |= $fFrozenNoSplit << 8;
02221 $grbit |= $fSelected << 9;
02222 $grbit |= $fPaged << 10;
02223
02224 $header = pack("vv", $record, $length);
02225 $data = pack("vvv", $grbit, $rwTop, $colLeft);
02226
02227 if ($this->_BIFF_version == 0x0500) {
02228 $rgbHdr = 0x00000000;
02229 $data .= pack("V", $rgbHdr);
02230 }
02231 elseif ($this->_BIFF_version == 0x0600) {
02232 $rgbHdr = 0x0040;
02233 $zoom_factor_page_break = 0x0000;
02234 $zoom_factor_normal = 0x0000;
02235 $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000);
02236 }
02237 $this->_append($header.$data);
02238 }
02239
02245 function _storeDefcol()
02246 {
02247 $record = 0x0055;
02248 $length = 0x0002;
02249 $colwidth = 0x0008;
02250
02251 $header = pack("vv", $record, $length);
02252 $data = pack("v", $colwidth);
02253 $this->_prepend($header.$data);
02254 }
02255
02271 function _storeColinfo($col_array)
02272 {
02273 if (isset($col_array[0])) {
02274 $colFirst = $col_array[0];
02275 }
02276 if (isset($col_array[1])) {
02277 $colLast = $col_array[1];
02278 }
02279 if (isset($col_array[2])) {
02280 $coldx = $col_array[2];
02281 }
02282 else {
02283 $coldx = 8.43;
02284 }
02285 if (isset($col_array[3])) {
02286 $format = $col_array[3];
02287 }
02288 else {
02289 $format = 0;
02290 }
02291 if (isset($col_array[4])) {
02292 $grbit = $col_array[4];
02293 }
02294 else {
02295 $grbit = 0;
02296 }
02297 if (isset($col_array[5])) {
02298 $level = $col_array[5];
02299 }
02300 else {
02301 $level = 0;
02302 }
02303 $record = 0x007D;
02304 $length = 0x000B;
02305
02306 $coldx += 0.72;
02307 $coldx *= 256;
02308
02309 $ixfe = $this->_XF($format);
02310 $reserved = 0x00;
02311
02312 $level = max(0, min($level, 7));
02313 $grbit |= $level << 8;
02314
02315 $header = pack("vv", $record, $length);
02316 $data = pack("vvvvvC", $colFirst, $colLast, $coldx,
02317 $ixfe, $grbit, $reserved);
02318 $this->_prepend($header.$data);
02319 }
02320
02328 function _storeSelection($array)
02329 {
02330 list($rwFirst,$colFirst,$rwLast,$colLast) = $array;
02331 $record = 0x001D;
02332 $length = 0x000F;
02333
02334 $pnn = $this->_active_pane;
02335 $rwAct = $rwFirst;
02336 $colAct = $colFirst;
02337 $irefAct = 0;
02338 $cref = 1;
02339
02340 if (!isset($rwLast)) {
02341 $rwLast = $rwFirst;
02342 }
02343 if (!isset($colLast)) {
02344 $colLast = $colFirst;
02345 }
02346
02347
02348 if ($rwFirst > $rwLast)
02349 {
02350 list($rwFirst, $rwLast) = array($rwLast, $rwFirst);
02351 }
02352
02353 if ($colFirst > $colLast)
02354 {
02355 list($colFirst, $colLast) = array($colLast, $colFirst);
02356 }
02357
02358 $header = pack("vv", $record, $length);
02359 $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct,
02360 $irefAct, $cref,
02361 $rwFirst, $rwLast,
02362 $colFirst, $colLast);
02363 $this->_append($header.$data);
02364 }
02365
02371 function _storeMergedCells()
02372 {
02373
02374 if (count($this->_merged_ranges) == 0) {
02375 return;
02376 }
02377 $record = 0x00E5;
02378 $length = 2 + count($this->_merged_ranges) * 8;
02379
02380 $header = pack('vv', $record, $length);
02381 $data = pack('v', count($this->_merged_ranges));
02382 foreach ($this->_merged_ranges as $range) {
02383 $data .= pack('vvvv', $range[0], $range[2], $range[1], $range[3]);
02384 }
02385 $this->_append($header.$data);
02386 }
02387
02401 function _storeExterncount($count)
02402 {
02403 $record = 0x0016;
02404 $length = 0x0002;
02405
02406 $header = pack("vv", $record, $length);
02407 $data = pack("v", $count);
02408 $this->_prepend($header.$data);
02409 }
02410
02420 function _storeExternsheet($sheetname)
02421 {
02422 $record = 0x0017;
02423
02424
02425
02426
02427 if ($this->name == $sheetname) {
02428 $sheetname = '';
02429 $length = 0x02;
02430 $cch = 1;
02431 $rgch = 0x02;
02432 }
02433 else {
02434 $length = 0x02 + strlen($sheetname);
02435 $cch = strlen($sheetname);
02436 $rgch = 0x03;
02437 }
02438
02439 $header = pack("vv", $record, $length);
02440 $data = pack("CC", $cch, $rgch);
02441 $this->_prepend($header.$data.$sheetname);
02442 }
02443
02458 function _storePanes($panes)
02459 {
02460 $y = $panes[0];
02461 $x = $panes[1];
02462 $rwTop = $panes[2];
02463 $colLeft = $panes[3];
02464 if (count($panes) > 4) {
02465 $pnnAct = $panes[4];
02466 }
02467 else {
02468 $pnnAct = NULL;
02469 }
02470 $record = 0x0041;
02471 $length = 0x000A;
02472
02473
02474 if ($this->_frozen)
02475 {
02476
02477 if (!isset($rwTop)) {
02478 $rwTop = $y;
02479 }
02480 if (!isset($colLeft)) {
02481 $colLeft = $x;
02482 }
02483 }
02484 else
02485 {
02486
02487 if (!isset($rwTop)) {
02488 $rwTop = 0;
02489 }
02490 if (!isset($colLeft)) {
02491 $colLeft = 0;
02492 }
02493
02494
02495
02496
02497
02498
02499 $y = 20*$y + 255;
02500 $x = 113.879*$x + 390;
02501 }
02502
02503
02504
02505
02506
02507 if (!isset($pnnAct))
02508 {
02509 if ($x != 0 and $y != 0)
02510 $pnnAct = 0;
02511 if ($x != 0 and $y == 0)
02512 $pnnAct = 1;
02513 if ($x == 0 and $y != 0)
02514 $pnnAct = 2;
02515 if ($x == 0 and $y == 0)
02516 $pnnAct = 3;
02517 }
02518
02519 $this->_active_pane = $pnnAct;
02520
02521 $header = pack("vv", $record, $length);
02522 $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct);
02523 $this->_append($header.$data);
02524 }
02525
02531 function _storeSetup()
02532 {
02533 $record = 0x00A1;
02534 $length = 0x0022;
02535
02536 $iPaperSize = $this->_paper_size;
02537 $iScale = $this->_print_scale;
02538 $iPageStart = 0x01;
02539 $iFitWidth = $this->_fit_width;
02540 $iFitHeight = $this->_fit_height;
02541 $grbit = 0x00;
02542 $iRes = 0x0258;
02543 $iVRes = 0x0258;
02544 $numHdr = $this->_margin_head;
02545 $numFtr = $this->_margin_foot;
02546 $iCopies = 0x01;
02547
02548 $fLeftToRight = 0x0;
02549 $fLandscape = $this->_orientation;
02550 $fNoPls = 0x0;
02551 $fNoColor = 0x0;
02552 $fDraft = 0x0;
02553 $fNotes = 0x0;
02554 $fNoOrient = 0x0;
02555 $fUsePage = 0x0;
02556
02557 $grbit = $fLeftToRight;
02558 $grbit |= $fLandscape << 1;
02559 $grbit |= $fNoPls << 2;
02560 $grbit |= $fNoColor << 3;
02561 $grbit |= $fDraft << 4;
02562 $grbit |= $fNotes << 5;
02563 $grbit |= $fNoOrient << 6;
02564 $grbit |= $fUsePage << 7;
02565
02566 $numHdr = pack("d", $numHdr);
02567 $numFtr = pack("d", $numFtr);
02568 if ($this->_byte_order)
02569 {
02570 $numHdr = strrev($numHdr);
02571 $numFtr = strrev($numFtr);
02572 }
02573
02574 $header = pack("vv", $record, $length);
02575 $data1 = pack("vvvvvvvv", $iPaperSize,
02576 $iScale,
02577 $iPageStart,
02578 $iFitWidth,
02579 $iFitHeight,
02580 $grbit,
02581 $iRes,
02582 $iVRes);
02583 $data2 = $numHdr.$numFtr;
02584 $data3 = pack("v", $iCopies);
02585 $this->_prepend($header.$data1.$data2.$data3);
02586 }
02587
02593 function _storeHeader()
02594 {
02595 $record = 0x0014;
02596
02597 $str = $this->_header;
02598 $cch = strlen($str);
02599 if ($this->_BIFF_version == 0x0600) {
02600 $encoding = 0x0;
02601 $length = 3 + $cch;
02602 }
02603 else {
02604 $length = 1 + $cch;
02605 }
02606 $header = pack("vv", $record, $length);
02607 if ($this->_BIFF_version == 0x0600) {
02608 $data = pack("vC", $cch, $encoding);
02609 }
02610 else {
02611 $data = pack("C", $cch);
02612 }
02613
02614 $this->_append($header.$data.$str);
02615 }
02616
02622 function _storeFooter()
02623 {
02624 $record = 0x0015;
02625
02626 $str = $this->_footer;
02627 $cch = strlen($str);
02628 if ($this->_BIFF_version == 0x0600) {
02629 $encoding = 0x0;
02630 $length = 3 + $cch;
02631 }
02632 else {
02633 $length = 1 + $cch;
02634 }
02635 $header = pack("vv", $record, $length);
02636 if ($this->_BIFF_version == 0x0600) {
02637 $data = pack("vC", $cch, $encoding);
02638 }
02639 else {
02640 $data = pack("C", $cch);
02641 }
02642
02643 $this->_append($header.$data.$str);
02644 }
02645
02651 function _storeHcenter()
02652 {
02653 $record = 0x0083;
02654 $length = 0x0002;
02655
02656 $fHCenter = $this->_hcenter;
02657
02658 $header = pack("vv", $record, $length);
02659 $data = pack("v", $fHCenter);
02660
02661 $this->_append($header.$data);
02662 }
02663
02669 function _storeVcenter()
02670 {
02671 $record = 0x0084;
02672 $length = 0x0002;
02673
02674 $fVCenter = $this->_vcenter;
02675
02676 $header = pack("vv", $record, $length);
02677 $data = pack("v", $fVCenter);
02678 $this->_append($header.$data);
02679 }
02680
02686 function _storeMarginLeft()
02687 {
02688 $record = 0x0026;
02689 $length = 0x0008;
02690
02691 $margin = $this->_margin_left;
02692
02693 $header = pack("vv", $record, $length);
02694 $data = pack("d", $margin);
02695 if ($this->_byte_order)
02696 {
02697 $data = strrev($data);
02698 }
02699
02700 $this->_append($header.$data);
02701 }
02702
02708 function _storeMarginRight()
02709 {
02710 $record = 0x0027;
02711 $length = 0x0008;
02712
02713 $margin = $this->_margin_right;
02714
02715 $header = pack("vv", $record, $length);
02716 $data = pack("d", $margin);
02717 if ($this->_byte_order)
02718 {
02719 $data = strrev($data);
02720 }
02721
02722 $this->_append($header.$data);
02723 }
02724
02730 function _storeMarginTop()
02731 {
02732 $record = 0x0028;
02733 $length = 0x0008;
02734
02735 $margin = $this->_margin_top;
02736
02737 $header = pack("vv", $record, $length);
02738 $data = pack("d", $margin);
02739 if ($this->_byte_order)
02740 {
02741 $data = strrev($data);
02742 }
02743
02744 $this->_append($header.$data);
02745 }
02746
02752 function _storeMarginBottom()
02753 {
02754 $record = 0x0029;
02755 $length = 0x0008;
02756
02757 $margin = $this->_margin_bottom;
02758
02759 $header = pack("vv", $record, $length);
02760 $data = pack("d", $margin);
02761 if ($this->_byte_order)
02762 {
02763 $data = strrev($data);
02764 }
02765
02766 $this->_append($header.$data);
02767 }
02768
02780 function mergeCells($first_row, $first_col, $last_row, $last_col)
02781 {
02782 $record = 0x00E5;
02783 $length = 0x000A;
02784 $cref = 1;
02785
02786
02787 if ($first_row > $last_row) {
02788 list($first_row, $last_row) = array($last_row, $first_row);
02789 }
02790
02791 if ($first_col > $last_col) {
02792 list($first_col, $last_col) = array($last_col, $first_col);
02793 }
02794
02795 $header = pack("vv", $record, $length);
02796 $data = pack("vvvvv", $cref, $first_row, $last_row,
02797 $first_col, $last_col);
02798
02799 $this->_append($header.$data);
02800 }
02801
02807 function _storePrintHeaders()
02808 {
02809 $record = 0x002a;
02810 $length = 0x0002;
02811
02812 $fPrintRwCol = $this->_print_headers;
02813
02814 $header = pack("vv", $record, $length);
02815 $data = pack("v", $fPrintRwCol);
02816 $this->_prepend($header.$data);
02817 }
02818
02825 function _storePrintGridlines()
02826 {
02827 $record = 0x002b;
02828 $length = 0x0002;
02829
02830 $fPrintGrid = $this->_print_gridlines;
02831
02832 $header = pack("vv", $record, $length);
02833 $data = pack("v", $fPrintGrid);
02834 $this->_prepend($header.$data);
02835 }
02836
02843 function _storeGridset()
02844 {
02845 $record = 0x0082;
02846 $length = 0x0002;
02847
02848 $fGridSet = !($this->_print_gridlines);
02849
02850 $header = pack("vv", $record, $length);
02851 $data = pack("v", $fGridSet);
02852 $this->_prepend($header.$data);
02853 }
02854
02863 function _storeGuts()
02864 {
02865 $record = 0x0080;
02866 $length = 0x0008;
02867
02868 $dxRwGut = 0x0000;
02869 $dxColGut = 0x0000;
02870
02871 $row_level = $this->_outline_row_level;
02872 $col_level = 0;
02873
02874
02875
02876 for ($i=0; $i < count($this->_colinfo); $i++)
02877 {
02878
02879 if (count($col_level) >= 6) {
02880 $col_level = max($this->_colinfo[$i][5], $col_level);
02881 }
02882 }
02883
02884
02885 $col_level = max(0, min($col_level, 7));
02886
02887
02888 if ($row_level) {
02889 $row_level++;
02890 }
02891 if ($col_level) {
02892 $col_level++;
02893 }
02894
02895 $header = pack("vv", $record, $length);
02896 $data = pack("vvvv", $dxRwGut, $dxColGut, $row_level, $col_level);
02897
02898 $this->_prepend($header.$data);
02899 }
02900
02901
02908 function _storeWsbool()
02909 {
02910 $record = 0x0081;
02911 $length = 0x0002;
02912 $grbit = 0x0000;
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924 $grbit |= 0x0001;
02925 if ($this->_outline_style) {
02926 $grbit |= 0x0020;
02927 }
02928 if ($this->_outline_below) {
02929 $grbit |= 0x0040;
02930 }
02931 if ($this->_outline_right) {
02932 $grbit |= 0x0080;
02933 }
02934 if ($this->_fit_page) {
02935 $grbit |= 0x0100;
02936 }
02937 if ($this->_outline_on) {
02938 $grbit |= 0x0400;
02939 }
02940
02941 $header = pack("vv", $record, $length);
02942 $data = pack("v", $grbit);
02943 $this->_prepend($header.$data);
02944 }
02945
02951 function _storeHbreak()
02952 {
02953
02954 if (empty($this->_hbreaks)) {
02955 return;
02956 }
02957
02958
02959 $breaks = $this->_hbreaks;
02960 sort($breaks, SORT_NUMERIC);
02961 if ($breaks[0] == 0) {
02962 array_shift($breaks);
02963 }
02964
02965 $record = 0x001b;
02966 $cbrk = count($breaks);
02967 $length = 2 + 6*$cbrk;
02968
02969 $header = pack("vv", $record, $length);
02970 $data = pack("v", $cbrk);
02971
02972
02973 foreach($breaks as $break) {
02974 $data .= pack("vvv", $break, 0x0000, 0x00ff);
02975 }
02976
02977 $this->_prepend($header.$data);
02978 }
02979
02980
02986 function _storeVbreak()
02987 {
02988
02989 if (empty($this->_vbreaks)) {
02990 return;
02991 }
02992
02993
02994
02995 $breaks = array_slice($this->_vbreaks,0,1000);
02996
02997
02998 sort($breaks, SORT_NUMERIC);
02999 if ($breaks[0] == 0) {
03000 array_shift($breaks);
03001 }
03002
03003 $record = 0x001a;
03004 $cbrk = count($breaks);
03005 $length = 2 + 6*$cbrk;
03006
03007 $header = pack("vv", $record, $length);
03008 $data = pack("v", $cbrk);
03009
03010
03011 foreach ($breaks as $break) {
03012 $data .= pack("vvv", $break, 0x0000, 0xffff);
03013 }
03014
03015 $this->_prepend($header.$data);
03016 }
03017
03023 function _storeProtect()
03024 {
03025
03026 if ($this->_protect == 0) {
03027 return;
03028 }
03029
03030 $record = 0x0012;
03031 $length = 0x0002;
03032
03033 $fLock = $this->_protect;
03034
03035 $header = pack("vv", $record, $length);
03036 $data = pack("v", $fLock);
03037
03038 $this->_prepend($header.$data);
03039 }
03040
03046 function _storePassword()
03047 {
03048
03049 if (($this->_protect == 0) or (!isset($this->_password))) {
03050 return;
03051 }
03052
03053 $record = 0x0013;
03054 $length = 0x0002;
03055
03056 $wPassword = $this->_password;
03057
03058 $header = pack("vv", $record, $length);
03059 $data = pack("v", $wPassword);
03060
03061 $this->_prepend($header.$data);
03062 }
03063
03064
03077 function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1)
03078 {
03079 $bitmap_array = $this->_processBitmap($bitmap);
03080 if ($this->isError($bitmap_array))
03081 {
03082 $this->writeString($row, $col, $bitmap_array->getMessage());
03083 return;
03084 }
03085 list($width, $height, $size, $data) = $bitmap_array;
03086
03087
03088 $width *= $scale_x;
03089 $height *= $scale_y;
03090
03091
03092 $this->_positionImage($col, $row, $x, $y, $width, $height);
03093
03094
03095 $record = 0x007f;
03096 $length = 8 + $size;
03097 $cf = 0x09;
03098 $env = 0x01;
03099 $lcb = $size;
03100
03101 $header = pack("vvvvV", $record, $length, $cf, $env, $lcb);
03102 $this->_append($header.$data);
03103 }
03104
03156 function _positionImage($col_start, $row_start, $x1, $y1, $width, $height)
03157 {
03158
03159 $col_end = $col_start;
03160 $row_end = $row_start;
03161
03162
03163 if ($x1 >= $this->_sizeCol($col_start))
03164 {
03165 $x1 = 0;
03166 }
03167 if ($y1 >= $this->_sizeRow($row_start))
03168 {
03169 $y1 = 0;
03170 }
03171
03172 $width = $width + $x1 -1;
03173 $height = $height + $y1 -1;
03174
03175
03176 while ($width >= $this->_sizeCol($col_end)) {
03177 $width -= $this->_sizeCol($col_end);
03178 $col_end++;
03179 }
03180
03181
03182 while ($height >= $this->_sizeRow($row_end)) {
03183 $height -= $this->_sizeRow($row_end);
03184 $row_end++;
03185 }
03186
03187
03188
03189
03190 if ($this->_sizeCol($col_start) == 0)
03191 return;
03192 if ($this->_sizeCol($col_end) == 0)
03193 return;
03194 if ($this->_sizeRow($row_start) == 0)
03195 return;
03196 if ($this->_sizeRow($row_end) == 0)
03197 return;
03198
03199
03200 $x1 = $x1 / $this->_sizeCol($col_start) * 1024;
03201 $y1 = $y1 / $this->_sizeRow($row_start) * 256;
03202 $x2 = $width / $this->_sizeCol($col_end) * 1024;
03203 $y2 = $height / $this->_sizeRow($row_end) * 256;
03204
03205 $this->_storeObjPicture( $col_start, $x1,
03206 $row_start, $y1,
03207 $col_end, $x2,
03208 $row_end, $y2
03209 );
03210 }
03211
03221 function _sizeCol($col)
03222 {
03223
03224 if (isset($this->col_sizes[$col])) {
03225 if ($this->col_sizes[$col] == 0) {
03226 return(0);
03227 }
03228 else {
03229 return(floor(7 * $this->col_sizes[$col] + 5));
03230 }
03231 }
03232 else {
03233 return(64);
03234 }
03235 }
03236
03247 function _sizeRow($row)
03248 {
03249
03250 if (isset($this->row_sizes[$row])) {
03251 if ($this->row_sizes[$row] == 0) {
03252 return(0);
03253 }
03254 else {
03255 return(floor(4/3 * $this->row_sizes[$row]));
03256 }
03257 }
03258 else {
03259 return(17);
03260 }
03261 }
03262
03277 function _storeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB)
03278 {
03279 $record = 0x005d;
03280 $length = 0x003c;
03281
03282 $cObj = 0x0001;
03283 $OT = 0x0008;
03284 $id = 0x0001;
03285 $grbit = 0x0614;
03286
03287 $cbMacro = 0x0000;
03288 $Reserved1 = 0x0000;
03289 $Reserved2 = 0x0000;
03290
03291 $icvBack = 0x09;
03292 $icvFore = 0x09;
03293 $fls = 0x00;
03294 $fAuto = 0x00;
03295 $icv = 0x08;
03296 $lns = 0xff;
03297 $lnw = 0x01;
03298 $fAutoB = 0x00;
03299 $frs = 0x0000;
03300 $cf = 0x0009;
03301 $Reserved3 = 0x0000;
03302 $cbPictFmla = 0x0000;
03303 $Reserved4 = 0x0000;
03304 $grbit2 = 0x0001;
03305 $Reserved5 = 0x0000;
03306
03307
03308 $header = pack("vv", $record, $length);
03309 $data = pack("V", $cObj);
03310 $data .= pack("v", $OT);
03311 $data .= pack("v", $id);
03312 $data .= pack("v", $grbit);
03313 $data .= pack("v", $colL);
03314 $data .= pack("v", $dxL);
03315 $data .= pack("v", $rwT);
03316 $data .= pack("v", $dyT);
03317 $data .= pack("v", $colR);
03318 $data .= pack("v", $dxR);
03319 $data .= pack("v", $rwB);
03320 $data .= pack("v", $dyB);
03321 $data .= pack("v", $cbMacro);
03322 $data .= pack("V", $Reserved1);
03323 $data .= pack("v", $Reserved2);
03324 $data .= pack("C", $icvBack);
03325 $data .= pack("C", $icvFore);
03326 $data .= pack("C", $fls);
03327 $data .= pack("C", $fAuto);
03328 $data .= pack("C", $icv);
03329 $data .= pack("C", $lns);
03330 $data .= pack("C", $lnw);
03331 $data .= pack("C", $fAutoB);
03332 $data .= pack("v", $frs);
03333 $data .= pack("V", $cf);
03334 $data .= pack("v", $Reserved3);
03335 $data .= pack("v", $cbPictFmla);
03336 $data .= pack("v", $Reserved4);
03337 $data .= pack("v", $grbit2);
03338 $data .= pack("V", $Reserved5);
03339
03340 $this->_append($header.$data);
03341 }
03342
03352 function _processBitmap($bitmap)
03353 {
03354
03355 $bmp_fd = @fopen($bitmap,"rb");
03356 if (!$bmp_fd) {
03357 $this->raiseError("Couldn't import $bitmap");
03358 }
03359
03360
03361 $data = fread($bmp_fd, filesize($bitmap));
03362
03363
03364 if (strlen($data) <= 0x36) {
03365 $this->raiseError("$bitmap doesn't contain enough data.\n");
03366 }
03367
03368
03369 $identity = unpack("A2", $data);
03370 if ($identity[''] != "BM") {
03371 $this->raiseError("$bitmap doesn't appear to be a valid bitmap image.\n");
03372 }
03373
03374
03375 $data = substr($data, 2);
03376
03377
03378
03379
03380 $size_array = unpack("V", substr($data, 0, 4));
03381 $size = $size_array[''];
03382 $data = substr($data, 4);
03383 $size -= 0x36;
03384 $size += 0x0C;
03385
03386
03387 $data = substr($data, 12);
03388
03389
03390 $width_and_height = unpack("V2", substr($data, 0, 8));
03391 $width = $width_and_height[1];
03392 $height = $width_and_height[2];
03393 $data = substr($data, 8);
03394 if ($width > 0xFFFF) {
03395 $this->raiseError("$bitmap: largest image width supported is 65k.\n");
03396 }
03397 if ($height > 0xFFFF) {
03398 $this->raiseError("$bitmap: largest image height supported is 65k.\n");
03399 }
03400
03401
03402 $planes_and_bitcount = unpack("v2", substr($data, 0, 4));
03403 $data = substr($data, 4);
03404 if ($planes_and_bitcount[2] != 24) {
03405 $this->raiseError("$bitmap isn't a 24bit true color bitmap.\n");
03406 }
03407 if ($planes_and_bitcount[1] != 1) {
03408 $this->raiseError("$bitmap: only 1 plane nupported in bitmap image.\n");
03409 }
03410
03411
03412 $compression = unpack("V", substr($data, 0, 4));
03413 $data = substr($data, 4);
03414
03415
03416 if ($compression[""] != 0) {
03417 $this->raiseError("$bitmap: compression not supported in bitmap image.\n");
03418 }
03419
03420
03421 $data = substr($data, 20);
03422
03423
03424 $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18);
03425 $data = $header . $data;
03426
03427 return (array($width, $height, $size, $data));
03428 }
03429
03436 function _storeZoom()
03437 {
03438
03439 if ($this->_zoom == 100) {
03440 return;
03441 }
03442
03443 $record = 0x00A0;
03444 $length = 0x0004;
03445
03446 $header = pack("vv", $record, $length);
03447 $data = pack("vv", $this->_zoom, 100);
03448 $this->_append($header.$data);
03449 }
03450
03454 function setValidation($row1, $col1, $row2, $col2, &$validator)
03455 {
03456 $this->_dv[] = $validator->_getData() .
03457 pack("vvvvv", 1, $row1, $row2, $col1, $col2);
03458 }
03459
03465 function _storeDataValidity()
03466 {
03467 $record = 0x01b2;
03468 $length = 0x0012;
03469
03470 $grbit = 0x0002;
03471 $horPos = 0x00000000;
03472 $verPos = 0x00000000;
03473 $objId = 0xffffffff;
03474
03475 $header = pack('vv', $record, $length);
03476 $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId,
03477 count($this->_dv));
03478 $this->_append($header.$data);
03479
03480 $record = 0x01be;
03481 foreach($this->_dv as $dv)
03482 {
03483 $length = strlen($dv);
03484 $header = pack("vv", $record, $length);
03485 $this->_append($header.$dv);
03486 }
03487 }
03488 }
03489 ?>