204                                                                &$str_total, &$str_unique, &$str_table, &$colors,
 
  208                parent::__construct();
 
  211                $this->_biffsize         = 0;
 
  212                $this->_palette          = array();
 
  213                $this->_country_code     = -1;
 
  215                $this->_str_total       = &$str_total;
 
  216                $this->_str_unique      = &$str_unique;
 
  217                $this->_str_table       = &$str_table;
 
  218                $this->_colors          = &$colors;
 
  221                $this->_phpExcel = $phpExcel;
 
  225                $this->_codepage = 0x04B0;
 
  228                $countSheets = $phpExcel->getSheetCount();
 
  229                for (
$i = 0; 
$i < $countSheets; ++
$i) {
 
  230                        $phpSheet = $phpExcel->getSheet(
$i);
 
  232                        $this->_parser->setExtSheet($phpSheet->getTitle(), 
$i);  
 
  234                        $supbook_index = 0x00;
 
  235                        $ref = pack(
'vvv', $supbook_index, 
$i, 
$i);
 
  236                        $this->_parser->_references[] = $ref;  
 
  239                        if ($phpSheet->isTabColorSet()) {
 
  240                                $this->
_addColor($phpSheet->getTabColor()->getRGB());
 
  256                $xfWriter->setIsStyleXf($isStyleXf);
 
  262                $xfWriter->setFontIndex($fontIndex);
 
  265                $xfWriter->setFgColor($this->
_addColor(
$style->getFill()->getStartColor()->getRGB()));
 
  266                $xfWriter->setBgColor($this->
_addColor(
$style->getFill()->getEndColor()->getRGB()));
 
  267                $xfWriter->setBottomColor($this->
_addColor(
$style->getBorders()->getBottom()->getColor()->getRGB()));
 
  268                $xfWriter->setTopColor($this->
_addColor(
$style->getBorders()->getTop()->getColor()->getRGB()));
 
  269                $xfWriter->setRightColor($this->
_addColor(
$style->getBorders()->getRight()->getColor()->getRGB()));
 
  270                $xfWriter->setLeftColor($this->
_addColor(
$style->getBorders()->getLeft()->getColor()->getRGB()));
 
  271                $xfWriter->setDiagColor($this->
_addColor(
$style->getBorders()->getDiagonal()->getColor()->getRGB()));
 
  274                if (
$style->getNumberFormat()->getBuiltInFormatCode() === 
false) {
 
  275                        $numberFormatHashCode = 
$style->getNumberFormat()->getHashCode();
 
  277                        if (isset($this->_addedNumberFormats[$numberFormatHashCode])) {
 
  278                                $numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode];
 
  280                                $numberFormatIndex = 164 + count($this->_numberFormats);
 
  281                                $this->_numberFormats[$numberFormatIndex] = 
$style->getNumberFormat();
 
  282                                $this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex;
 
  285                        $numberFormatIndex = (int) 
$style->getNumberFormat()->getBuiltInFormatCode();
 
  289                $xfWriter->setNumberFormatIndex($numberFormatIndex);
 
  291                $this->_xfWriters[] = $xfWriter;
 
  293                $xfIndex = count($this->_xfWriters) - 1;
 
  306                if(isset($this->_addedFonts[$fontHashCode])){
 
  307                        $fontIndex = $this->_addedFonts[$fontHashCode];
 
  309                        $countFonts = count($this->_fontWriters);
 
  310                        $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1;
 
  314                        $this->_fontWriters[] = $fontWriter;
 
  316                        $this->_addedFonts[$fontHashCode] = $fontIndex;
 
  328                if (!isset($this->_colors[$rgb])) {
 
  329                        if (count($this->_colors) < 57) {
 
  331                                $colorIndex = 8 + count($this->_colors);
 
  332                                $this->_palette[$colorIndex] =
 
  334                                                hexdec(substr($rgb, 0, 2)),
 
  335                                                hexdec(substr($rgb, 2, 2)),
 
  336                                                hexdec(substr($rgb, 4)),
 
  339                                $this->_colors[$rgb] = $colorIndex;
 
  346                        $colorIndex = $this->_colors[$rgb];
 
  359                $this->_palette = array(
 
  360                        0x08 => array(0x00, 0x00, 0x00, 0x00),
 
  361                        0x09 => array(0xff, 0xff, 0xff, 0x00),
 
  362                        0x0A => array(0xff, 0x00, 0x00, 0x00),
 
  363                        0x0B => array(0x00, 0xff, 0x00, 0x00),
 
  364                        0x0C => array(0x00, 0x00, 0xff, 0x00),
 
  365                        0x0D => array(0xff, 0xff, 0x00, 0x00),
 
  366                        0x0E => array(0xff, 0x00, 0xff, 0x00),
 
  367                        0x0F => array(0x00, 0xff, 0xff, 0x00),
 
  368                        0x10 => array(0x80, 0x00, 0x00, 0x00),
 
  369                        0x11 => array(0x00, 0x80, 0x00, 0x00),
 
  370                        0x12 => array(0x00, 0x00, 0x80, 0x00),
 
  371                        0x13 => array(0x80, 0x80, 0x00, 0x00),
 
  372                        0x14 => array(0x80, 0x00, 0x80, 0x00),
 
  373                        0x15 => array(0x00, 0x80, 0x80, 0x00),
 
  374                        0x16 => array(0xc0, 0xc0, 0xc0, 0x00),
 
  375                        0x17 => array(0x80, 0x80, 0x80, 0x00),
 
  376                        0x18 => array(0x99, 0x99, 0xff, 0x00),
 
  377                        0x19 => array(0x99, 0x33, 0x66, 0x00),
 
  378                        0x1A => array(0xff, 0xff, 0xcc, 0x00),
 
  379                        0x1B => array(0xcc, 0xff, 0xff, 0x00),
 
  380                        0x1C => array(0x66, 0x00, 0x66, 0x00),
 
  381                        0x1D => array(0xff, 0x80, 0x80, 0x00),
 
  382                        0x1E => array(0x00, 0x66, 0xcc, 0x00),
 
  383                        0x1F => array(0xcc, 0xcc, 0xff, 0x00),
 
  384                        0x20 => array(0x00, 0x00, 0x80, 0x00),
 
  385                        0x21 => array(0xff, 0x00, 0xff, 0x00),
 
  386                        0x22 => array(0xff, 0xff, 0x00, 0x00),
 
  387                        0x23 => array(0x00, 0xff, 0xff, 0x00),
 
  388                        0x24 => array(0x80, 0x00, 0x80, 0x00),
 
  389                        0x25 => array(0x80, 0x00, 0x00, 0x00),
 
  390                        0x26 => array(0x00, 0x80, 0x80, 0x00),
 
  391                        0x27 => array(0x00, 0x00, 0xff, 0x00),
 
  392                        0x28 => array(0x00, 0xcc, 0xff, 0x00),
 
  393                        0x29 => array(0xcc, 0xff, 0xff, 0x00),
 
  394                        0x2A => array(0xcc, 0xff, 0xcc, 0x00),
 
  395                        0x2B => array(0xff, 0xff, 0x99, 0x00),
 
  396                        0x2C => array(0x99, 0xcc, 0xff, 0x00),
 
  397                        0x2D => array(0xff, 0x99, 0xcc, 0x00),
 
  398                        0x2E => array(0xcc, 0x99, 0xff, 0x00),
 
  399                        0x2F => array(0xff, 0xcc, 0x99, 0x00),
 
  400                        0x30 => array(0x33, 0x66, 0xff, 0x00),
 
  401                        0x31 => array(0x33, 0xcc, 0xcc, 0x00),
 
  402                        0x32 => array(0x99, 0xcc, 0x00, 0x00),
 
  403                        0x33 => array(0xff, 0xcc, 0x00, 0x00),
 
  404                        0x34 => array(0xff, 0x99, 0x00, 0x00),
 
  405                        0x35 => array(0xff, 0x66, 0x00, 0x00),
 
  406                        0x36 => array(0x66, 0x66, 0x99, 0x00),
 
  407                        0x37 => array(0x96, 0x96, 0x96, 0x00),
 
  408                        0x38 => array(0x00, 0x33, 0x66, 0x00),
 
  409                        0x39 => array(0x33, 0x99, 0x66, 0x00),
 
  410                        0x3A => array(0x00, 0x33, 0x00, 0x00),
 
  411                        0x3B => array(0x33, 0x33, 0x00, 0x00),
 
  412                        0x3C => array(0x99, 0x33, 0x00, 0x00),
 
  413                        0x3D => array(0x99, 0x33, 0x66, 0x00),
 
  414                        0x3E => array(0x33, 0x33, 0x99, 0x00),
 
  415                        0x3F => array(0x33, 0x33, 0x33, 0x00),
 
  428                $this->_worksheetSizes = $pWorksheetSizes;
 
  432                $total_worksheets = $this->_phpExcel->getSheetCount();
 
  448                if ($this->_country_code != -1) {
 
  465                for (
$i = 0; 
$i < $total_worksheets; ++
$i) {
 
  470                $this->_data .= $part3;
 
  482                $boundsheet_length = 10;  
 
  488                $total_worksheets = count($this->_phpExcel->getAllSheets());
 
  489                foreach ($this->_phpExcel->getWorksheetIterator() as $sheet) {
 
  494                for (
$i = 0; 
$i < $total_worksheets; ++
$i) {
 
  495                        $this->_worksheetOffsets[
$i] = $offset;
 
  496                        $offset += $this->_worksheetSizes[
$i];
 
  498                $this->_biffsize = $offset;
 
  506                foreach ($this->_fontWriters as $fontWriter) {
 
  507                        $this->
_append($fontWriter->writeFont());
 
  516                foreach ($this->_numberFormats as $numberFormatIndex => $numberFormat) {
 
  517                        $this->
_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex);
 
  526                foreach ($this->_xfWriters as $xfWriter) {
 
  527                        $this->
_append($xfWriter->writeXf());
 
  545                $countSheets = $this->_phpExcel->getSheetCount();
 
  550                for (
$i = 0; 
$i < $countSheets; ++
$i) {
 
  561                $total_worksheets = $this->_phpExcel->getSheetCount();
 
  564                for (
$i = 0; 
$i < $total_worksheets; ++
$i) {
 
  565                        $sheetSetup = $this->_phpExcel->getSheet(
$i)->getPageSetup();
 
  567                        if ($sheetSetup->isPrintAreaSet()) {
 
  570                                $printArea = $printArea[0];
 
  574                                $print_rowmin = $printArea[0][1] - 1;
 
  575                                $print_rowmax = $printArea[1][1] - 1;
 
  591                for (
$i = 0; 
$i < $total_worksheets; ++
$i) {
 
  592                        $sheetSetup = $this->_phpExcel->getSheet(
$i)->getPageSetup();
 
  595                        if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) {
 
  596                                $repeat = $sheetSetup->getColumnsToRepeatAtLeft();
 
  600                                $repeat = $sheetSetup->getRowsToRepeatAtTop();
 
  601                                $rowmin = $repeat[0] - 1;
 
  602                                $rowmax = $repeat[1] - 1;
 
  614                        } 
else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) {
 
  617                                if ($sheetSetup->isColumnsToRepeatAtLeftSet()) {
 
  618                                        $repeat = $sheetSetup->getColumnsToRepeatAtLeft();
 
  627                                if ($sheetSetup->isRowsToRepeatAtTopSet()) {
 
  628                                        $repeat = $sheetSetup->getRowsToRepeatAtTop();
 
  629                                        $rowmin = $repeat[0] - 1;
 
  630                                        $rowmax = $repeat[1] - 1;
 
  657                if (count($this->_phpExcel->getNamedRanges()) > 0) {
 
  659                        $namedRanges = $this->_phpExcel->getNamedRanges();
 
  660                        foreach ($namedRanges as $namedRange) {
 
  664                                for (
$i = 0; 
$i < count($range); 
$i++) {
 
  665                                        $range[
$i][0] = 
'\'' . str_replace(
"'", 
"''", $namedRange->getWorksheet()->getTitle()) . 
'\'!
' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]); 
  666                                        if (isset($range[$i][1])) { 
  667                                                $range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]); 
  670                                $range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2 
  674                                        $error = $this->_parser->parse($range); 
  675                                        $formulaData = $this->_parser->toReversePolish(); 
  677                                        // make sure tRef3d is of type tRef3dR (0x3A) 
  678                                        if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { 
  679                                                $formulaData = "\x3A" . substr($formulaData, 1); 
  682                                        if ($namedRange->getLocalOnly()) { 
  684                                                $scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1; 
  689                                        $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); 
  691                                } catch(PHPExcel_Exception $e) { 
  697                // total number of sheets 
  698                $total_worksheets = $this->_phpExcel->getSheetCount(); 
  700                // write the print titles (repeating rows, columns), if any 
  701                for ($i = 0; $i < $total_worksheets; ++$i) { 
  702                        $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); 
  703                        // simultaneous repeatColumns repeatRows 
  704                        if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { 
  705                                $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); 
  706                                $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; 
  707                                $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; 
  709                                $repeat = $sheetSetup->getRowsToRepeatAtTop(); 
  710                                $rowmin = $repeat[0] - 1; 
  711                                $rowmax = $repeat[1] - 1; 
  713                                // construct formula data manually 
  714                                $formulaData = pack('Cv
', 0x29, 0x17); // tMemFunc 
  715                                $formulaData .= pack('Cvvvvv
', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d 
  716                                $formulaData .= pack('Cvvvvv
', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d 
  717                                $formulaData .= pack('C', 0x10); // tList 
  719                                // store the DEFINEDNAME record 
  720                                $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); 
  722                        // (exclusive) either repeatColumns or repeatRows 
  723                        } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { 
  726                                if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { 
  727                                        $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); 
  728                                        $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; 
  729                                        $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; 
  735                                if ($sheetSetup->isRowsToRepeatAtTopSet()) { 
  736                                        $repeat = $sheetSetup->getRowsToRepeatAtTop(); 
  737                                        $rowmin = $repeat[0] - 1; 
  738                                        $rowmax = $repeat[1] - 1; 
  744                                // construct formula data manually because parser does not recognize absolute 3d cell references 
  745                                $formulaData = pack('Cvvvvv
', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); 
  747                                // store the DEFINEDNAME record 
  748                                $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); 
  752                // write the print areas, if any 
  753                for ($i = 0; $i < $total_worksheets; ++$i) { 
  754                        $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); 
  755                        if ($sheetSetup->isPrintAreaSet()) { 
  756                                // Print area, e.g. A3:J6,H1:X20 
  757                                $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); 
  758                                $countPrintArea = count($printArea); 
  761                                for ($j = 0; $j < $countPrintArea; ++$j) { 
  762                                        $printAreaRect = $printArea[$j]; // e.g. A3:J6 
  763                                        $printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]); 
  764                                        $printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]); 
  766                                        $print_rowmin = $printAreaRect[0][1] - 1; 
  767                                        $print_rowmax = $printAreaRect[1][1] - 1; 
  768                                        $print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1; 
  769                                        $print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1; 
  771                                        // construct formula data manually because parser does not recognize absolute 3d cell references 
  772                                        $formulaData .= pack('Cvvvvv
', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); 
  775                                                $formulaData .= pack('C', 0x10); // list operator token ',
' 
  779                                // store the DEFINEDNAME record 
  780                                $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); 
  784                // write autofilters, if any 
  785                for ($i = 0; $i < $total_worksheets; ++$i) { 
  786                        $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); 
  787                        $autoFilterRange = $sheetAutoFilter->getRange(); 
  788                        if(!empty($autoFilterRange)) { 
  789                                $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); 
  791                                //Autofilter built in name 
  792                                $name = pack('C', 0x0D); 
  794                                $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); 
  810        private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) 
  815                $options = $isBuiltIn ? 0x20 : 0x00; 
  817                // length of the name, character count 
  818                $nlen = PHPExcel_Shared_String::CountCharacters($name); 
  820                // name with stripped length field 
  821                $name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2); 
  823                // size of the formula (in bytes) 
  824                $sz = strlen($formulaData); 
  827                $data = pack('vCCvvvCCCC
', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0) 
  828                        . $name . $formulaData; 
  829                $length = strlen($data); 
  831                $header = pack('vv
', $record, $length); 
  833                return $header . $data; 
  845        private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ 
  849                $options = ($isHidden  ? 0x21 : 0x00); 
  851                $extra  = pack('Cvvvvv
', 
  854                                $rangeBounds[0][1] - 1, 
  855                                $rangeBounds[1][1] - 1, 
  856                                $rangeBounds[0][0] - 1, 
  857                                $rangeBounds[1][0] - 1); 
  859                // size of the formula (in bytes) 
  860                $sz = strlen($extra); 
  863                $data = pack('vCCvvvCCCCC
', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) 
  865                $length = strlen($data); 
  867                $header = pack('vv
', $record, $length); 
  869                return $header . $data; 
  875        private function _writeCodepage() 
  877                $record          = 0x0042;             // Record identifier 
  878                $length          = 0x0002;             // Number of bytes to follow 
  879                $cv              = $this->_codepage;   // The code page 
  881                $header          = pack('vv
', $record, $length); 
  882                $data            = pack('v
',  $cv); 
  884                $this->_append($header . $data); 
  890        private function _writeWindow1() 
  892                $record    = 0x003D;                 // Record identifier 
  893                $length    = 0x0012;                 // Number of bytes to follow 
  895                $xWn       = 0x0000;                 // Horizontal position of window 
  896                $yWn       = 0x0000;                 // Vertical position of window 
  897                $dxWn      = 0x25BC;                 // Width of window 
  898                $dyWn      = 0x1572;                 // Height of window 
  900                $grbit     = 0x0038;                 // Option flags 
  902                // not supported by PHPExcel, so there is only one selected sheet, the active 
  903                $ctabsel   = 1;       // Number of workbook tabs selected 
  905                $wTabRatio = 0x0258;                 // Tab to scrollbar ratio 
  907                // not supported by PHPExcel, set to 0 
  908                $itabFirst = 0;     // 1st displayed worksheet 
  909                $itabCur   = $this->_phpExcel->getActiveSheetIndex();    // Active worksheet 
  911                $header    = pack("vv",        $record, $length); 
  912                $data      = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, 
  914                                                                           $itabCur, $itabFirst, 
  915                                                                           $ctabsel, $wTabRatio); 
  916                $this->_append($header . $data); 
  925        private function _writeBoundsheet($sheet, $offset) 
  927                $sheetname = $sheet->getTitle(); 
  928                $record    = 0x0085;                    // Record identifier 
  931                switch ($sheet->getSheetState()) { 
  932                        case PHPExcel_Worksheet::SHEETSTATE_VISIBLE:    $ss = 0x00; break; 
  933                        case PHPExcel_Worksheet::SHEETSTATE_HIDDEN:             $ss = 0x01; break; 
  934                        case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; 
  935                        default: $ss = 0x00; break; 
  941                $grbit     = 0x0000;                    // Visibility and sheet type 
  943                $data      = pack("VCC", $offset, $ss, $st); 
  944                $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); 
  946                $length = strlen($data); 
  947                $header = pack("vv",  $record, $length); 
  948                $this->_append($header . $data); 
  954        private function _writeSupbookInternal() 
  956                $record    = 0x01AE;   // Record identifier 
  957                $length    = 0x0004;   // Bytes to follow 
  959                $header    = pack("vv", $record, $length); 
  960                $data      = pack("vv", $this->_phpExcel->getSheetCount(), 0x0401); 
  961                return $this->writeData($header . $data); 
  969        private function _writeExternsheetBiff8() 
  971                $total_references = count($this->_parser->_references); 
  972                $record   = 0x0017;                     // Record identifier 
  973                $length   = 2 + 6 * $total_references;  // Number of bytes to follow 
  975                $supbook_index = 0;           // FIXME: only using internal SUPBOOK record 
  976                $header           = pack("vv",  $record, $length); 
  977                $data             = pack('v
', $total_references); 
  978                for ($i = 0; $i < $total_references; ++$i) { 
  979                        $data .= $this->_parser->_references[$i]; 
  981                return $this->writeData($header . $data); 
  987        private function _writeStyle() 
  989                $record    = 0x0293;   // Record identifier 
  990                $length    = 0x0004;   // Bytes to follow 
  992                $ixfe      = 0x8000;  // Index to cell style XF 
  993                $BuiltIn   = 0x00;     // Built-in style 
  994                $iLevel    = 0xff;     // Outline style level 
  996                $header    = pack("vv",  $record, $length); 
  997                $data      = pack("vCC", $ixfe, $BuiltIn, $iLevel); 
  998                $this->_append($header . $data); 
 1007        private function _writeNumFormat($format, $ifmt) 
 1009                $record    = 0x041E;                      // Record identifier 
 1011                $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); 
 1012                $length    = 2 + strlen($numberFormatString);      // Number of bytes to follow 
 1015                $header    = pack("vv", $record, $length); 
 1016                $data      = pack("v", $ifmt) .  $numberFormatString; 
 1017                $this->_append($header . $data); 
 1023        private function _writeDatemode() 
 1025                $record    = 0x0022;         // Record identifier 
 1026                $length    = 0x0002;         // Bytes to follow 
 1028                $f1904     = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? 
 1029                        1 : 0;   // Flag for 1904 date system 
 1031                $header    = pack("vv", $record, $length); 
 1032                $data      = pack("v", $f1904); 
 1033                $this->_append($header . $data); 
 1048        private function _writeExterncount($cxals) 
 1050                $record   = 0x0016;          // Record identifier 
 1051                $length   = 0x0002;          // Number of bytes to follow 
 1053                $header   = pack("vv", $record, $length); 
 1054                $data     = pack("v",  $cxals); 
 1055                $this->_append($header . $data); 
 1067        private function _writeExternsheet($sheetname) 
 1069                $record      = 0x0017;                     // Record identifier 
 1070                $length      = 0x02 + strlen($sheetname);  // Number of bytes to follow 
 1072                $cch         = strlen($sheetname);         // Length of sheet name 
 1073                $rgch        = 0x03;                       // Filename encoding 
 1075                $header      = pack("vv",  $record, $length); 
 1076                $data        = pack("CC", $cch, $rgch); 
 1077                $this->_append($header . $data . $sheetname); 
 1091        private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) 
 1093                $record          = 0x0018;       // Record identifier 
 1094                $length          = 0x0024;       // Number of bytes to follow 
 1096                $grbit           = 0x0020;       // Option flags 
 1097                $chKey           = 0x00;         // Keyboard shortcut 
 1098                $cch             = 0x01;         // Length of text name 
 1099                $cce             = 0x0015;       // Length of text definition 
 1100                $ixals           = $index + 1;   // Sheet index 
 1101                $itab            = $ixals;       // Equal to ixals 
 1102                $cchCustMenu     = 0x00;         // Length of cust menu text 
 1103                $cchDescription  = 0x00;         // Length of description text 
 1104                $cchHelptopic    = 0x00;         // Length of help topic text 
 1105                $cchStatustext   = 0x00;         // Length of status bar text 
 1106                $rgch            = $type;        // Built-in name type 
 1109                $unknown04       = 0xffff-$index; 
 1110                $unknown05       = 0x0000; 
 1111                $unknown06       = 0x0000; 
 1112                $unknown07       = 0x1087; 
 1113                $unknown08       = 0x8005; 
 1115                $header             = pack("vv", $record, $length); 
 1116                $data               = pack("v", $grbit); 
 1117                $data              .= pack("C", $chKey); 
 1118                $data              .= pack("C", $cch); 
 1119                $data              .= pack("v", $cce); 
 1120                $data              .= pack("v", $ixals); 
 1121                $data              .= pack("v", $itab); 
 1122                $data              .= pack("C", $cchCustMenu); 
 1123                $data              .= pack("C", $cchDescription); 
 1124                $data              .= pack("C", $cchHelptopic); 
 1125                $data              .= pack("C", $cchStatustext); 
 1126                $data              .= pack("C", $rgch); 
 1127                $data              .= pack("C", $unknown03); 
 1128                $data              .= pack("v", $unknown04); 
 1129                $data              .= pack("v", $unknown05); 
 1130                $data              .= pack("v", $unknown06); 
 1131                $data              .= pack("v", $unknown07); 
 1132                $data              .= pack("v", $unknown08); 
 1133                $data              .= pack("v", $index); 
 1134                $data              .= pack("v", $index); 
 1135                $data              .= pack("v", $rowmin); 
 1136                $data              .= pack("v", $rowmax); 
 1137                $data              .= pack("C", $colmin); 
 1138                $data              .= pack("C", $colmax); 
 1139                $this->_append($header . $data); 
 1155        private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) 
 1157                $record          = 0x0018;       // Record identifier 
 1158                $length          = 0x003d;       // Number of bytes to follow 
 1159                $grbit           = 0x0020;       // Option flags 
 1160                $chKey           = 0x00;         // Keyboard shortcut 
 1161                $cch             = 0x01;         // Length of text name 
 1162                $cce             = 0x002e;       // Length of text definition 
 1163                $ixals           = $index + 1;   // Sheet index 
 1164                $itab            = $ixals;       // Equal to ixals 
 1165                $cchCustMenu     = 0x00;         // Length of cust menu text 
 1166                $cchDescription  = 0x00;         // Length of description text 
 1167                $cchHelptopic    = 0x00;         // Length of help topic text 
 1168                $cchStatustext   = 0x00;         // Length of status bar text 
 1169                $rgch            = $type;        // Built-in name type 
 1172                $unknown02       = 0x002b; 
 1174                $unknown04       = 0xffff-$index; 
 1175                $unknown05       = 0x0000; 
 1176                $unknown06       = 0x0000; 
 1177                $unknown07       = 0x1087; 
 1178                $unknown08       = 0x8008; 
 1180                $header             = pack("vv",  $record, $length); 
 1181                $data               = pack("v", $grbit); 
 1182                $data              .= pack("C", $chKey); 
 1183                $data              .= pack("C", $cch); 
 1184                $data              .= pack("v", $cce); 
 1185                $data              .= pack("v", $ixals); 
 1186                $data              .= pack("v", $itab); 
 1187                $data              .= pack("C", $cchCustMenu); 
 1188                $data              .= pack("C", $cchDescription); 
 1189                $data              .= pack("C", $cchHelptopic); 
 1190                $data              .= pack("C", $cchStatustext); 
 1191                $data              .= pack("C", $rgch); 
 1192                $data              .= pack("C", $unknown01); 
 1193                $data              .= pack("v", $unknown02); 
 1194                // Column definition 
 1195                $data              .= pack("C", $unknown03); 
 1196                $data              .= pack("v", $unknown04); 
 1197                $data              .= pack("v", $unknown05); 
 1198                $data              .= pack("v", $unknown06); 
 1199                $data              .= pack("v", $unknown07); 
 1200                $data              .= pack("v", $unknown08); 
 1201                $data              .= pack("v", $index); 
 1202                $data              .= pack("v", $index); 
 1203                $data              .= pack("v", 0x0000); 
 1204                $data              .= pack("v", 0x3fff); 
 1205                $data              .= pack("C", $colmin); 
 1206                $data              .= pack("C", $colmax); 
 1208                $data              .= pack("C", $unknown03); 
 1209                $data              .= pack("v", $unknown04); 
 1210                $data              .= pack("v", $unknown05); 
 1211                $data              .= pack("v", $unknown06); 
 1212                $data              .= pack("v", $unknown07); 
 1213                $data              .= pack("v", $unknown08); 
 1214                $data              .= pack("v", $index); 
 1215                $data              .= pack("v", $index); 
 1216                $data              .= pack("v", $rowmin); 
 1217                $data              .= pack("v", $rowmax); 
 1218                $data              .= pack("C", 0x00); 
 1219                $data              .= pack("C", 0xff); 
 1221                $data              .= pack("C", 0x10); 
 1222                $this->_append($header . $data); 
 1230        private function _writeCountry() 
 1232                $record          = 0x008C;    // Record identifier 
 1233                $length          = 4;         // Number of bytes to follow 
 1235                $header = pack('vv
',  $record, $length); 
 1236                /* using the same country code always for simplicity */ 
 1237                $data = pack('vv
', $this->_country_code, $this->_country_code); 
 1238                //$this->_append($header . $data); 
 1239                return $this->writeData($header . $data); 
 1247        private function _writeRecalcId() 
 1249                $record = 0x01C1;    // Record identifier 
 1250                $length = 8;         // Number of bytes to follow 
 1252                $header = pack('vv
',  $record, $length); 
 1254                // by inspection of real Excel files, MS Office Excel 2007 writes this 
 1255                $data = pack('VV
', 0x000001C1, 0x00001E667); 
 1257                return $this->writeData($header . $data); 
 1263        private function _writePalette() 
 1265                $aref            = $this->_palette; 
 1267                $record          = 0x0092;                 // Record identifier 
 1268                $length          = 2 + 4 * count($aref);   // Number of bytes to follow 
 1269                $ccv             =         count($aref);   // Number of RGB values to follow 
 1270                $data = '';                                // The RGB data 
 1272                // Pack the RGB data 
 1273                foreach ($aref as $color) { 
 1274                        foreach ($color as $byte) { 
 1275                                $data .= pack("C",$byte); 
 1279                $header = pack("vvv",  $record, $length, $ccv); 
 1280                $this->_append($header . $data); 
 1297        private function _writeSharedStringsTable() 
 1299                // maximum size of record data (excluding record header) 
 1300                $continue_limit = 8224; 
 1302                // initialize array of record data blocks 
 1303                $recordDatas = array(); 
 1305                // start SST record data block with total number of strings, total number of unique strings 
 1306                $recordData = pack("VV", $this->_str_total, $this->_str_unique); 
 1308                // loop through all (unique) strings in shared strings table 
 1309                foreach (array_keys($this->_str_table) as $string) { 
 1311                        // here $string is a BIFF8 encoded string 
 1313                        // length = character count 
 1314                        $headerinfo = unpack("vlength/Cencoding", $string); 
 1316                        // currently, this is always 1 = uncompressed 
 1317                        $encoding = $headerinfo["encoding"]; 
 1319                        // initialize finished writing current $string 
 1322                        while ($finished === false) { 
 1324                                // normally, there will be only one cycle, but if string cannot immediately be written as is 
 1325                                // there will be need for more than one cylcle, if string longer than one record data block, there 
 1326                                // may be need for even more cycles 
 1328                                if (strlen($recordData) + strlen($string) <= $continue_limit) { 
 1329                                        // then we can write the string (or remainder of string) without any problems 
 1330                                        $recordData .= $string; 
 1332                                        if (strlen($recordData) + strlen($string) == $continue_limit) { 
 1333                                                // we close the record data block, and initialize a new one 
 1334                                                $recordDatas[] = $recordData; 
 1338                                        // we are finished writing this string 
 1341                                        // special treatment writing the string (or remainder of the string) 
 1342                                        // If the string is very long it may need to be written in more than one CONTINUE record. 
 1344                                        // check how many bytes more there is room for in the current record 
 1345                                        $space_remaining = $continue_limit - strlen($recordData); 
 1347                                        // minimum space needed 
 1348                                        // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character 
 1349                                        // compressed:   2 byte string length length field + 1 byte option flags + 1 byte character 
 1350                                        $min_space_needed = ($encoding == 1) ? 5 : 4; 
 1352                                        // We have two cases 
 1353                                        // 1. space remaining is less than minimum space needed 
 1354                                        //              here we must waste the space remaining and move to next record data block 
 1355                                        // 2. space remaining is greater than or equal to minimum space needed 
 1356                                        //              here we write as much as we can in the current block, then move to next record data block 
 1358                                        // 1. space remaining is less than minimum space needed 
 1359                                        if ($space_remaining < $min_space_needed) { 
 1360                                                // we close the block, store the block data 
 1361                                                $recordDatas[] = $recordData; 
 1363                                                // and start new record data block where we start writing the string 
 1366                                        // 2. space remaining is greater than or equal to minimum space needed 
 1368                                                // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below 
 1369                                                $effective_space_remaining = $space_remaining; 
 1371                                                // for uncompressed strings, sometimes effective space remaining is reduced by 1 
 1372                                                if ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) { 
 1373                                                        --$effective_space_remaining; 
 1376                                                // one block fininshed, store the block data 
 1377                                                $recordData .= substr($string, 0, $effective_space_remaining); 
 1379                                                $string = substr($string, $effective_space_remaining); // for next cycle in while loop 
 1380                                                $recordDatas[] = $recordData; 
 1382                                                // start new record data block with the repeated option flags 
 1383                                                $recordData = pack('C', $encoding); 
 1389                // Store the last record data block unless it is empty 
 1390                // if there was no need for any continue records, this will be the for SST record data block itself 
 1391                if (strlen($recordData) > 0) { 
 1392                        $recordDatas[] = $recordData; 
 1395                // combine into one chunk with all the blocks SST, CONTINUE,... 
 1397                foreach ($recordDatas as $i => $recordData) { 
 1398                        // first block should have the SST record header, remaing should have CONTINUE header 
 1399                        $record = ($i == 0) ? 0x00FC : 0x003C; 
 1401                        $header = pack("vv", $record, strlen($recordData)); 
 1402                        $data = $header . $recordData; 
 1404                        $chunk .= $this->writeData($data); 
 1413        private function _writeMsoDrawingGroup() 
 1415                // write the Escher stream if necessary 
 1416                if (isset($this->_escher)) { 
 1417                        $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); 
 1418                        $data = $writer->close(); 
 1421                        $length = strlen($data); 
 1422                        $header = pack("vv",  $record, $length); 
 1424                        return $this->writeData($header . $data); 
 1436        public function getEscher() 
 1438                return $this->_escher; 
 1446        public function setEscher(PHPExcel_Shared_Escher $pValue = null) 
 1448                $this->_escher = $pValue; 
An exception for terminatinating execution or to throw for unit testing.
static coordinateFromString($pCoordinateString='A1')
Coordinate from string.
static splitRange($pRange='A1:A1')
Split range into coordinate strings.
static columnIndexFromString($pString='A')
Column index from string.
static UTF8toBIFF8UnicodeShort($value, $arrcRuns=array())
Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) Writes the string using ...
getHashCode()
Get hash code.
_storeBof($type)
Writes Excel BOF record to indicate the beginning of a stream or sub-stream in the BIFF file.
writeEof()
Writes Excel EOF record to indicate the end of a BIFF stream.
_append($data)
General storage function.
_writeRecalcId()
Write the RECALCID record.
_writeNames()
Write the NAME record to define the print area and the repeat rows and cols.
_writeNumFormat($format, $ifmt)
Writes Excel FORMAT record for non "built-in" numerical formats.
addXfWriter($style, $isStyleXf=false)
Add a new XF writer.
_writeExternsheetBiff8()
Writes the Excel BIFF EXTERNSHEET record.
_writeExterns()
Write the EXTERNCOUNT and EXTERNSHEET records.
_writeSharedStringsTable()
Handling of the SST continue blocks is complicated by the need to include an additional continuation ...
_writeExternsheet($sheetname)
Writes the Excel BIFF EXTERNSHEET record.
__construct(PHPExcel $phpExcel=null, &$str_total, &$str_unique, &$str_table, &$colors, $parser)
Class constructor.
_writeExterncount($cxals)
Write BIFF record EXTERNCOUNT to indicate the number of external sheet references in the workbook.
_writeBoundsheet($sheet, $offset)
Writes Excel BIFF BOUNDSHEET record.
_writeCountry()
Stores the COUNTRY record for localization.
_writeMsoDrawingGroup()
Writes the MSODRAWINGGROUP record if needed.
_calcSheetOffsets()
Calculate offsets for Worksheet BOF records.
_writeNameLong($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...
_writeCodepage()
Stores the CODEPAGE biff record.
_writePalette()
Stores the PALETTE biff record.
writeWorkbook($pWorksheetSizes=null)
Assemble worksheets into a workbook and send the BIFF data to an OLE storage.
_writeAllFonts()
Store the Excel FONT records.
_writeAllXfs()
Write all XF records.
_writeSupbookInternal()
Write Internal SUPBOOK record.
_addColor($rgb)
Alter color palette adding a custom color.
_writeDatemode()
Write DATEMODE record to indicate the date system in use (1904 or 1900).
_addFont(PHPExcel_Style_Font $font)
Add a font to added fonts.
_writeAllDefinedNamesBiff8()
Writes all the DEFINEDNAME records (BIFF8).
_setPaletteXl97()
Sets the colour palette to the Excel 97+ default.
_writeStyle()
Write Excel BIFF STYLE records.
_writeWindow1()
Write Excel BIFF WINDOW1 record.
_writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax)
Store the NAME record in the short format that is used for storing the print area,...
_writeAllStyles()
Write all STYLE records.
_writeAllNumFormats()
Store user defined numerical formats i.e.