35 require_once
'Spreadsheet/Excel/Writer/Format.php';
36 require_once
'Spreadsheet/Excel/Writer/BIFFwriter.php';
37 require_once
'Spreadsheet/Excel/Writer/Worksheet.php';
38 require_once
'Spreadsheet/Excel/Writer/Parser.php';
39 require_once
'OLE/PPS/Root.php';
40 require_once
'OLE/PPS/File.php';
182 $this->_activesheet = 0;
183 $this->_firstsheet = 0;
184 $this->_selected = 0;
185 $this->_xf_index = 16;
186 $this->_fileclosed = 0;
187 $this->_biffsize = 0;
188 $this->_sheetname =
'Sheet';
190 $this->_worksheets = array();
191 $this->_sheetnames = array();
192 $this->_formats = array();
193 $this->_palette = array();
194 $this->_codepage = 0x04E4;
195 $this->_country_code = -1;
196 $this->_string_sizeinfo = 3;
199 $this->_url_format =& $this->
addFormat(array(
'color' =>
'blue',
'underline' => 1));
200 $this->_str_total = 0;
201 $this->_str_unique = 0;
202 $this->_str_table = array();
215 if ($this->_fileclosed) {
222 $this->_fileclosed = 1;
266 $this->_BIFF_version = $version;
268 $this->_limit = 8228;
269 $this->_tmp_format->_BIFF_version = $version;
270 $this->_url_format->_BIFF_version = $version;
271 $this->_parser->_BIFF_version = $version;
272 $this->_codepage = 0x04B0;
274 $total_worksheets = count($this->_worksheets);
276 for ($i = 0; $i < $total_worksheets; $i++) {
277 $this->_worksheets[$i]->_BIFF_version = $version;
280 $total_formats = count($this->_formats);
282 for ($i = 0; $i < $total_formats; $i++) {
283 $this->_formats[$i]->_BIFF_version = $version;
297 $this->_country_code = $code;
312 $index = count($this->_worksheets);
316 $name = $sheetname.($index+1);
320 if ($this->_BIFF_version != 0x0600)
322 if (strlen($name) > 31) {
323 return $this->
raiseError(
"Sheetname $name must be <= 31 chars");
328 $total_worksheets = count($this->_worksheets);
329 for ($i = 0; $i < $total_worksheets; $i++) {
330 if ($this->_worksheets[$i]->getName() == $name) {
331 return $this->
raiseError(
"Worksheet '$name' already exists");
337 $this->_activesheet, $this->_firstsheet,
338 $this->_str_total, $this->_str_unique,
339 $this->_str_table, $this->_url_format,
340 $this->_parser, $this->_tmp_dir);
342 $this->_worksheets[$index] = &$worksheet;
343 $this->_sheetnames[$index] = $name;
344 $this->_parser->setExtSheet($name, $index);
359 $this->_xf_index += 1;
360 $this->_formats[] = &$format;
372 include_once
'Spreadsheet/Excel/Writer/Validator.php';
396 if ($index < 8 or $index > 64) {
398 return $this->
raiseError(
"Color index $index outside range: 8 <= index <= 64");
402 if (($red < 0 or $red > 255) ||
403 ($green < 0 or $green > 255) ||
404 ($blue < 0 or $blue > 255))
406 return $this->
raiseError(
"Color component outside range: 0 <= color <= 255");
412 $this->_palette[$index] = array($red, $green, $blue, 0);
423 $this->_palette = array(
424 array(0x00, 0x00, 0x00, 0x00),
425 array(0xff, 0xff, 0xff, 0x00),
426 array(0xff, 0x00, 0x00, 0x00),
427 array(0x00, 0xff, 0x00, 0x00),
428 array(0x00, 0x00, 0xff, 0x00),
429 array(0xff, 0xff, 0x00, 0x00),
430 array(0xff, 0x00, 0xff, 0x00),
431 array(0x00, 0xff, 0xff, 0x00),
432 array(0x80, 0x00, 0x00, 0x00),
433 array(0x00, 0x80, 0x00, 0x00),
434 array(0x00, 0x00, 0x80, 0x00),
435 array(0x80, 0x80, 0x00, 0x00),
436 array(0x80, 0x00, 0x80, 0x00),
437 array(0x00, 0x80, 0x80, 0x00),
438 array(0xc0, 0xc0, 0xc0, 0x00),
439 array(0x80, 0x80, 0x80, 0x00),
440 array(0x99, 0x99, 0xff, 0x00),
441 array(0x99, 0x33, 0x66, 0x00),
442 array(0xff, 0xff, 0xcc, 0x00),
443 array(0xcc, 0xff, 0xff, 0x00),
444 array(0x66, 0x00, 0x66, 0x00),
445 array(0xff, 0x80, 0x80, 0x00),
446 array(0x00, 0x66, 0xcc, 0x00),
447 array(0xcc, 0xcc, 0xff, 0x00),
448 array(0x00, 0x00, 0x80, 0x00),
449 array(0xff, 0x00, 0xff, 0x00),
450 array(0xff, 0xff, 0x00, 0x00),
451 array(0x00, 0xff, 0xff, 0x00),
452 array(0x80, 0x00, 0x80, 0x00),
453 array(0x80, 0x00, 0x00, 0x00),
454 array(0x00, 0x80, 0x80, 0x00),
455 array(0x00, 0x00, 0xff, 0x00),
456 array(0x00, 0xcc, 0xff, 0x00),
457 array(0xcc, 0xff, 0xff, 0x00),
458 array(0xcc, 0xff, 0xcc, 0x00),
459 array(0xff, 0xff, 0x99, 0x00),
460 array(0x99, 0xcc, 0xff, 0x00),
461 array(0xff, 0x99, 0xcc, 0x00),
462 array(0xcc, 0x99, 0xff, 0x00),
463 array(0xff, 0xcc, 0x99, 0x00),
464 array(0x33, 0x66, 0xff, 0x00),
465 array(0x33, 0xcc, 0xcc, 0x00),
466 array(0x99, 0xcc, 0x00, 0x00),
467 array(0xff, 0xcc, 0x00, 0x00),
468 array(0xff, 0x99, 0x00, 0x00),
469 array(0xff, 0x66, 0x00, 0x00),
470 array(0x66, 0x66, 0x99, 0x00),
471 array(0x96, 0x96, 0x96, 0x00),
472 array(0x00, 0x33, 0x66, 0x00),
473 array(0x33, 0x99, 0x66, 0x00),
474 array(0x00, 0x33, 0x00, 0x00),
475 array(0x33, 0x33, 0x00, 0x00),
476 array(0x99, 0x33, 0x00, 0x00),
477 array(0x99, 0x33, 0x66, 0x00),
478 array(0x33, 0x33, 0x99, 0x00),
479 array(0x33, 0x33, 0x33, 0x00),
492 if (count($this->_worksheets) == 0) {
497 if ($this->_activesheet == 0) {
498 $this->_worksheets[0]->selected = 1;
503 $total_worksheets = count($this->_worksheets);
504 for ($i = 0; $i < $total_worksheets; $i++) {
505 if ($this->_worksheets[$i]->selected) {
508 $this->_worksheets[$i]->close($this->_sheetnames);
514 if ($this->_BIFF_version == 0x0600) {
517 if ($this->_BIFF_version == 0x0500) {
521 if ($this->_BIFF_version == 0x0500) {
533 for ($i = 0; $i < $total_worksheets; $i++) {
534 $this->
_storeBoundsheet($this->_worksheets[$i]->name,$this->_worksheets[$i]->offset);
537 if ($this->_country_code != -1) {
541 if ($this->_BIFF_version == 0x0600) {
568 if($this->_BIFF_version == 0x0600) {
573 if ($this->_tmp_dir !=
'') {
574 $OLE->setTempDir($this->_tmp_dir);
580 $OLE->append($this->_data);
582 $total_worksheets = count($this->_worksheets);
583 for ($i = 0; $i < $total_worksheets; $i++) {
584 while ($tmp = $this->_worksheets[$i]->getData()) {
590 if ($this->_tmp_dir !=
'') {
591 $root->setTempDir($this->_tmp_dir);
594 $res = $root->save($this->_filename);
608 if ($this->_BIFF_version == 0x0600) {
609 $boundsheet_length = 12;
611 $boundsheet_length = 11;
616 if ($this->_BIFF_version == 0x0600) {
620 if ($this->_country_code != -1) {
626 $total_worksheets = count($this->_worksheets);
628 for ($i = 0; $i < $total_worksheets; $i++) {
629 $offset += $boundsheet_length + strlen($this->_worksheets[$i]->name);
633 for ($i = 0; $i < $total_worksheets; $i++) {
634 $this->_worksheets[$i]->offset = $offset;
635 $offset += $this->_worksheets[$i]->_datasize;
637 $this->_biffsize = $offset;
649 $font = $format->getFont();
654 for ($i = 1; $i <= 5; $i++){
664 $key = $format->getFontKey();
667 $total_formats = count($this->_formats);
668 for ($i = 0; $i < $total_formats; $i++) {
669 $key = $this->_formats[$i]->getFontKey();
670 if (isset($fonts[$key])) {
672 $this->_formats[$i]->font_index = $fonts[$key];
675 $fonts[$key] = $index;
676 $this->_formats[$i]->font_index = $index;
678 $font = $this->_formats[$i]->getFont();
692 $hash_num_formats = array();
693 $num_formats = array();
698 $total_formats = count($this->_formats);
699 for ($i = 0; $i < $total_formats; $i++) {
700 $num_format = $this->_formats[$i]->_num_format;
706 if (!preg_match(
"/^0+\d/", $num_format)) {
707 if (preg_match(
"/^\d+$/", $num_format)) {
712 if (isset($hash_num_formats[$num_format])) {
714 $this->_formats[$i]->_num_format = $hash_num_formats[$num_format];
717 $hash_num_formats[$num_format] = $index;
718 $this->_formats[$i]->_num_format = $index;
719 array_push($num_formats,$num_format);
726 foreach ($num_formats as $num_format) {
743 for ($i = 0; $i <= 14; $i++) {
744 $xf = $format->getXf(
'style');
748 $xf = $format->getXf(
'cell');
752 $total_formats = count($this->_formats);
753 for ($i = 0; $i < $total_formats; $i++) {
754 $xf = $this->_formats[$i]->getXf(
'cell');
781 foreach ($this->_sheetnames as $sheetname) {
794 $total_worksheets = count($this->_worksheets);
795 for ($i = 0; $i < $total_worksheets; $i++) {
797 if (isset($this->_worksheets[$i]->print_rowmin)) {
799 $this->_worksheets[$i]->index,
801 $this->_worksheets[$i]->print_rowmin,
802 $this->_worksheets[$i]->print_rowmax,
803 $this->_worksheets[$i]->print_colmin,
804 $this->_worksheets[$i]->print_colmax
810 $total_worksheets = count($this->_worksheets);
811 for ($i = 0; $i < $total_worksheets; $i++) {
812 $rowmin = $this->_worksheets[$i]->title_rowmin;
813 $rowmax = $this->_worksheets[$i]->title_rowmax;
814 $colmin = $this->_worksheets[$i]->title_colmin;
815 $colmax = $this->_worksheets[$i]->title_colmax;
820 if (isset($rowmin) && isset($colmin)) {
824 $this->_worksheets[$i]->index,
831 } elseif (isset($rowmin)) {
834 $this->_worksheets[$i]->index,
841 } elseif (isset($colmin)) {
844 $this->_worksheets[$i]->index,
877 $header = pack(
'vv', $record, $length);
878 $data = pack(
'v', $cv);
905 $header = pack(
"vv", $record, $length);
906 $data = pack(
"vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn,
908 $itabCur, $itabFirst,
909 $ctabsel, $wTabRatio);
924 if ($this->_BIFF_version == 0x0600) {
925 $length = 0x08 + strlen($sheetname);
927 $length = 0x07 + strlen($sheetname);
931 $cch = strlen($sheetname);
933 $header = pack(
"vv", $record, $length);
934 if ($this->_BIFF_version == 0x0600) {
935 $data = pack(
"Vvv", $offset, $grbit, $cch);
937 $data = pack(
"VvC", $offset, $grbit, $cch);
939 $this->
_append($header.$data.$sheetname);
952 $header = pack(
"vv", $record, $length);
953 $data = pack(
"vv", count($this->_worksheets), 0x0104);
966 $total_references = count($this->_parser->_references);
968 $length = 2 + 6 * $total_references;
971 $header = pack(
"vv", $record, $length);
972 $data = pack(
'v', $total_references);
973 for ($i = 0; $i < $total_references; $i++) {
974 $data .= $this->_parser->_references[$i];
993 $header = pack(
"vv", $record, $length);
994 $data = pack(
"vCC", $ixfe, $BuiltIn, $iLevel);
1010 if ($this->_BIFF_version == 0x0600) {
1011 $length = 5 + strlen($format);
1013 } elseif ($this->_BIFF_version == 0x0500) {
1014 $length = 3 + strlen($format);
1017 $cch = strlen($format);
1019 $header = pack(
"vv", $record, $length);
1020 if ($this->_BIFF_version == 0x0600) {
1021 $data = pack(
"vvC", $ifmt, $cch, $encoding);
1022 } elseif ($this->_BIFF_version == 0x0500) {
1023 $data = pack(
"vC", $ifmt, $cch);
1040 $header = pack(
"vv", $record, $length);
1041 $data = pack(
"v", $f1904);
1064 $header = pack(
"vv", $record, $length);
1065 $data = pack(
"v", $cxals);
1083 $length = 0x02 + strlen($sheetname);
1085 $cch = strlen($sheetname);
1088 $header = pack(
"vv", $record, $length);
1089 $data = pack(
"CC", $cch, $rgch);
1115 $ixals = $index + 1;
1117 $cchCustMenu = 0x00;
1118 $cchDescription = 0x00;
1119 $cchHelptopic = 0x00;
1120 $cchStatustext = 0x00;
1124 $unknown04 = 0xffff-$index;
1125 $unknown05 = 0x0000;
1126 $unknown06 = 0x0000;
1127 $unknown07 = 0x1087;
1128 $unknown08 = 0x8005;
1130 $header = pack(
"vv", $record, $length);
1131 $data = pack(
"v", $grbit);
1132 $data .= pack(
"C", $chKey);
1133 $data .= pack(
"C", $cch);
1134 $data .= pack(
"v", $cce);
1135 $data .= pack(
"v", $ixals);
1136 $data .= pack(
"v", $itab);
1137 $data .= pack(
"C", $cchCustMenu);
1138 $data .= pack(
"C", $cchDescription);
1139 $data .= pack(
"C", $cchHelptopic);
1140 $data .= pack(
"C", $cchStatustext);
1141 $data .= pack(
"C", $rgch);
1142 $data .= pack(
"C", $unknown03);
1143 $data .= pack(
"v", $unknown04);
1144 $data .= pack(
"v", $unknown05);
1145 $data .= pack(
"v", $unknown06);
1146 $data .= pack(
"v", $unknown07);
1147 $data .= pack(
"v", $unknown08);
1148 $data .= pack(
"v", $index);
1149 $data .= pack(
"v", $index);
1150 $data .= pack(
"v", $rowmin);
1151 $data .= pack(
"v", $rowmax);
1152 $data .= pack(
"C", $colmin);
1153 $data .= pack(
"C", $colmax);
1180 $ixals = $index + 1;
1182 $cchCustMenu = 0x00;
1183 $cchDescription = 0x00;
1184 $cchHelptopic = 0x00;
1185 $cchStatustext = 0x00;
1189 $unknown02 = 0x002b;
1191 $unknown04 = 0xffff-$index;
1192 $unknown05 = 0x0000;
1193 $unknown06 = 0x0000;
1194 $unknown07 = 0x1087;
1195 $unknown08 = 0x8008;
1197 $header = pack(
"vv", $record, $length);
1198 $data = pack(
"v", $grbit);
1199 $data .= pack(
"C", $chKey);
1200 $data .= pack(
"C", $cch);
1201 $data .= pack(
"v", $cce);
1202 $data .= pack(
"v", $ixals);
1203 $data .= pack(
"v", $itab);
1204 $data .= pack(
"C", $cchCustMenu);
1205 $data .= pack(
"C", $cchDescription);
1206 $data .= pack(
"C", $cchHelptopic);
1207 $data .= pack(
"C", $cchStatustext);
1208 $data .= pack(
"C", $rgch);
1209 $data .= pack(
"C", $unknown01);
1210 $data .= pack(
"v", $unknown02);
1212 $data .= pack(
"C", $unknown03);
1213 $data .= pack(
"v", $unknown04);
1214 $data .= pack(
"v", $unknown05);
1215 $data .= pack(
"v", $unknown06);
1216 $data .= pack(
"v", $unknown07);
1217 $data .= pack(
"v", $unknown08);
1218 $data .= pack(
"v", $index);
1219 $data .= pack(
"v", $index);
1220 $data .= pack(
"v", 0x0000);
1221 $data .= pack(
"v", 0x3fff);
1222 $data .= pack(
"C", $colmin);
1223 $data .= pack(
"C", $colmax);
1225 $data .= pack(
"C", $unknown03);
1226 $data .= pack(
"v", $unknown04);
1227 $data .= pack(
"v", $unknown05);
1228 $data .= pack(
"v", $unknown06);
1229 $data .= pack(
"v", $unknown07);
1230 $data .= pack(
"v", $unknown08);
1231 $data .= pack(
"v", $index);
1232 $data .= pack(
"v", $index);
1233 $data .= pack(
"v", $rowmin);
1234 $data .= pack(
"v", $rowmax);
1235 $data .= pack(
"C", 0x00);
1236 $data .= pack(
"C", 0xff);
1238 $data .= pack(
"C", 0x10);
1252 $header = pack(
'vv', $record, $length);
1254 $data = pack(
'vv', $this->_country_code, $this->_country_code);
1268 $length = 2 + 4 * count($aref);
1269 $ccv = count($aref);
1273 foreach ($aref as $color) {
1274 foreach ($color as $byte) {
1275 $data .= pack(
"C",$byte);
1279 $header = pack(
"vvv", $record, $length, $ccv);
1302 $continue_limit = 8208;
1305 $this->_block_sizes = array();
1308 foreach (array_keys($this->_str_table) as $string) {
1309 $string_length = strlen($string);
1310 $headerinfo = unpack(
"vlength/Cencoding", $string);
1311 $encoding = $headerinfo[
"encoding"];
1316 $block_length += $string_length;
1319 if ($block_length < $continue_limit) {
1320 $written += $string_length;
1327 while ($block_length >= $continue_limit) {
1332 $space_remaining = $continue_limit - $written - $continue;
1342 if ($encoding == 1) {
1346 if ($space_remaining > $header_length) {
1348 if (!$split_string && $space_remaining % 2 != 1) {
1353 else if ($split_string && $space_remaining % 2 == 1) {
1363 if ($space_remaining > $header_length) {
1365 $written += $space_remaining;
1368 $block_length -= $continue_limit - $continue - $align;
1371 $this->_block_sizes[] = $continue_limit - $align;
1376 if ($block_length > 0) {
1383 $this->_block_sizes[] = $written + $continue;
1386 $block_length -= $continue_limit - $space_remaining - $continue;
1394 if ($block_length < $continue_limit) {
1395 $written = $block_length;
1403 if ($written + $continue) {
1404 $this->_block_sizes[] = $written + $continue;
1414 $tmp_block_sizes = array();
1415 $tmp_block_sizes = $this->_block_sizes;
1418 if (!empty($tmp_block_sizes)) {
1419 $length += array_shift($tmp_block_sizes);
1421 while (!empty($tmp_block_sizes)) {
1422 $length += 4 + array_shift($tmp_block_sizes);
1446 $continue_limit = 8208;
1452 $tmp_block_sizes = $this->_block_sizes;
1458 if (!empty($tmp_block_sizes)) {
1459 $length = 8 + array_shift($tmp_block_sizes);
1469 $header = pack(
"vv", $record, $length);
1470 $data = pack(
"VV", $this->_str_total, $this->_str_unique);
1477 foreach (array_keys($this->_str_table) as $string) {
1479 $string_length = strlen($string);
1480 $headerinfo = unpack(
"vlength/Cencoding", $string);
1481 $encoding = $headerinfo[
"encoding"];
1487 $block_length += $string_length;
1491 if ($block_length < $continue_limit) {
1493 $written += $string_length;
1501 while ($block_length >= $continue_limit) {
1507 $space_remaining = $continue_limit - $written - $continue;
1516 if ($encoding == 1) {
1520 if ($space_remaining > $header_length) {
1522 if (!$split_string && $space_remaining % 2 != 1) {
1527 else if ($split_string && $space_remaining % 2 == 1) {
1537 if ($space_remaining > $header_length) {
1539 $tmp = substr($string, 0, $space_remaining);
1543 $string = substr($string, $space_remaining);
1546 $block_length -= $continue_limit - $continue - $align;
1552 if ($block_length > 0) {
1559 $block_length -= $continue_limit - $space_remaining - $continue;
1564 if (!empty($this->_block_sizes)) {
1566 $length = array_shift($tmp_block_sizes);
1568 $header = pack(
'vv', $record, $length);
1570 $header .= pack(
'C', $encoding);
1579 if ($block_length < $continue_limit) {
1581 $written = $block_length;
_storeBoundsheet($sheetname, $offset)
Writes Excel BIFF BOUNDSHEET record.
_storeWindow1()
Write Excel BIFF WINDOW1 record.
_storeCodepage()
Stores the CODEPAGE biff record.
& addWorksheet($name='')
Add a new worksheet to the Excel workbook.
_calculateSharedStringsSizes()
Calculate Handling of the SST continue blocks is complicated by the need to include an additional con...
_storeSharedStringsTable()
Write all of the workbooks strings into an indexed array.
_storeNumFormat($format, $ifmt)
Writes Excel FORMAT record for non "built-in" numerical formats.
_storeOLEFile()
Store the workbook in an OLE container.
setCustomColor($index, $red, $green, $blue)
Change the RGB components of the elements in the colour palette.
sheets()
An accessor for the _worksheets[] array Returns an array of the worksheet objects in a workbook It ac...
_storeAllFonts()
Store the Excel FONT records.
setVersion($version)
Sets the BIFF version.
_storeEof()
Writes Excel EOF record to indicate the end of a BIFF stream.
Spreadsheet_Excel_Writer_Workbook($filename)
Class constructor.
_storeExternsheet($sheetname)
Writes the Excel BIFF EXTERNSHEET record.
_storeWorkbook()
Assemble worksheets into a workbook and send the BIFF data to an OLE storage.
_storeStyle()
Write Excel BIFF STYLE records.
_calcSheetOffsets()
Calculate offsets for Worksheet BOF records.
_storeDatemode()
Write DATEMODE record to indicate the date system in use (1904 or 1900).
_storeAllXfs()
Write all XF records.
& addValidator()
Create new validator.
_storeAllNumFormats()
Store user defined numerical formats i.e.
_storeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax)
Store the NAME record in the long format that is used for storing the repeat rows and columns when bo...
Asc2Ucs($ascii)
Utility function to transform ASCII text to Unicode.
_setPaletteXl97()
Sets the colour palette to the Excel 97+ default.
& addFormat($properties=array())
Add a new format to the Excel workbook.
_storeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax)
Store the NAME record in the short format that is used for storing the print area, repeat rows only and repeat columns only.
_storeNames()
Write the NAME record to define the print area and the repeat rows and cols.
_storeSupbookInternal()
Write Internal SUPBOOK record.
_storeBof($type)
Writes Excel BOF record to indicate the beginning of a stream or sub-stream in the BIFF file...
& raiseError($message=null, $code=null, $mode=null, $options=null, $userinfo=null, $error_class=null, $skipmsg=false)
This method is a wrapper that returns an instance of the configured error class with this object's de...
close()
Calls finalization methods.
_storeExternsheetBiff8()
Writes the Excel BIFF EXTERNSHEET record.
worksheets()
An accessor for the _worksheets[] array.
setCountry($code)
Set the country identifier for the workbook.
_storeExterncount($cxals)
Write BIFF record EXTERNCOUNT to indicate the number of external sheet references in the workbook...
_storePalette()
Stores the PALETTE biff record.
_storeCountry()
Stores the COUNTRY record for localization.
_storeExterns()
Write the EXTERNCOUNT and EXTERNSHEET records.
Spreadsheet_Excel_Writer_BIFFwriter()
Constructor.
_storeAllStyles()
Write all STYLE records.
isError($data, $code=null)
Tell whether a value is a PEAR error.
_append($data)
General storage function.