Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 88

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 215

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 216

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 217

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 218

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 219

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 220
PK!b۴Rterminate-i.yamlnu[--- !ruby/object:RI::MethodDescription aliases: [] block_params: comment: full_name: CSV::Writer#terminate is_singleton: false name: terminate params: () visibility: private PK!ieB-cdesc-Writer.yamlnu[--- !ruby/object:RI::ClassDescription attributes: [] class_methods: - !ruby/object:RI::MethodSummary name: create - !ruby/object:RI::MethodSummary name: generate - !ruby/object:RI::MethodSummary name: new comment: - !ruby/struct:SM::Flow::P body: CSV formatted string/stream writer. - !ruby/struct:SM::Flow::P body: EXAMPLE - !ruby/struct:SM::Flow::VERB body: " Write rows to 'csvout' file.\n\n outfile = File.open('csvout', 'wb')\n CSV::Writer.generate(outfile) do |csv|\n csv << ['c1', nil, '', '"', "\\r\\n", 'c2']\n ...\n end\n\n outfile.close\n" constants: [] full_name: CSV::Writer includes: [] instance_methods: - !ruby/object:RI::MethodSummary name: "<<" - !ruby/object:RI::MethodSummary name: add_row - !ruby/object:RI::MethodSummary name: close - !ruby/object:RI::MethodSummary name: terminate name: Writer superclass: Object PK!j= new-c.yamlnu[--- !ruby/object:RI::MethodDescription aliases: [] block_params: comment: full_name: CSV::Writer::new is_singleton: true name: new params: (dev) visibility: public PK! j"" create-c.yamlnu[--- !ruby/object:RI::MethodDescription aliases: [] block_params: comment: - !ruby/struct:SM::Flow::P body: str_or_writable must handle '<<(string)'. full_name: CSV::Writer::create is_singleton: true name: create params: (str_or_writable, fs = ',', rs = nil) visibility: public PK!`Č;; %3c%3c-i.yamlnu[--- !ruby/object:RI::MethodDescription aliases: - !ruby/object:RI::AliasName name: add_row block_params: comment: - !ruby/struct:SM::Flow::P body: dump CSV stream to the device. argument must be an Array of String. full_name: CSV::Writer#<< is_singleton: false name: "<<" params: (row) visibility: public PK!ãadd_row-i.yamlnu[--- !ruby/object:RI::MethodDescription aliases: [] block_params: comment: - !ruby/struct:SM::Flow::P body: "Alias for #<<" full_name: CSV::Writer#add_row is_singleton: false name: add_row params: (row) visibility: public PK!uugenerate-c.yamlnu[--- !ruby/object:RI::MethodDescription aliases: [] block_params: (writer) comment: - !ruby/struct:SM::Flow::P body: Given block is called with the writer instance. str_or_writable must handle '<<(string)'. full_name: CSV::Writer::generate is_singleton: true name: generate params: (str_or_writable, fs = ',', rs = nil, &block) {|writer| ...} visibility: public PK!ֳ close-i.yamlnu[--- !ruby/object:RI::MethodDescription aliases: [] block_params: comment: full_name: CSV::Writer#close is_singleton: false name: close params: () visibility: public PK!q#{YP'P'Excel2007/Comments.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Comments cache $comments = $pWorksheet->getComments(); // Authors cache $authors = array(); $authorId = 0; foreach ($comments as $comment) { if (!isset($authors[$comment->getAuthor()])) { $authors[$comment->getAuthor()] = $authorId++; } } // comments $objWriter->startElement('comments'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); // Loop through authors $objWriter->startElement('authors'); foreach ($authors as $author => $index) { $objWriter->writeElement('author', $author); } $objWriter->endElement(); // Loop through comments $objWriter->startElement('commentList'); foreach ($comments as $key => $value) { $this->writeComment($objWriter, $key, $value, $authors); } $objWriter->endElement(); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write comment to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pCellReference Cell reference * @param PHPExcel_Comment $pComment Comment * @param array $pAuthors Array of authors * @throws PHPExcel_Writer_Exception */ private function writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) { // comment $objWriter->startElement('comment'); $objWriter->writeAttribute('ref', $pCellReference); $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); // text $objWriter->startElement('text'); $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); $objWriter->endElement(); $objWriter->endElement(); } /** * Write VML comments to XML format * * @param PHPExcel_Worksheet $pWorksheet * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Comments cache $comments = $pWorksheet->getComments(); // xml $objWriter->startElement('xml'); $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); // o:shapelayout $objWriter->startElement('o:shapelayout'); $objWriter->writeAttribute('v:ext', 'edit'); // o:idmap $objWriter->startElement('o:idmap'); $objWriter->writeAttribute('v:ext', 'edit'); $objWriter->writeAttribute('data', '1'); $objWriter->endElement(); $objWriter->endElement(); // v:shapetype $objWriter->startElement('v:shapetype'); $objWriter->writeAttribute('id', '_x0000_t202'); $objWriter->writeAttribute('coordsize', '21600,21600'); $objWriter->writeAttribute('o:spt', '202'); $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); // v:stroke $objWriter->startElement('v:stroke'); $objWriter->writeAttribute('joinstyle', 'miter'); $objWriter->endElement(); // v:path $objWriter->startElement('v:path'); $objWriter->writeAttribute('gradientshapeok', 't'); $objWriter->writeAttribute('o:connecttype', 'rect'); $objWriter->endElement(); $objWriter->endElement(); // Loop through comments foreach ($comments as $key => $value) { $this->writeVMLComment($objWriter, $key, $value); } $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write VML comment to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pCellReference Cell reference * @param PHPExcel_Comment $pComment Comment * @throws PHPExcel_Writer_Exception */ private function writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) { // Metadata list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference); $column = PHPExcel_Cell::columnIndexFromString($column); $id = 1024 + $column + $row; $id = substr($id, 0, 4); // v:shape $objWriter->startElement('v:shape'); $objWriter->writeAttribute('id', '_x0000_s' . $id); $objWriter->writeAttribute('type', '#_x0000_t202'); $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); $objWriter->writeAttribute('o:insetmode', 'auto'); // v:fill $objWriter->startElement('v:fill'); $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); $objWriter->endElement(); // v:shadow $objWriter->startElement('v:shadow'); $objWriter->writeAttribute('on', 't'); $objWriter->writeAttribute('color', 'black'); $objWriter->writeAttribute('obscured', 't'); $objWriter->endElement(); // v:path $objWriter->startElement('v:path'); $objWriter->writeAttribute('o:connecttype', 'none'); $objWriter->endElement(); // v:textbox $objWriter->startElement('v:textbox'); $objWriter->writeAttribute('style', 'mso-direction-alt:auto'); // div $objWriter->startElement('div'); $objWriter->writeAttribute('style', 'text-align:left'); $objWriter->endElement(); $objWriter->endElement(); // x:ClientData $objWriter->startElement('x:ClientData'); $objWriter->writeAttribute('ObjectType', 'Note'); // x:MoveWithCells $objWriter->writeElement('x:MoveWithCells', ''); // x:SizeWithCells $objWriter->writeElement('x:SizeWithCells', ''); // x:Anchor //$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18'); // x:AutoFill $objWriter->writeElement('x:AutoFill', 'False'); // x:Row $objWriter->writeElement('x:Row', ($row - 1)); // x:Column $objWriter->writeElement('x:Column', ($column - 1)); $objWriter->endElement(); $objWriter->endElement(); } } PK!yZ]]Excel2007/Theme.phpnu[ 'MS Pゴシック', 'Hang' => '맑은 고딕', 'Hans' => '宋体', 'Hant' => '新細明體', 'Arab' => 'Times New Roman', 'Hebr' => 'Times New Roman', 'Thai' => 'Tahoma', 'Ethi' => 'Nyala', 'Beng' => 'Vrinda', 'Gujr' => 'Shruti', 'Khmr' => 'MoolBoran', 'Knda' => 'Tunga', 'Guru' => 'Raavi', 'Cans' => 'Euphemia', 'Cher' => 'Plantagenet Cherokee', 'Yiii' => 'Microsoft Yi Baiti', 'Tibt' => 'Microsoft Himalaya', 'Thaa' => 'MV Boli', 'Deva' => 'Mangal', 'Telu' => 'Gautami', 'Taml' => 'Latha', 'Syrc' => 'Estrangelo Edessa', 'Orya' => 'Kalinga', 'Mlym' => 'Kartika', 'Laoo' => 'DokChampa', 'Sinh' => 'Iskoola Pota', 'Mong' => 'Mongolian Baiti', 'Viet' => 'Times New Roman', 'Uigh' => 'Microsoft Uighur', 'Geor' => 'Sylfaen', ); /** * Map of Minor fonts to write * @static array of string * */ private static $minorFonts = array( 'Jpan' => 'MS Pゴシック', 'Hang' => '맑은 고딕', 'Hans' => '宋体', 'Hant' => '新細明體', 'Arab' => 'Arial', 'Hebr' => 'Arial', 'Thai' => 'Tahoma', 'Ethi' => 'Nyala', 'Beng' => 'Vrinda', 'Gujr' => 'Shruti', 'Khmr' => 'DaunPenh', 'Knda' => 'Tunga', 'Guru' => 'Raavi', 'Cans' => 'Euphemia', 'Cher' => 'Plantagenet Cherokee', 'Yiii' => 'Microsoft Yi Baiti', 'Tibt' => 'Microsoft Himalaya', 'Thaa' => 'MV Boli', 'Deva' => 'Mangal', 'Telu' => 'Gautami', 'Taml' => 'Latha', 'Syrc' => 'Estrangelo Edessa', 'Orya' => 'Kalinga', 'Mlym' => 'Kartika', 'Laoo' => 'DokChampa', 'Sinh' => 'Iskoola Pota', 'Mong' => 'Mongolian Baiti', 'Viet' => 'Arial', 'Uigh' => 'Microsoft Uighur', 'Geor' => 'Sylfaen', ); /** * Map of core colours * @static array of string * */ private static $colourScheme = array( 'dk2' => '1F497D', 'lt2' => 'EEECE1', 'accent1' => '4F81BD', 'accent2' => 'C0504D', 'accent3' => '9BBB59', 'accent4' => '8064A2', 'accent5' => '4BACC6', 'accent6' => 'F79646', 'hlink' => '0000FF', 'folHlink' => '800080', ); /** * Write theme to XML format * * @param PHPExcel $pPHPExcel * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeTheme(PHPExcel $pPHPExcel = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // a:theme $objWriter->startElement('a:theme'); $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); $objWriter->writeAttribute('name', 'Office Theme'); // a:themeElements $objWriter->startElement('a:themeElements'); // a:clrScheme $objWriter->startElement('a:clrScheme'); $objWriter->writeAttribute('name', 'Office'); // a:dk1 $objWriter->startElement('a:dk1'); // a:sysClr $objWriter->startElement('a:sysClr'); $objWriter->writeAttribute('val', 'windowText'); $objWriter->writeAttribute('lastClr', '000000'); $objWriter->endElement(); $objWriter->endElement(); // a:lt1 $objWriter->startElement('a:lt1'); // a:sysClr $objWriter->startElement('a:sysClr'); $objWriter->writeAttribute('val', 'window'); $objWriter->writeAttribute('lastClr', 'FFFFFF'); $objWriter->endElement(); $objWriter->endElement(); // a:dk2 $this->writeColourScheme($objWriter); $objWriter->endElement(); // a:fontScheme $objWriter->startElement('a:fontScheme'); $objWriter->writeAttribute('name', 'Office'); // a:majorFont $objWriter->startElement('a:majorFont'); $this->writeFonts($objWriter, 'Cambria', self::$majorFonts); $objWriter->endElement(); // a:minorFont $objWriter->startElement('a:minorFont'); $this->writeFonts($objWriter, 'Calibri', self::$minorFonts); $objWriter->endElement(); $objWriter->endElement(); // a:fmtScheme $objWriter->startElement('a:fmtScheme'); $objWriter->writeAttribute('name', 'Office'); // a:fillStyleLst $objWriter->startElement('a:fillStyleLst'); // a:solidFill $objWriter->startElement('a:solidFill'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); $objWriter->endElement(); // a:gradFill $objWriter->startElement('a:gradFill'); $objWriter->writeAttribute('rotWithShape', '1'); // a:gsLst $objWriter->startElement('a:gsLst'); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '0'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:tint $objWriter->startElement('a:tint'); $objWriter->writeAttribute('val', '50000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '300000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '35000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:tint $objWriter->startElement('a:tint'); $objWriter->writeAttribute('val', '37000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '300000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '100000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:tint $objWriter->startElement('a:tint'); $objWriter->writeAttribute('val', '15000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '350000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:lin $objWriter->startElement('a:lin'); $objWriter->writeAttribute('ang', '16200000'); $objWriter->writeAttribute('scaled', '1'); $objWriter->endElement(); $objWriter->endElement(); // a:gradFill $objWriter->startElement('a:gradFill'); $objWriter->writeAttribute('rotWithShape', '1'); // a:gsLst $objWriter->startElement('a:gsLst'); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '0'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '51000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '130000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '80000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '93000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '130000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '100000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '94000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '135000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:lin $objWriter->startElement('a:lin'); $objWriter->writeAttribute('ang', '16200000'); $objWriter->writeAttribute('scaled', '0'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:lnStyleLst $objWriter->startElement('a:lnStyleLst'); // a:ln $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', '9525'); $objWriter->writeAttribute('cap', 'flat'); $objWriter->writeAttribute('cmpd', 'sng'); $objWriter->writeAttribute('algn', 'ctr'); // a:solidFill $objWriter->startElement('a:solidFill'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '95000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '105000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:prstDash $objWriter->startElement('a:prstDash'); $objWriter->writeAttribute('val', 'solid'); $objWriter->endElement(); $objWriter->endElement(); // a:ln $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', '25400'); $objWriter->writeAttribute('cap', 'flat'); $objWriter->writeAttribute('cmpd', 'sng'); $objWriter->writeAttribute('algn', 'ctr'); // a:solidFill $objWriter->startElement('a:solidFill'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); $objWriter->endElement(); // a:prstDash $objWriter->startElement('a:prstDash'); $objWriter->writeAttribute('val', 'solid'); $objWriter->endElement(); $objWriter->endElement(); // a:ln $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', '38100'); $objWriter->writeAttribute('cap', 'flat'); $objWriter->writeAttribute('cmpd', 'sng'); $objWriter->writeAttribute('algn', 'ctr'); // a:solidFill $objWriter->startElement('a:solidFill'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); $objWriter->endElement(); // a:prstDash $objWriter->startElement('a:prstDash'); $objWriter->writeAttribute('val', 'solid'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:effectStyleLst $objWriter->startElement('a:effectStyleLst'); // a:effectStyle $objWriter->startElement('a:effectStyle'); // a:effectLst $objWriter->startElement('a:effectLst'); // a:outerShdw $objWriter->startElement('a:outerShdw'); $objWriter->writeAttribute('blurRad', '40000'); $objWriter->writeAttribute('dist', '20000'); $objWriter->writeAttribute('dir', '5400000'); $objWriter->writeAttribute('rotWithShape', '0'); // a:srgbClr $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', '000000'); // a:alpha $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', '38000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:effectStyle $objWriter->startElement('a:effectStyle'); // a:effectLst $objWriter->startElement('a:effectLst'); // a:outerShdw $objWriter->startElement('a:outerShdw'); $objWriter->writeAttribute('blurRad', '40000'); $objWriter->writeAttribute('dist', '23000'); $objWriter->writeAttribute('dir', '5400000'); $objWriter->writeAttribute('rotWithShape', '0'); // a:srgbClr $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', '000000'); // a:alpha $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', '35000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:effectStyle $objWriter->startElement('a:effectStyle'); // a:effectLst $objWriter->startElement('a:effectLst'); // a:outerShdw $objWriter->startElement('a:outerShdw'); $objWriter->writeAttribute('blurRad', '40000'); $objWriter->writeAttribute('dist', '23000'); $objWriter->writeAttribute('dir', '5400000'); $objWriter->writeAttribute('rotWithShape', '0'); // a:srgbClr $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', '000000'); // a:alpha $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', '35000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:scene3d $objWriter->startElement('a:scene3d'); // a:camera $objWriter->startElement('a:camera'); $objWriter->writeAttribute('prst', 'orthographicFront'); // a:rot $objWriter->startElement('a:rot'); $objWriter->writeAttribute('lat', '0'); $objWriter->writeAttribute('lon', '0'); $objWriter->writeAttribute('rev', '0'); $objWriter->endElement(); $objWriter->endElement(); // a:lightRig $objWriter->startElement('a:lightRig'); $objWriter->writeAttribute('rig', 'threePt'); $objWriter->writeAttribute('dir', 't'); // a:rot $objWriter->startElement('a:rot'); $objWriter->writeAttribute('lat', '0'); $objWriter->writeAttribute('lon', '0'); $objWriter->writeAttribute('rev', '1200000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:sp3d $objWriter->startElement('a:sp3d'); // a:bevelT $objWriter->startElement('a:bevelT'); $objWriter->writeAttribute('w', '63500'); $objWriter->writeAttribute('h', '25400'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:bgFillStyleLst $objWriter->startElement('a:bgFillStyleLst'); // a:solidFill $objWriter->startElement('a:solidFill'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); $objWriter->endElement(); // a:gradFill $objWriter->startElement('a:gradFill'); $objWriter->writeAttribute('rotWithShape', '1'); // a:gsLst $objWriter->startElement('a:gsLst'); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '0'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:tint $objWriter->startElement('a:tint'); $objWriter->writeAttribute('val', '40000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '350000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '40000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:tint $objWriter->startElement('a:tint'); $objWriter->writeAttribute('val', '45000'); $objWriter->endElement(); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '99000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '350000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '100000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '20000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '255000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:path $objWriter->startElement('a:path'); $objWriter->writeAttribute('path', 'circle'); // a:fillToRect $objWriter->startElement('a:fillToRect'); $objWriter->writeAttribute('l', '50000'); $objWriter->writeAttribute('t', '-80000'); $objWriter->writeAttribute('r', '50000'); $objWriter->writeAttribute('b', '180000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gradFill $objWriter->startElement('a:gradFill'); $objWriter->writeAttribute('rotWithShape', '1'); // a:gsLst $objWriter->startElement('a:gsLst'); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '0'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:tint $objWriter->startElement('a:tint'); $objWriter->writeAttribute('val', '80000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '300000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:gs $objWriter->startElement('a:gs'); $objWriter->writeAttribute('pos', '100000'); // a:schemeClr $objWriter->startElement('a:schemeClr'); $objWriter->writeAttribute('val', 'phClr'); // a:shade $objWriter->startElement('a:shade'); $objWriter->writeAttribute('val', '30000'); $objWriter->endElement(); // a:satMod $objWriter->startElement('a:satMod'); $objWriter->writeAttribute('val', '200000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:path $objWriter->startElement('a:path'); $objWriter->writeAttribute('path', 'circle'); // a:fillToRect $objWriter->startElement('a:fillToRect'); $objWriter->writeAttribute('l', '50000'); $objWriter->writeAttribute('t', '50000'); $objWriter->writeAttribute('r', '50000'); $objWriter->writeAttribute('b', '50000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // a:objectDefaults $objWriter->writeElement('a:objectDefaults', null); // a:extraClrSchemeLst $objWriter->writeElement('a:extraClrSchemeLst', null); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write fonts to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter * @param string $latinFont * @param array of string $fontSet * @return string XML Output * @throws PHPExcel_Writer_Exception */ private function writeFonts($objWriter, $latinFont, $fontSet) { // a:latin $objWriter->startElement('a:latin'); $objWriter->writeAttribute('typeface', $latinFont); $objWriter->endElement(); // a:ea $objWriter->startElement('a:ea'); $objWriter->writeAttribute('typeface', ''); $objWriter->endElement(); // a:cs $objWriter->startElement('a:cs'); $objWriter->writeAttribute('typeface', ''); $objWriter->endElement(); foreach ($fontSet as $fontScript => $typeface) { $objWriter->startElement('a:font'); $objWriter->writeAttribute('script', $fontScript); $objWriter->writeAttribute('typeface', $typeface); $objWriter->endElement(); } } /** * Write colour scheme to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter * @return string XML Output * @throws PHPExcel_Writer_Exception */ private function writeColourScheme($objWriter) { foreach (self::$colourScheme as $colourName => $colourValue) { $objWriter->startElement('a:'.$colourName); $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', $colourValue); $objWriter->endElement(); $objWriter->endElement(); } } } PK!O+Q\&\&Excel2007/DocProps.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Properties $objWriter->startElement('Properties'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); // Application $objWriter->writeElement('Application', 'Microsoft Excel'); // DocSecurity $objWriter->writeElement('DocSecurity', '0'); // ScaleCrop $objWriter->writeElement('ScaleCrop', 'false'); // HeadingPairs $objWriter->startElement('HeadingPairs'); // Vector $objWriter->startElement('vt:vector'); $objWriter->writeAttribute('size', '2'); $objWriter->writeAttribute('baseType', 'variant'); // Variant $objWriter->startElement('vt:variant'); $objWriter->writeElement('vt:lpstr', 'Worksheets'); $objWriter->endElement(); // Variant $objWriter->startElement('vt:variant'); $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // TitlesOfParts $objWriter->startElement('TitlesOfParts'); // Vector $objWriter->startElement('vt:vector'); $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); $objWriter->writeAttribute('baseType', 'lpstr'); $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); } $objWriter->endElement(); $objWriter->endElement(); // Company $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); // Company $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); // LinksUpToDate $objWriter->writeElement('LinksUpToDate', 'false'); // SharedDoc $objWriter->writeElement('SharedDoc', 'false'); // HyperlinksChanged $objWriter->writeElement('HyperlinksChanged', 'false'); // AppVersion $objWriter->writeElement('AppVersion', '12.0000'); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write docProps/core.xml to XML format * * @param PHPExcel $pPHPExcel * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeDocPropsCore(PHPExcel $pPHPExcel = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // cp:coreProperties $objWriter->startElement('cp:coreProperties'); $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); // dc:creator $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); // cp:lastModifiedBy $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); // dcterms:created $objWriter->startElement('dcterms:created'); $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); $objWriter->endElement(); // dcterms:modified $objWriter->startElement('dcterms:modified'); $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); $objWriter->endElement(); // dc:title $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); // dc:description $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); // dc:subject $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); // cp:keywords $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); // cp:category $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write docProps/custom.xml to XML format * * @param PHPExcel $pPHPExcel * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) { $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); if (empty($customPropertyList)) { return; } // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // cp:coreProperties $objWriter->startElement('Properties'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); foreach ($customPropertyList as $key => $customProperty) { $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); $objWriter->startElement('property'); $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); $objWriter->writeAttribute('pid', $key+2); $objWriter->writeAttribute('name', $customProperty); switch ($propertyType) { case 'i': $objWriter->writeElement('vt:i4', $propertyValue); break; case 'f': $objWriter->writeElement('vt:r8', $propertyValue); break; case 'b': $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); break; case 'd': $objWriter->startElement('vt:filetime'); $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); $objWriter->endElement(); break; default: $objWriter->writeElement('vt:lpwstr', $propertyValue); break; } $objWriter->endElement(); } $objWriter->endElement(); return $objWriter->getData(); } } PK!CExcel2007/Worksheet.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Worksheet $objWriter->startElement('worksheet'); $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); // sheetPr $this->writeSheetPr($objWriter, $pSheet); // Dimension $this->writeDimension($objWriter, $pSheet); // sheetViews $this->writeSheetViews($objWriter, $pSheet); // sheetFormatPr $this->writeSheetFormatPr($objWriter, $pSheet); // cols $this->writeCols($objWriter, $pSheet); // sheetData $this->writeSheetData($objWriter, $pSheet, $pStringTable); // sheetProtection $this->writeSheetProtection($objWriter, $pSheet); // protectedRanges $this->writeProtectedRanges($objWriter, $pSheet); // autoFilter $this->writeAutoFilter($objWriter, $pSheet); // mergeCells $this->writeMergeCells($objWriter, $pSheet); // conditionalFormatting $this->writeConditionalFormatting($objWriter, $pSheet); // dataValidations $this->writeDataValidations($objWriter, $pSheet); // hyperlinks $this->writeHyperlinks($objWriter, $pSheet); // Print options $this->writePrintOptions($objWriter, $pSheet); // Page margins $this->writePageMargins($objWriter, $pSheet); // Page setup $this->writePageSetup($objWriter, $pSheet); // Header / footer $this->writeHeaderFooter($objWriter, $pSheet); // Breaks $this->writeBreaks($objWriter, $pSheet); // Drawings and/or Charts $this->writeDrawings($objWriter, $pSheet, $includeCharts); // LegacyDrawing $this->writeLegacyDrawing($objWriter, $pSheet); // LegacyDrawingHF $this->writeLegacyDrawingHF($objWriter, $pSheet); $objWriter->endElement(); // Return return $objWriter->getData(); } else { throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); } } /** * Write SheetPr * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetPr $objWriter->startElement('sheetPr'); //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); if ($pSheet->getParent()->hasMacros()) {//if the workbook have macros, we need to have codeName for the sheet if ($pSheet->hasCodeName()==false) { $pSheet->setCodeName($pSheet->getTitle()); } $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); } $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { $objWriter->writeAttribute('filterMode', 1); $pSheet->getAutoFilter()->showHideRows(); } // tabColor if ($pSheet->isTabColorSet()) { $objWriter->startElement('tabColor'); $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); $objWriter->endElement(); } // outlinePr $objWriter->startElement('outlinePr'); $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); $objWriter->endElement(); // pageSetUpPr if ($pSheet->getPageSetup()->getFitToPage()) { $objWriter->startElement('pageSetUpPr'); $objWriter->writeAttribute('fitToPage', '1'); $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Dimension * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // dimension $objWriter->startElement('dimension'); $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension()); $objWriter->endElement(); } /** * Write SheetViews * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetViews $objWriter->startElement('sheetViews'); // Sheet selected? $sheetSelected = false; if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) { $sheetSelected = true; } // sheetView $objWriter->startElement('sheetView'); $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); $objWriter->writeAttribute('workbookViewId', '0'); // Zoom scales if ($pSheet->getSheetView()->getZoomScale() != 100) { $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); } if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); } // View Layout Type if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); } // Gridlines if ($pSheet->getShowGridlines()) { $objWriter->writeAttribute('showGridLines', 'true'); } else { $objWriter->writeAttribute('showGridLines', 'false'); } // Row and column headers if ($pSheet->getShowRowColHeaders()) { $objWriter->writeAttribute('showRowColHeaders', '1'); } else { $objWriter->writeAttribute('showRowColHeaders', '0'); } // Right-to-left if ($pSheet->getRightToLeft()) { $objWriter->writeAttribute('rightToLeft', 'true'); } $activeCell = $pSheet->getActiveCell(); // Pane $pane = ''; $topLeftCell = $pSheet->getFreezePane(); if (($topLeftCell != '') && ($topLeftCell != 'A1')) { $activeCell = empty($activeCell) ? $topLeftCell : $activeCell; // Calculate freeze coordinates $xSplit = $ySplit = 0; list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); // pane $pane = 'topRight'; $objWriter->startElement('pane'); if ($xSplit > 1) { $objWriter->writeAttribute('xSplit', $xSplit - 1); } if ($ySplit > 1) { $objWriter->writeAttribute('ySplit', $ySplit - 1); $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; } $objWriter->writeAttribute('topLeftCell', $topLeftCell); $objWriter->writeAttribute('activePane', $pane); $objWriter->writeAttribute('state', 'frozen'); $objWriter->endElement(); if (($xSplit > 1) && ($ySplit > 1)) { // Write additional selections if more than two panes (ie both an X and a Y split) $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'topRight'); $objWriter->endElement(); $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'bottomLeft'); $objWriter->endElement(); } } // Selection // if ($pane != '') { // Only need to write selection element if we have a split pane // We cheat a little by over-riding the active cell selection, setting it to the split cell $objWriter->startElement('selection'); if ($pane != '') { $objWriter->writeAttribute('pane', $pane); } $objWriter->writeAttribute('activeCell', $activeCell); $objWriter->writeAttribute('sqref', $activeCell); $objWriter->endElement(); // } $objWriter->endElement(); $objWriter->endElement(); } /** * Write SheetFormatPr * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetFormatPr $objWriter->startElement('sheetFormatPr'); // Default row height if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { $objWriter->writeAttribute('customHeight', 'true'); $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); } else { $objWriter->writeAttribute('defaultRowHeight', '14.4'); } // Set Zero Height row if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' || strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') { $objWriter->writeAttribute('zeroHeight', '1'); } // Default column width if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); } // Outline level - row $outlineLevelRow = 0; foreach ($pSheet->getRowDimensions() as $dimension) { if ($dimension->getOutlineLevel() > $outlineLevelRow) { $outlineLevelRow = $dimension->getOutlineLevel(); } } $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); // Outline level - column $outlineLevelCol = 0; foreach ($pSheet->getColumnDimensions() as $dimension) { if ($dimension->getOutlineLevel() > $outlineLevelCol) { $outlineLevelCol = $dimension->getOutlineLevel(); } } $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); $objWriter->endElement(); } /** * Write Cols * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // cols if (count($pSheet->getColumnDimensions()) > 0) { $objWriter->startElement('cols'); $pSheet->calculateColumnWidths(); // Loop through column dimensions foreach ($pSheet->getColumnDimensions() as $colDimension) { // col $objWriter->startElement('col'); $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); if ($colDimension->getWidth() < 0) { // No width set, apply default of 10 $objWriter->writeAttribute('width', '9.10'); } else { // Width set $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); } // Column visibility if ($colDimension->getVisible() == false) { $objWriter->writeAttribute('hidden', 'true'); } // Auto size? if ($colDimension->getAutoSize()) { $objWriter->writeAttribute('bestFit', 'true'); } // Custom width? if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { $objWriter->writeAttribute('customWidth', 'true'); } // Collapsed if ($colDimension->getCollapsed() == true) { $objWriter->writeAttribute('collapsed', 'true'); } // Outline level if ($colDimension->getOutlineLevel() > 0) { $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); } // Style $objWriter->writeAttribute('style', $colDimension->getXfIndex()); $objWriter->endElement(); } $objWriter->endElement(); } } /** * Write SheetProtection * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetProtection $objWriter->startElement('sheetProtection'); if ($pSheet->getProtection()->getPassword() != '') { $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); } $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); $objWriter->endElement(); } /** * Write ConditionalFormatting * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Conditional id $id = 1; // Loop through styles in the current worksheet foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { // WHY was this again? // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') { // continue; // } if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) { // conditionalFormatting $objWriter->startElement('conditionalFormatting'); $objWriter->writeAttribute('sqref', $cellCoordinate); // cfRule $objWriter->startElement('cfRule'); $objWriter->writeAttribute('type', $conditional->getConditionType()); $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode())); $objWriter->writeAttribute('priority', $id++); if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { $objWriter->writeAttribute('operator', $conditional->getOperatorType()); } if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && !is_null($conditional->getText())) { $objWriter->writeAttribute('text', $conditional->getText()); } if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { foreach ($conditional->getConditions() as $formula) { // Formula $objWriter->writeElement('formula', $formula); } } $objWriter->endElement(); $objWriter->endElement(); } } } } /** * Write DataValidations * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Datavalidation collection $dataValidationCollection = $pSheet->getDataValidationCollection(); // Write data validations? if (!empty($dataValidationCollection)) { $objWriter->startElement('dataValidations'); $objWriter->writeAttribute('count', count($dataValidationCollection)); foreach ($dataValidationCollection as $coordinate => $dv) { $objWriter->startElement('dataValidation'); if ($dv->getType() != '') { $objWriter->writeAttribute('type', $dv->getType()); } if ($dv->getErrorStyle() != '') { $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle()); } if ($dv->getOperator() != '') { $objWriter->writeAttribute('operator', $dv->getOperator()); } $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); if ($dv->getErrorTitle() !== '') { $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); } if ($dv->getError() !== '') { $objWriter->writeAttribute('error', $dv->getError()); } if ($dv->getPromptTitle() !== '') { $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle()); } if ($dv->getPrompt() !== '') { $objWriter->writeAttribute('prompt', $dv->getPrompt()); } $objWriter->writeAttribute('sqref', $coordinate); if ($dv->getFormula1() !== '') { $objWriter->writeElement('formula1', $dv->getFormula1()); } if ($dv->getFormula2() !== '') { $objWriter->writeElement('formula2', $dv->getFormula2()); } $objWriter->endElement(); } $objWriter->endElement(); } } /** * Write Hyperlinks * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Hyperlink collection $hyperlinkCollection = $pSheet->getHyperlinkCollection(); // Relation ID $relationId = 1; // Write hyperlinks? if (!empty($hyperlinkCollection)) { $objWriter->startElement('hyperlinks'); foreach ($hyperlinkCollection as $coordinate => $hyperlink) { $objWriter->startElement('hyperlink'); $objWriter->writeAttribute('ref', $coordinate); if (!$hyperlink->isInternal()) { $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); ++$relationId; } else { $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); } if ($hyperlink->getTooltip() != '') { $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip()); } $objWriter->endElement(); } $objWriter->endElement(); } } /** * Write ProtectedRanges * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { if (count($pSheet->getProtectedCells()) > 0) { // protectedRanges $objWriter->startElement('protectedRanges'); // Loop protectedRanges foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { // protectedRange $objWriter->startElement('protectedRange'); $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); $objWriter->writeAttribute('sqref', $protectedCell); if (!empty($passwordHash)) { $objWriter->writeAttribute('password', $passwordHash); } $objWriter->endElement(); } $objWriter->endElement(); } } /** * Write MergeCells * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { if (count($pSheet->getMergeCells()) > 0) { // mergeCells $objWriter->startElement('mergeCells'); // Loop mergeCells foreach ($pSheet->getMergeCells() as $mergeCell) { // mergeCell $objWriter->startElement('mergeCell'); $objWriter->writeAttribute('ref', $mergeCell); $objWriter->endElement(); } $objWriter->endElement(); } } /** * Write PrintOptions * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // printOptions $objWriter->startElement('printOptions'); $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); $objWriter->writeAttribute('gridLinesSet', 'true'); if ($pSheet->getPageSetup()->getHorizontalCentered()) { $objWriter->writeAttribute('horizontalCentered', 'true'); } if ($pSheet->getPageSetup()->getVerticalCentered()) { $objWriter->writeAttribute('verticalCentered', 'true'); } $objWriter->endElement(); } /** * Write PageMargins * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // pageMargins $objWriter->startElement('pageMargins'); $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); $objWriter->endElement(); } /** * Write AutoFilter * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { // autoFilter $objWriter->startElement('autoFilter'); // Strip any worksheet reference from the filter coordinates $range = PHPExcel_Cell::splitRange($autoFilterRange); $range = $range[0]; // Strip any worksheet ref if (strpos($range[0], '!') !== false) { list($ws, $range[0]) = explode('!', $range[0]); } $range = implode(':', $range); $objWriter->writeAttribute('ref', str_replace('$', '', $range)); $columns = $pSheet->getAutoFilter()->getColumns(); if (count($columns > 0)) { foreach ($columns as $columnID => $column) { $rules = $column->getRules(); if (count($rules) > 0) { $objWriter->startElement('filterColumn'); $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); $objWriter->startElement($column->getFilterType()); if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { $objWriter->writeAttribute('and', 1); } foreach ($rules as $rule) { if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && ($rule->getValue() === '')) { // Filter rule for Blanks $objWriter->writeAttribute('blank', 1); } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { // Dynamic Filter Rule $objWriter->writeAttribute('type', $rule->getGrouping()); $val = $column->getAttribute('val'); if ($val !== null) { $objWriter->writeAttribute('val', $val); } $maxVal = $column->getAttribute('maxVal'); if ($maxVal !== null) { $objWriter->writeAttribute('maxVal', $maxVal); } } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { // Top 10 Filter Rule $objWriter->writeAttribute('val', $rule->getValue()); $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); } else { // Filter, DateGroupItem or CustomFilter $objWriter->startElement($rule->getRuleType()); if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { $objWriter->writeAttribute('operator', $rule->getOperator()); } if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { // Date Group filters foreach ($rule->getValue() as $key => $value) { if ($value > '') { $objWriter->writeAttribute($key, $value); } } $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); } else { $objWriter->writeAttribute('val', $rule->getValue()); } $objWriter->endElement(); } } $objWriter->endElement(); $objWriter->endElement(); } } } $objWriter->endElement(); } } /** * Write PageSetup * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // pageSetup $objWriter->startElement('pageSetup'); $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); if (!is_null($pSheet->getPageSetup()->getScale())) { $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); } if (!is_null($pSheet->getPageSetup()->getFitToHeight())) { $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); } else { $objWriter->writeAttribute('fitToHeight', '0'); } if (!is_null($pSheet->getPageSetup()->getFitToWidth())) { $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); } else { $objWriter->writeAttribute('fitToWidth', '0'); } if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) { $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); $objWriter->writeAttribute('useFirstPageNumber', '1'); } $objWriter->endElement(); } /** * Write Header / Footer * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // headerFooter $objWriter->startElement('headerFooter'); $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); $objWriter->endElement(); } /** * Write Breaks * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Get row and column breaks $aRowBreaks = array(); $aColumnBreaks = array(); foreach ($pSheet->getBreaks() as $cell => $breakType) { if ($breakType == PHPExcel_Worksheet::BREAK_ROW) { $aRowBreaks[] = $cell; } elseif ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { $aColumnBreaks[] = $cell; } } // rowBreaks if (!empty($aRowBreaks)) { $objWriter->startElement('rowBreaks'); $objWriter->writeAttribute('count', count($aRowBreaks)); $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); foreach ($aRowBreaks as $cell) { $coords = PHPExcel_Cell::coordinateFromString($cell); $objWriter->startElement('brk'); $objWriter->writeAttribute('id', $coords[1]); $objWriter->writeAttribute('man', '1'); $objWriter->endElement(); } $objWriter->endElement(); } // Second, write column breaks if (!empty($aColumnBreaks)) { $objWriter->startElement('colBreaks'); $objWriter->writeAttribute('count', count($aColumnBreaks)); $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); foreach ($aColumnBreaks as $cell) { $coords = PHPExcel_Cell::coordinateFromString($cell); $objWriter->startElement('brk'); $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); $objWriter->writeAttribute('man', '1'); $objWriter->endElement(); } $objWriter->endElement(); } } /** * Write SheetData * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @param string[] $pStringTable String table * @throws PHPExcel_Writer_Exception */ private function writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) { if (is_array($pStringTable)) { // Flipped stringtable, for faster index searching $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable); // sheetData $objWriter->startElement('sheetData'); // Get column count $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); // Highest row number $highestRow = $pSheet->getHighestRow(); // Loop through cells $cellsByRow = array(); foreach ($pSheet->getCellCollection() as $cellID) { $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); $cellsByRow[$cellAddress[1]][] = $cellID; } $currentRow = 0; while ($currentRow++ < $highestRow) { // Get row dimension $rowDimension = $pSheet->getRowDimension($currentRow); // Write current row? $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null; if ($writeCurrentRow) { // Start a new row $objWriter->startElement('row'); $objWriter->writeAttribute('r', $currentRow); $objWriter->writeAttribute('spans', '1:' . $colCount); // Row dimensions if ($rowDimension->getRowHeight() >= 0) { $objWriter->writeAttribute('customHeight', '1'); $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); } // Row visibility if ($rowDimension->getVisible() == false) { $objWriter->writeAttribute('hidden', 'true'); } // Collapsed if ($rowDimension->getCollapsed() == true) { $objWriter->writeAttribute('collapsed', 'true'); } // Outline level if ($rowDimension->getOutlineLevel() > 0) { $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); } // Style if ($rowDimension->getXfIndex() !== null) { $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); $objWriter->writeAttribute('customFormat', '1'); } // Write cells if (isset($cellsByRow[$currentRow])) { foreach ($cellsByRow[$currentRow] as $cellAddress) { // Write cell $this->writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); } } // End row $objWriter->endElement(); } } $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } /** * Write Cell * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @param PHPExcel_Cell $pCellAddress Cell Address * @param string[] $pStringTable String table * @param string[] $pFlippedStringTable String table (flipped), for faster index searching * @throws PHPExcel_Writer_Exception */ private function writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) { if (is_array($pStringTable) && is_array($pFlippedStringTable)) { // Cell $pCell = $pSheet->getCell($pCellAddress); $objWriter->startElement('c'); $objWriter->writeAttribute('r', $pCellAddress); // Sheet styles if ($pCell->getXfIndex() != '') { $objWriter->writeAttribute('s', $pCell->getXfIndex()); } // If cell value is supplied, write cell value $cellValue = $pCell->getValue(); if (is_object($cellValue) || $cellValue !== '') { // Map type $mappedType = $pCell->getDataType(); // Write data type depending on its type switch (strtolower($mappedType)) { case 'inlinestr': // Inline string case 's': // String case 'b': // Boolean $objWriter->writeAttribute('t', $mappedType); break; case 'f': // Formula $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ? $pCell->getCalculatedValue() : $cellValue; if (is_string($calculatedValue)) { $objWriter->writeAttribute('t', 'str'); } break; case 'e': // Error $objWriter->writeAttribute('t', $mappedType); } // Write data depending on its type switch (strtolower($mappedType)) { case 'inlinestr': // Inline string if (! $cellValue instanceof PHPExcel_RichText) { $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML(htmlspecialchars($cellValue))); } elseif ($cellValue instanceof PHPExcel_RichText) { $objWriter->startElement('is'); $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); $objWriter->endElement(); } break; case 's': // String if (! $cellValue instanceof PHPExcel_RichText) { if (isset($pFlippedStringTable[$cellValue])) { $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]); } } elseif ($cellValue instanceof PHPExcel_RichText) { $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]); } break; case 'f': // Formula $attributes = $pCell->getFormulaAttributes(); if ($attributes['t'] == 'array') { $objWriter->startElement('f'); $objWriter->writeAttribute('t', 'array'); $objWriter->writeAttribute('ref', $pCellAddress); $objWriter->writeAttribute('aca', '1'); $objWriter->writeAttribute('ca', '1'); $objWriter->text(substr($cellValue, 1)); $objWriter->endElement(); } else { $objWriter->writeElement('f', substr($cellValue, 1)); } if ($this->getParentWriter()->getOffice2003Compatibility() === false) { if ($this->getParentWriter()->getPreCalculateFormulas()) { // $calculatedValue = $pCell->getCalculatedValue(); if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') { $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue)); } else { $objWriter->writeElement('v', '0'); } } else { $objWriter->writeElement('v', '0'); } } break; case 'n': // Numeric // force point as decimal separator in case current locale uses comma $objWriter->writeElement('v', str_replace(',', '.', $cellValue)); break; case 'b': // Boolean $objWriter->writeElement('v', ($cellValue ? '1' : '0')); break; case 'e': // Error if (substr($cellValue, 0, 1) == '=') { $objWriter->writeElement('f', substr($cellValue, 1)); $objWriter->writeElement('v', substr($cellValue, 1)); } else { $objWriter->writeElement('v', $cellValue); } break; } } $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } /** * Write Drawings * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @param boolean $includeCharts Flag indicating if we should include drawing details for charts * @throws PHPExcel_Writer_Exception */ private function writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = false) { $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; // If sheet contains drawings, add the relationships if (($pSheet->getDrawingCollection()->count() > 0) || ($chartCount > 0)) { $objWriter->startElement('drawing'); $objWriter->writeAttribute('r:id', 'rId1'); $objWriter->endElement(); } } /** * Write LegacyDrawing * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // If sheet contains comments, add the relationships if (count($pSheet->getComments()) > 0) { $objWriter->startElement('legacyDrawing'); $objWriter->writeAttribute('r:id', 'rId_comments_vml1'); $objWriter->endElement(); } } /** * Write LegacyDrawingHF * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // If sheet contains images, add the relationships if (count($pSheet->getHeaderFooter()->getImages()) > 0) { $objWriter->startElement('legacyDrawingHF'); $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1'); $objWriter->endElement(); } } } PK!&Excel2007/Chart.phpnu[calculateCellValues = $calculateCellValues; // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // Ensure that data series values are up-to-date before we save if ($this->calculateCellValues) { $pChart->refresh(); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // c:chartSpace $objWriter->startElement('c:chartSpace'); $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $objWriter->startElement('c:date1904'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->startElement('c:lang'); $objWriter->writeAttribute('val', "en-GB"); $objWriter->endElement(); $objWriter->startElement('c:roundedCorners'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $this->writeAlternateContent($objWriter); $objWriter->startElement('c:chart'); $this->writeTitle($pChart->getTitle(), $objWriter); $objWriter->startElement('c:autoTitleDeleted'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $this->writePlotArea($pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $objWriter, $pChart->getWorksheet(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines()); $this->writeLegend($pChart->getLegend(), $objWriter); $objWriter->startElement('c:plotVisOnly'); $objWriter->writeAttribute('val', 1); $objWriter->endElement(); $objWriter->startElement('c:dispBlanksAs'); $objWriter->writeAttribute('val', "gap"); $objWriter->endElement(); $objWriter->startElement('c:showDLblsOverMax'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->endElement(); $this->writePrintSettings($objWriter); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write Chart Title * * @param PHPExcel_Chart_Title $title * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) { if (is_null($title)) { return; } $objWriter->startElement('c:title'); $objWriter->startElement('c:tx'); $objWriter->startElement('c:rich'); $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p'); $caption = $title->getCaption(); if ((is_array($caption)) && (count($caption) > 0)) { $caption = $caption[0]; } $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $this->writeLayout($title->getLayout(), $objWriter); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Chart Legend * * @param PHPExcel_Chart_Legend $legend * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) { if (is_null($legend)) { return; } $objWriter->startElement('c:legend'); $objWriter->startElement('c:legendPos'); $objWriter->writeAttribute('val', $legend->getPosition()); $objWriter->endElement(); $this->writeLayout($legend->getLayout(), $objWriter); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); $objWriter->endElement(); $objWriter->startElement('c:txPr'); $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p'); $objWriter->startElement('a:pPr'); $objWriter->writeAttribute('rtl', 0); $objWriter->startElement('a:defRPr'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('a:endParaRPr'); $objWriter->writeAttribute('lang', "en-US"); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Chart Plot Area * * @param PHPExcel_Chart_PlotArea $plotArea * @param PHPExcel_Chart_Title $xAxisLabel * @param PHPExcel_Chart_Title $yAxisLabel * @param PHPExcel_Chart_Axis $xAxis * @param PHPExcel_Chart_Axis $yAxis * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines) { if (is_null($plotArea)) { return; } $id1 = $id2 = 0; $this->_seriesIndex = 0; $objWriter->startElement('c:plotArea'); $layout = $plotArea->getLayout(); $this->writeLayout($layout, $objWriter); $chartTypes = self::getChartType($plotArea); $catIsMultiLevelSeries = $valIsMultiLevelSeries = false; $plotGroupingType = ''; foreach ($chartTypes as $chartType) { $objWriter->startElement('c:' . $chartType); $groupCount = $plotArea->getPlotGroupCount(); for ($i = 0; $i < $groupCount; ++$i) { $plotGroup = $plotArea->getPlotGroupByIndex($i); $groupType = $plotGroup->getPlotType(); if ($groupType == $chartType) { $plotStyle = $plotGroup->getPlotStyle(); if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { $objWriter->startElement('c:radarStyle'); $objWriter->writeAttribute('val', $plotStyle); $objWriter->endElement(); } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { $objWriter->startElement('c:scatterStyle'); $objWriter->writeAttribute('val', $plotStyle); $objWriter->endElement(); } $this->writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); } } $this->writeDataLabels($objWriter, $layout); if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { // Line only, Line3D can't be smoothed $objWriter->startElement('c:smooth'); $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine()); $objWriter->endElement(); } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) ||($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { $objWriter->startElement('c:gapWidth'); $objWriter->writeAttribute('val', 150); $objWriter->endElement(); if ($plotGroupingType == 'percentStacked' || $plotGroupingType == 'stacked') { $objWriter->startElement('c:overlap'); $objWriter->writeAttribute('val', 100); $objWriter->endElement(); } } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { $objWriter->startElement('c:bubbleScale'); $objWriter->writeAttribute('val', 25); $objWriter->endElement(); $objWriter->startElement('c:showNegBubbles'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { $objWriter->startElement('c:hiLowLines'); $objWriter->endElement(); $objWriter->startElement('c:upDownBars'); $objWriter->startElement('c:gapWidth'); $objWriter->writeAttribute('val', 300); $objWriter->endElement(); $objWriter->startElement('c:upBars'); $objWriter->endElement(); $objWriter->startElement('c:downBars'); $objWriter->endElement(); $objWriter->endElement(); } // Generate 2 unique numbers to use for axId values // $id1 = $id2 = rand(10000000,99999999); // do { // $id2 = rand(10000000,99999999); // } while ($id1 == $id2); $id1 = '75091328'; $id2 = '75089408'; if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { $objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id1); $objWriter->endElement(); $objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id2); $objWriter->endElement(); } else { $objWriter->startElement('c:firstSliceAng'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { $objWriter->startElement('c:holeSize'); $objWriter->writeAttribute('val', 50); $objWriter->endElement(); } } $objWriter->endElement(); } if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { $this->writeValueAxis($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); } else { $this->writeCategoryAxis($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis); } $this->writeValueAxis($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); } $objWriter->endElement(); } /** * Write Data Labels * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Chart_Layout $chartLayout Chart layout * * @throws PHPExcel_Writer_Exception */ private function writeDataLabels($objWriter, $chartLayout) { $objWriter->startElement('c:dLbls'); $objWriter->startElement('c:showLegendKey'); $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1)); $objWriter->endElement(); $objWriter->startElement('c:showVal'); $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1)); $objWriter->endElement(); $objWriter->startElement('c:showCatName'); $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1)); $objWriter->endElement(); $objWriter->startElement('c:showSerName'); $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1)); $objWriter->endElement(); $objWriter->startElement('c:showPercent'); $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1)); $objWriter->endElement(); $objWriter->startElement('c:showBubbleSize'); $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1)); $objWriter->endElement(); $objWriter->startElement('c:showLeaderLines'); $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1)); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Category Axis * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Chart_PlotArea $plotArea * @param PHPExcel_Chart_Title $xAxisLabel * @param string $groupType Chart type * @param string $id1 * @param string $id2 * @param boolean $isMultiLevelSeries * * @throws PHPExcel_Writer_Exception */ private function writeCategoryAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) { $objWriter->startElement('c:catAx'); if ($id1 > 0) { $objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id1); $objWriter->endElement(); } $objWriter->startElement('c:scaling'); $objWriter->startElement('c:orientation'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation')); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('c:delete'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->startElement('c:axPos'); $objWriter->writeAttribute('val', "b"); $objWriter->endElement(); if (!is_null($xAxisLabel)) { $objWriter->startElement('c:title'); $objWriter->startElement('c:tx'); $objWriter->startElement('c:rich'); $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p'); $objWriter->startElement('a:r'); $caption = $xAxisLabel->getCaption(); if (is_array($caption)) { $caption = $caption[0]; } $objWriter->startElement('a:t'); // $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $layout = $xAxisLabel->getLayout(); $this->writeLayout($layout, $objWriter); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->endElement(); } $objWriter->startElement('c:numFmt'); $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat()); $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked()); $objWriter->endElement(); $objWriter->startElement('c:majorTickMark'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark')); $objWriter->endElement(); $objWriter->startElement('c:minorTickMark'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark')); $objWriter->endElement(); $objWriter->startElement('c:tickLblPos'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels')); $objWriter->endElement(); if ($id2 > 0) { $objWriter->startElement('c:crossAx'); $objWriter->writeAttribute('val', $id2); $objWriter->endElement(); $objWriter->startElement('c:crosses'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses')); $objWriter->endElement(); } $objWriter->startElement('c:auto'); $objWriter->writeAttribute('val', 1); $objWriter->endElement(); $objWriter->startElement('c:lblAlgn'); $objWriter->writeAttribute('val', "ctr"); $objWriter->endElement(); $objWriter->startElement('c:lblOffset'); $objWriter->writeAttribute('val', 100); $objWriter->endElement(); if ($isMultiLevelSeries) { $objWriter->startElement('c:noMultiLvlLbl'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Value Axis * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Chart_PlotArea $plotArea * @param PHPExcel_Chart_Title $yAxisLabel * @param string $groupType Chart type * @param string $id1 * @param string $id2 * @param boolean $isMultiLevelSeries * * @throws PHPExcel_Writer_Exception */ private function writeValueAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) { $objWriter->startElement('c:valAx'); if ($id2 > 0) { $objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id2); $objWriter->endElement(); } $objWriter->startElement('c:scaling'); if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) { $objWriter->startElement('c:max'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum')); $objWriter->endElement(); } if (!is_null($xAxis->getAxisOptionsProperty('minimum'))) { $objWriter->startElement('c:min'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum')); $objWriter->endElement(); } $objWriter->startElement('c:orientation'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation')); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('c:delete'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->startElement('c:axPos'); $objWriter->writeAttribute('val', "l"); $objWriter->endElement(); $objWriter->startElement('c:majorGridlines'); $objWriter->startElement('c:spPr'); if (!is_null($majorGridlines->getLineColorProperty('value'))) { $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width')); $objWriter->startElement('a:solidFill'); $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}"); $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value')); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha')); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end srgbClr $objWriter->endElement(); //end solidFill $objWriter->startElement('a:prstDash'); $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash')); $objWriter->endElement(); if ($majorGridlines->getLineStyleProperty('join') == 'miter') { $objWriter->startElement('a:miter'); $objWriter->writeAttribute('lim', '800000'); $objWriter->endElement(); } else { $objWriter->startElement('a:bevel'); $objWriter->endElement(); } if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { $objWriter->startElement('a:headEnd'); $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w')); $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len')); $objWriter->endElement(); } if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { $objWriter->startElement('a:tailEnd'); $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w')); $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len')); $objWriter->endElement(); } $objWriter->endElement(); //end ln } $objWriter->startElement('a:effectLst'); if (!is_null($majorGridlines->getGlowSize())) { $objWriter->startElement('a:glow'); $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize()); $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}"); $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value')); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha')); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end schemeClr $objWriter->endElement(); //end glow } if (!is_null($majorGridlines->getShadowProperty('presets'))) { $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}"); if (!is_null($majorGridlines->getShadowProperty('blur'))) { $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur')); } if (!is_null($majorGridlines->getShadowProperty('distance'))) { $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance')); } if (!is_null($majorGridlines->getShadowProperty('direction'))) { $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction')); } if (!is_null($majorGridlines->getShadowProperty('algn'))) { $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn')); } if (!is_null($majorGridlines->getShadowProperty(array('size', 'sx')))) { $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(array('size', 'sx'))); } if (!is_null($majorGridlines->getShadowProperty(array('size', 'sy')))) { $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(array('size', 'sy'))); } if (!is_null($majorGridlines->getShadowProperty(array('size', 'kx')))) { $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(array('size', 'kx'))); } if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) { $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape')); } $objWriter->startElement("a:{$majorGridlines->getShadowProperty(array('color', 'type'))}"); $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'value'))); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'alpha'))); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end color:type $objWriter->endElement(); //end shadow } if (!is_null($majorGridlines->getSoftEdgesSize())) { $objWriter->startElement('a:softEdge'); $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize()); $objWriter->endElement(); //end softEdge } $objWriter->endElement(); //end effectLst $objWriter->endElement(); //end spPr $objWriter->endElement(); //end majorGridLines if ($minorGridlines->getObjectState()) { $objWriter->startElement('c:minorGridlines'); $objWriter->startElement('c:spPr'); if (!is_null($minorGridlines->getLineColorProperty('value'))) { $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width')); $objWriter->startElement('a:solidFill'); $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}"); $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value')); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha')); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end srgbClr $objWriter->endElement(); //end solidFill $objWriter->startElement('a:prstDash'); $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash')); $objWriter->endElement(); if ($minorGridlines->getLineStyleProperty('join') == 'miter') { $objWriter->startElement('a:miter'); $objWriter->writeAttribute('lim', '800000'); $objWriter->endElement(); } else { $objWriter->startElement('a:bevel'); $objWriter->endElement(); } if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { $objWriter->startElement('a:headEnd'); $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w')); $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len')); $objWriter->endElement(); } if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { $objWriter->startElement('a:tailEnd'); $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w')); $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len')); $objWriter->endElement(); } $objWriter->endElement(); //end ln } $objWriter->startElement('a:effectLst'); if (!is_null($minorGridlines->getGlowSize())) { $objWriter->startElement('a:glow'); $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize()); $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}"); $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value')); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha')); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end schemeClr $objWriter->endElement(); //end glow } if (!is_null($minorGridlines->getShadowProperty('presets'))) { $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}"); if (!is_null($minorGridlines->getShadowProperty('blur'))) { $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur')); } if (!is_null($minorGridlines->getShadowProperty('distance'))) { $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance')); } if (!is_null($minorGridlines->getShadowProperty('direction'))) { $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction')); } if (!is_null($minorGridlines->getShadowProperty('algn'))) { $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn')); } if (!is_null($minorGridlines->getShadowProperty(array('size', 'sx')))) { $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(array('size', 'sx'))); } if (!is_null($minorGridlines->getShadowProperty(array('size', 'sy')))) { $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(array('size', 'sy'))); } if (!is_null($minorGridlines->getShadowProperty(array('size', 'kx')))) { $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(array('size', 'kx'))); } if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) { $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape')); } $objWriter->startElement("a:{$minorGridlines->getShadowProperty(array('color', 'type'))}"); $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'value'))); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'alpha'))); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end color:type $objWriter->endElement(); //end shadow } if (!is_null($minorGridlines->getSoftEdgesSize())) { $objWriter->startElement('a:softEdge'); $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize()); $objWriter->endElement(); //end softEdge } $objWriter->endElement(); //end effectLst $objWriter->endElement(); //end spPr $objWriter->endElement(); //end minorGridLines } if (!is_null($yAxisLabel)) { $objWriter->startElement('c:title'); $objWriter->startElement('c:tx'); $objWriter->startElement('c:rich'); $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p'); $objWriter->startElement('a:r'); $caption = $yAxisLabel->getCaption(); if (is_array($caption)) { $caption = $caption[0]; } $objWriter->startElement('a:t'); // $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { $layout = $yAxisLabel->getLayout(); $this->writeLayout($layout, $objWriter); } $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->endElement(); } $objWriter->startElement('c:numFmt'); $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat()); $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked()); $objWriter->endElement(); $objWriter->startElement('c:majorTickMark'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark')); $objWriter->endElement(); $objWriter->startElement('c:minorTickMark'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark')); $objWriter->endElement(); $objWriter->startElement('c:tickLblPos'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels')); $objWriter->endElement(); $objWriter->startElement('c:spPr'); if (!is_null($xAxis->getFillProperty('value'))) { $objWriter->startElement('a:solidFill'); $objWriter->startElement("a:" . $xAxis->getFillProperty('type')); $objWriter->writeAttribute('val', $xAxis->getFillProperty('value')); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha')); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width')); $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap')); $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound')); if (!is_null($xAxis->getLineProperty('value'))) { $objWriter->startElement('a:solidFill'); $objWriter->startElement("a:" . $xAxis->getLineProperty('type')); $objWriter->writeAttribute('val', $xAxis->getLineProperty('value')); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha')); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } $objWriter->startElement('a:prstDash'); $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash')); $objWriter->endElement(); if ($xAxis->getLineStyleProperty('join') == 'miter') { $objWriter->startElement('a:miter'); $objWriter->writeAttribute('lim', '800000'); $objWriter->endElement(); } else { $objWriter->startElement('a:bevel'); $objWriter->endElement(); } if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'head', 'type')))) { $objWriter->startElement('a:headEnd'); $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'head', 'type'))); $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head')); $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head')); $objWriter->endElement(); } if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'end', 'type')))) { $objWriter->startElement('a:tailEnd'); $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'end', 'type'))); $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end')); $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end')); $objWriter->endElement(); } $objWriter->endElement(); $objWriter->startElement('a:effectLst'); if (!is_null($xAxis->getGlowProperty('size'))) { $objWriter->startElement('a:glow'); $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size')); $objWriter->startElement("a:{$xAxis->getGlowProperty(array('color','type'))}"); $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','value'))); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','alpha'))); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } if (!is_null($xAxis->getShadowProperty('presets'))) { $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}"); if (!is_null($xAxis->getShadowProperty('blur'))) { $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur')); } if (!is_null($xAxis->getShadowProperty('distance'))) { $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance')); } if (!is_null($xAxis->getShadowProperty('direction'))) { $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction')); } if (!is_null($xAxis->getShadowProperty('algn'))) { $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); } if (!is_null($xAxis->getShadowProperty(array('size','sx')))) { $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(array('size','sx'))); } if (!is_null($xAxis->getShadowProperty(array('size','sy')))) { $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(array('size','sy'))); } if (!is_null($xAxis->getShadowProperty(array('size','kx')))) { $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(array('size','kx'))); } if (!is_null($xAxis->getShadowProperty('rotWithShape'))) { $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); } $objWriter->startElement("a:{$xAxis->getShadowProperty(array('color','type'))}"); $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','value'))); $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','alpha'))); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } if (!is_null($xAxis->getSoftEdgesSize())) { $objWriter->startElement('a:softEdge'); $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize()); $objWriter->endElement(); } $objWriter->endElement(); //effectList $objWriter->endElement(); //end spPr if ($id1 > 0) { $objWriter->startElement('c:crossAx'); $objWriter->writeAttribute('val', $id2); $objWriter->endElement(); if (!is_null($xAxis->getAxisOptionsProperty('horizontal_crosses_value'))) { $objWriter->startElement('c:crossesAt'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value')); $objWriter->endElement(); } else { $objWriter->startElement('c:crosses'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses')); $objWriter->endElement(); } $objWriter->startElement('c:crossBetween'); $objWriter->writeAttribute('val', "midCat"); $objWriter->endElement(); if (!is_null($xAxis->getAxisOptionsProperty('major_unit'))) { $objWriter->startElement('c:majorUnit'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit')); $objWriter->endElement(); } if (!is_null($xAxis->getAxisOptionsProperty('minor_unit'))) { $objWriter->startElement('c:minorUnit'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit')); $objWriter->endElement(); } } if ($isMultiLevelSeries) { if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { $objWriter->startElement('c:noMultiLvlLbl'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); } } $objWriter->endElement(); } /** * Get the data series type(s) for a chart plot series * * @param PHPExcel_Chart_PlotArea $plotArea * * @return string|array * @throws PHPExcel_Writer_Exception */ private static function getChartType($plotArea) { $groupCount = $plotArea->getPlotGroupCount(); if ($groupCount == 1) { $chartType = array($plotArea->getPlotGroupByIndex(0)->getPlotType()); } else { $chartTypes = array(); for ($i = 0; $i < $groupCount; ++$i) { $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType(); } $chartType = array_unique($chartTypes); if (count($chartTypes) == 0) { throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); } } return $chartType; } /** * Write Plot Group (series of related plots) * * @param PHPExcel_Chart_DataSeries $plotGroup * @param string $groupType Type of plot for dataseries * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param boolean &$catIsMultiLevelSeries Is category a multi-series category * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set * @param string &$plotGroupingType Type of grouping for multi-series values * @param PHPExcel_Worksheet $pSheet * * @throws PHPExcel_Writer_Exception */ private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet) { if (is_null($plotGroup)) { return; } if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { $objWriter->startElement('c:barDir'); $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); $objWriter->endElement(); } if (!is_null($plotGroup->getPlotGrouping())) { $plotGroupingType = $plotGroup->getPlotGrouping(); $objWriter->startElement('c:grouping'); $objWriter->writeAttribute('val', $plotGroupingType); $objWriter->endElement(); } // Get these details before the loop, because we can use the count to check for varyColors $plotSeriesOrder = $plotGroup->getPlotOrder(); $plotSeriesCount = count($plotSeriesOrder); if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || ($plotSeriesCount > 1)) { $objWriter->startElement('c:varyColors'); $objWriter->writeAttribute('val', 1); $objWriter->endElement(); } else { $objWriter->startElement('c:varyColors'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); } } } foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { $objWriter->startElement('c:ser'); $objWriter->startElement('c:idx'); $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); $objWriter->endElement(); $objWriter->startElement('c:order'); $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); $objWriter->endElement(); if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { $objWriter->startElement('c:dPt'); $objWriter->startElement('c:idx'); $objWriter->writeAttribute('val', 3); $objWriter->endElement(); $objWriter->startElement('c:bubble3D'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); $objWriter->startElement('c:spPr'); $objWriter->startElement('a:solidFill'); $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', 'FF9900'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } // Labels $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { $objWriter->startElement('c:tx'); $objWriter->startElement('c:strRef'); $this->writePlotSeriesLabel($plotSeriesLabel, $objWriter); $objWriter->endElement(); $objWriter->endElement(); } // Formatting for the points if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { $objWriter->startElement('c:spPr'); $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', 12700); if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { $objWriter->startElement('a:noFill'); $objWriter->endElement(); } $objWriter->endElement(); $objWriter->endElement(); } $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); if ($plotSeriesValues) { $plotSeriesMarker = $plotSeriesValues->getPointMarker(); if ($plotSeriesMarker) { $objWriter->startElement('c:marker'); $objWriter->startElement('c:symbol'); $objWriter->writeAttribute('val', $plotSeriesMarker); $objWriter->endElement(); if ($plotSeriesMarker !== 'none') { $objWriter->startElement('c:size'); $objWriter->writeAttribute('val', 3); $objWriter->endElement(); } $objWriter->endElement(); } } if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)) { $objWriter->startElement('c:invertIfNegative'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); } // Category Labels $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { if (!is_null($plotGroup->getPlotStyle())) { $plotStyle = $plotGroup->getPlotStyle(); if ($plotStyle) { $objWriter->startElement('c:explosion'); $objWriter->writeAttribute('val', 25); $objWriter->endElement(); } } } if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { $objWriter->startElement('c:xVal'); } else { $objWriter->startElement('c:cat'); } $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); $objWriter->endElement(); } // Values if ($plotSeriesValues) { $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { $objWriter->startElement('c:yVal'); } else { $objWriter->startElement('c:val'); } $this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); $objWriter->endElement(); } if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { $this->writeBubbles($plotSeriesValues, $objWriter, $pSheet); } $objWriter->endElement(); } $this->_seriesIndex += $plotSeriesIdx + 1; } /** * Write Plot Series Label * * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writePlotSeriesLabel($plotSeriesLabel, $objWriter) { if (is_null($plotSeriesLabel)) { return; } $objWriter->startElement('c:f'); $objWriter->writeRawData($plotSeriesLabel->getDataSource()); $objWriter->endElement(); $objWriter->startElement('c:strCache'); $objWriter->startElement('c:ptCount'); $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount()); $objWriter->endElement(); foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotLabelKey); $objWriter->startElement('c:v'); $objWriter->writeRawData($plotLabelValue); $objWriter->endElement(); $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Plot Series Values * * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $groupType Type of plot for dataseries * @param string $dataType Datatype of series values * @param PHPExcel_Worksheet $pSheet * * @throws PHPExcel_Writer_Exception */ private function writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet) { if (is_null($plotSeriesValues)) { return; } if ($plotSeriesValues->isMultiLevelSeries()) { $levelCount = $plotSeriesValues->multiLevelCount(); $objWriter->startElement('c:multiLvlStrRef'); $objWriter->startElement('c:f'); $objWriter->writeRawData($plotSeriesValues->getDataSource()); $objWriter->endElement(); $objWriter->startElement('c:multiLvlStrCache'); $objWriter->startElement('c:ptCount'); $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); $objWriter->endElement(); for ($level = 0; $level < $levelCount; ++$level) { $objWriter->startElement('c:lvl'); foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { if (isset($plotSeriesValue[$level])) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); $objWriter->startElement('c:v'); $objWriter->writeRawData($plotSeriesValue[$level]); $objWriter->endElement(); $objWriter->endElement(); } } $objWriter->endElement(); } $objWriter->endElement(); $objWriter->endElement(); } else { $objWriter->startElement('c:' . $dataType . 'Ref'); $objWriter->startElement('c:f'); $objWriter->writeRawData($plotSeriesValues->getDataSource()); $objWriter->endElement(); $objWriter->startElement('c:' . $dataType . 'Cache'); if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { if (($plotSeriesValues->getFormatCode() !== null) && ($plotSeriesValues->getFormatCode() !== '')) { $objWriter->startElement('c:formatCode'); $objWriter->writeRawData($plotSeriesValues->getFormatCode()); $objWriter->endElement(); } } $objWriter->startElement('c:ptCount'); $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); $objWriter->endElement(); $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { if (is_array($dataValues)) { foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); $objWriter->startElement('c:v'); $objWriter->writeRawData($plotSeriesValue); $objWriter->endElement(); $objWriter->endElement(); } } } $objWriter->endElement(); $objWriter->endElement(); } } /** * Write Bubble Chart Details * * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { if (is_null($plotSeriesValues)) { return; } $objWriter->startElement('c:bubbleSize'); $objWriter->startElement('c:numLit'); $objWriter->startElement('c:formatCode'); $objWriter->writeRawData('General'); $objWriter->endElement(); $objWriter->startElement('c:ptCount'); $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); $objWriter->endElement(); $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) { if (is_array($dataValues)) { foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); $objWriter->startElement('c:v'); $objWriter->writeRawData(1); $objWriter->endElement(); $objWriter->endElement(); } } } $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('c:bubble3D'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); } /** * Write Layout * * @param PHPExcel_Chart_Layout $layout * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) { $objWriter->startElement('c:layout'); if (!is_null($layout)) { $objWriter->startElement('c:manualLayout'); $layoutTarget = $layout->getLayoutTarget(); if (!is_null($layoutTarget)) { $objWriter->startElement('c:layoutTarget'); $objWriter->writeAttribute('val', $layoutTarget); $objWriter->endElement(); } $xMode = $layout->getXMode(); if (!is_null($xMode)) { $objWriter->startElement('c:xMode'); $objWriter->writeAttribute('val', $xMode); $objWriter->endElement(); } $yMode = $layout->getYMode(); if (!is_null($yMode)) { $objWriter->startElement('c:yMode'); $objWriter->writeAttribute('val', $yMode); $objWriter->endElement(); } $x = $layout->getXPosition(); if (!is_null($x)) { $objWriter->startElement('c:x'); $objWriter->writeAttribute('val', $x); $objWriter->endElement(); } $y = $layout->getYPosition(); if (!is_null($y)) { $objWriter->startElement('c:y'); $objWriter->writeAttribute('val', $y); $objWriter->endElement(); } $w = $layout->getWidth(); if (!is_null($w)) { $objWriter->startElement('c:w'); $objWriter->writeAttribute('val', $w); $objWriter->endElement(); } $h = $layout->getHeight(); if (!is_null($h)) { $objWriter->startElement('c:h'); $objWriter->writeAttribute('val', $h); $objWriter->endElement(); } $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Alternate Content block * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writeAlternateContent($objWriter) { $objWriter->startElement('mc:AlternateContent'); $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); $objWriter->startElement('mc:Choice'); $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); $objWriter->writeAttribute('Requires', 'c14'); $objWriter->startElement('c14:style'); $objWriter->writeAttribute('val', '102'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('mc:Fallback'); $objWriter->startElement('c:style'); $objWriter->writeAttribute('val', '2'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Printer Settings * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * * @throws PHPExcel_Writer_Exception */ private function writePrintSettings($objWriter) { $objWriter->startElement('c:printSettings'); $objWriter->startElement('c:headerFooter'); $objWriter->endElement(); $objWriter->startElement('c:pageMargins'); $objWriter->writeAttribute('footer', 0.3); $objWriter->writeAttribute('header', 0.3); $objWriter->writeAttribute('r', 0.7); $objWriter->writeAttribute('l', 0.7); $objWriter->writeAttribute('t', 0.75); $objWriter->writeAttribute('b', 0.75); $objWriter->endElement(); $objWriter->startElement('c:pageSetup'); $objWriter->writeAttribute('orientation', "portrait"); $objWriter->endElement(); $objWriter->endElement(); } } PK!3h,,Excel2007/ContentTypes.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Types $objWriter->startElement('Types'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); // Theme $this->writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); // Styles $this->writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'); // Rels $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); // XML $this->writeDefaultContentType($objWriter, 'xml', 'application/xml'); // VML $this->writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); // Workbook if ($pPHPExcel->hasMacros()) { //Macros in workbook ? // Yes : not standard content but "macroEnabled" $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); //... and define a new type for the VBA project $this->writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); if ($pPHPExcel->hasMacrosCertificate()) {// signed macros ? // Yes : add needed information $this->writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'); } } else {// no macros in workbook, so standard type $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'); } // DocProps $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); if (!empty($customPropertyList)) { $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); } // Worksheets $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { $this->writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); } // Shared strings $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); // Add worksheet relationship content types $chart = 1; for ($i = 0; $i < $sheetCount; ++$i) { $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; // We need a drawing relationship for the worksheet if we have either drawings or charts if (($drawingCount > 0) || ($chartCount > 0)) { $this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); } // If we have charts, then we need a chart relationship for every individual chart if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { $this->writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); } } } // Comments for ($i = 0; $i < $sheetCount; ++$i) { if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { $this->writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); } } // Add media content-types $aMediaContentTypes = array(); $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); for ($i = 0; $i < $mediaCount; ++$i) { $extension = ''; $mimeType = ''; if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); $mimeType = $this->getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); $extension = explode('/', $extension); $extension = $extension[1]; $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); } if (!isset( $aMediaContentTypes[$extension])) { $aMediaContentTypes[$extension] = $mimeType; $this->writeDefaultContentType($objWriter, $extension, $mimeType); } } if ($pPHPExcel->hasRibbonBinObjects()) { // Some additional objects in the ribbon ? // we need to write "Extension" but not already write for media content $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); foreach ($tabRibbonTypes as $aRibbonType) { $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor $this->writeDefaultContentType($objWriter, $aRibbonType, $mimeType); } } $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { if (!isset( $aMediaContentTypes[strtolower($image->getExtension())])) { $aMediaContentTypes[strtolower($image->getExtension())] = $this->getImageMimeType($image->getPath()); $this->writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]); } } } } $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Get image mime type * * @param string $pFile Filename * @return string Mime Type * @throws PHPExcel_Writer_Exception */ private function getImageMimeType($pFile = '') { if (PHPExcel_Shared_File::file_exists($pFile)) { $image = getimagesize($pFile); return image_type_to_mime_type($image[2]); } else { throw new PHPExcel_Writer_Exception("File $pFile does not exist"); } } /** * Write Default content type * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pPartname Part name * @param string $pContentType Content type * @throws PHPExcel_Writer_Exception */ private function writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') { if ($pPartname != '' && $pContentType != '') { // Write content type $objWriter->startElement('Default'); $objWriter->writeAttribute('Extension', $pPartname); $objWriter->writeAttribute('ContentType', $pContentType); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } /** * Write Override content type * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pPartname Part name * @param string $pContentType Content type * @throws PHPExcel_Writer_Exception */ private function writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') { if ($pPartname != '' && $pContentType != '') { // Write content type $objWriter->startElement('Override'); $objWriter->writeAttribute('PartName', $pPartname); $objWriter->writeAttribute('ContentType', $pContentType); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } } PK!򬵂>>Excel2007/Rels.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); if (!empty($customPropertyList)) { // Relationship docProps/app.xml $this->writeRelationship( $objWriter, 4, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', 'docProps/custom.xml' ); } // Relationship docProps/app.xml $this->writeRelationship( $objWriter, 3, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', 'docProps/app.xml' ); // Relationship docProps/core.xml $this->writeRelationship( $objWriter, 2, 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', 'docProps/core.xml' ); // Relationship xl/workbook.xml $this->writeRelationship( $objWriter, 1, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', 'xl/workbook.xml' ); // a custom UI in workbook ? if ($pPHPExcel->hasRibbon()) { $this->writeRelationShip( $objWriter, 5, 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', $pPHPExcel->getRibbonXMLData('target') ); } $objWriter->endElement(); return $objWriter->getData(); } /** * Write workbook relationships to XML format * * @param PHPExcel $pPHPExcel * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Relationship styles.xml $this->writeRelationship( $objWriter, 1, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', 'styles.xml' ); // Relationship theme/theme1.xml $this->writeRelationship( $objWriter, 2, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', 'theme/theme1.xml' ); // Relationship sharedStrings.xml $this->writeRelationship( $objWriter, 3, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', 'sharedStrings.xml' ); // Relationships with sheets $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { $this->writeRelationship( $objWriter, ($i + 1 + 3), 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', 'worksheets/sheet' . ($i + 1) . '.xml' ); } // Relationships for vbaProject if needed // id : just after the last sheet if ($pPHPExcel->hasMacros()) { $this->writeRelationShip( $objWriter, ($i + 1 + 3), 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', 'vbaProject.bin' ); ++$i;//increment i if needed for an another relation } $objWriter->endElement(); return $objWriter->getData(); } /** * Write worksheet relationships to XML format * * Numbering is as follows: * rId1 - Drawings * rId_hyperlink_x - Hyperlinks * * @param PHPExcel_Worksheet $pWorksheet * @param int $pWorksheetId * @param boolean $includeCharts Flag indicating if we should write charts * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = false) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Write drawing relationships? $d = 0; if ($includeCharts) { $charts = $pWorksheet->getChartCollection(); } else { $charts = array(); } if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0)) { $this->writeRelationship( $objWriter, ++$d, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', '../drawings/drawing' . $pWorksheetId . '.xml' ); } // Write chart relationships? // $chartCount = 0; // $charts = $pWorksheet->getChartCollection(); // echo 'Chart Rels: ' , count($charts) , '
'; // if (count($charts) > 0) { // foreach ($charts as $chart) { // $this->writeRelationship( // $objWriter, // ++$d, // 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', // '../charts/chart' . ++$chartCount . '.xml' // ); // } // } // // Write hyperlink relationships? $i = 1; foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { if (!$hyperlink->isInternal()) { $this->writeRelationship( $objWriter, '_hyperlink_' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External' ); ++$i; } } // Write comments relationship? $i = 1; if (count($pWorksheet->getComments()) > 0) { $this->writeRelationship( $objWriter, '_comments_vml' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', '../drawings/vmlDrawing' . $pWorksheetId . '.vml' ); $this->writeRelationship( $objWriter, '_comments' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', '../comments' . $pWorksheetId . '.xml' ); } // Write header/footer relationship? $i = 1; if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { $this->writeRelationship( $objWriter, '_headerfooter_vml' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' ); } $objWriter->endElement(); return $objWriter->getData(); } /** * Write drawing relationships to XML format * * @param PHPExcel_Worksheet $pWorksheet * @param int &$chartRef Chart ID * @param boolean $includeCharts Flag indicating if we should write charts * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = false) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Loop through images and write relationships $i = 1; $iterator = $pWorksheet->getDrawingCollection()->getIterator(); while ($iterator->valid()) { if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { // Write relationship for image drawing $this->writeRelationship( $objWriter, $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) ); } $iterator->next(); ++$i; } if ($includeCharts) { // Loop through charts and write relationships $chartCount = $pWorksheet->getChartCount(); if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { $this->writeRelationship( $objWriter, $i++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/chart' . ++$chartRef . '.xml' ); } } } $objWriter->endElement(); return $objWriter->getData(); } /** * Write header/footer drawing relationships to XML format * * @param PHPExcel_Worksheet $pWorksheet * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Loop through images and write relationships foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { // Write relationship for image drawing $this->writeRelationship( $objWriter, $key, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $value->getIndexedFilename() ); } $objWriter->endElement(); return $objWriter->getData(); } /** * Write Override content type * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param int $pId Relationship ID. rId will be prepended! * @param string $pType Relationship type * @param string $pTarget Relationship target * @param string $pTargetMode Relationship target mode * @throws PHPExcel_Writer_Exception */ private function writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') { if ($pType != '' && $pTarget != '') { // Write relationship $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', 'rId' . $pId); $objWriter->writeAttribute('Type', $pType); $objWriter->writeAttribute('Target', $pTarget); if ($pTargetMode != '') { $objWriter->writeAttribute('TargetMode', $pTargetMode); } $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } } PK!q Excel2007/RelsRibbon.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); $localRels = $pPHPExcel->getRibbonBinObjects('names'); if (is_array($localRels)) { foreach ($localRels as $aId => $aTarget) { $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', $aId); $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); $objWriter->writeAttribute('Target', $aTarget); $objWriter->endElement(); } } $objWriter->endElement(); return $objWriter->getData(); } } PK!]{E{EExcel2007/Workbook.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // workbook $objWriter->startElement('workbook'); $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); // fileVersion $this->writeFileVersion($objWriter); // workbookPr $this->writeWorkbookPr($objWriter); // workbookProtection $this->writeWorkbookProtection($objWriter, $pPHPExcel); // bookViews if ($this->getParentWriter()->getOffice2003Compatibility() === false) { $this->writeBookViews($objWriter, $pPHPExcel); } // sheets $this->writeSheets($objWriter, $pPHPExcel); // definedNames $this->writeDefinedNames($objWriter, $pPHPExcel); // calcPr $this->writeCalcPr($objWriter, $recalcRequired); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write file version * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @throws PHPExcel_Writer_Exception */ private function writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) { $objWriter->startElement('fileVersion'); $objWriter->writeAttribute('appName', 'xl'); $objWriter->writeAttribute('lastEdited', '4'); $objWriter->writeAttribute('lowestEdited', '4'); $objWriter->writeAttribute('rupBuild', '4505'); $objWriter->endElement(); } /** * Write WorkbookPr * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @throws PHPExcel_Writer_Exception */ private function writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) { $objWriter->startElement('workbookPr'); if (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) { $objWriter->writeAttribute('date1904', '1'); } $objWriter->writeAttribute('codeName', 'ThisWorkbook'); $objWriter->endElement(); } /** * Write BookViews * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ private function writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { // bookViews $objWriter->startElement('bookViews'); // workbookView $objWriter->startElement('workbookView'); $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); $objWriter->writeAttribute('autoFilterDateGrouping', '1'); $objWriter->writeAttribute('firstSheet', '0'); $objWriter->writeAttribute('minimized', '0'); $objWriter->writeAttribute('showHorizontalScroll', '1'); $objWriter->writeAttribute('showSheetTabs', '1'); $objWriter->writeAttribute('showVerticalScroll', '1'); $objWriter->writeAttribute('tabRatio', '600'); $objWriter->writeAttribute('visibility', 'visible'); $objWriter->endElement(); $objWriter->endElement(); } /** * Write WorkbookProtection * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ private function writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { $objWriter->startElement('workbookProtection'); $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') { $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); } if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') { $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); } $objWriter->endElement(); } } /** * Write calcPr * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing * @throws PHPExcel_Writer_Exception */ private function writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = true) { $objWriter->startElement('calcPr'); // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit // because the file has changed $objWriter->writeAttribute('calcId', '999999'); $objWriter->writeAttribute('calcMode', 'auto'); // fullCalcOnLoad isn't needed if we've recalculating for the save $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); $objWriter->endElement(); } /** * Write sheets * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ private function writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { // Write sheets $objWriter->startElement('sheets'); $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { // sheet $this->writeSheet( $objWriter, $pPHPExcel->getSheet($i)->getTitle(), ($i + 1), ($i + 1 + 3), $pPHPExcel->getSheet($i)->getSheetState() ); } $objWriter->endElement(); } /** * Write sheet * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pSheetname Sheet name * @param int $pSheetId Sheet id * @param int $pRelId Relationship ID * @param string $sheetState Sheet state (visible, hidden, veryHidden) * @throws PHPExcel_Writer_Exception */ private function writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') { if ($pSheetname != '') { // Write sheet $objWriter->startElement('sheet'); $objWriter->writeAttribute('name', $pSheetname); $objWriter->writeAttribute('sheetId', $pSheetId); if ($sheetState != 'visible' && $sheetState != '') { $objWriter->writeAttribute('state', $sheetState); } $objWriter->writeAttribute('r:id', 'rId' . $pRelId); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } /** * Write Defined Names * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ private function writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { // Write defined names $objWriter->startElement('definedNames'); // Named ranges if (count($pPHPExcel->getNamedRanges()) > 0) { // Named ranges $this->writeNamedRanges($objWriter, $pPHPExcel); } // Other defined names $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { // definedName for autoFilter $this->writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); // definedName for Print_Titles $this->writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); // definedName for Print_Area $this->writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); } $objWriter->endElement(); } /** * Write named ranges * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ private function writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) { // Loop named ranges $namedRanges = $pPHPExcel->getNamedRanges(); foreach ($namedRanges as $namedRange) { $this->writeDefinedNameForNamedRange($objWriter, $namedRange); } } /** * Write Defined Name for named range * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_NamedRange $pNamedRange * @throws PHPExcel_Writer_Exception */ private function writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) { // definedName for named range $objWriter->startElement('definedName'); $objWriter->writeAttribute('name', $pNamedRange->getName()); if ($pNamedRange->getLocalOnly()) { $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); } // Create absolute coordinate and write as raw text $range = PHPExcel_Cell::splitRange($pNamedRange->getRange()); for ($i = 0; $i < count($range); $i++) { $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]); if (isset($range[$i][1])) { $range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]); } } $range = PHPExcel_Cell::buildRange($range); $objWriter->writeRawData($range); $objWriter->endElement(); } /** * Write Defined Name for autoFilter * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet * @param int $pSheetId * @throws PHPExcel_Writer_Exception */ private function writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) { // definedName for autoFilter $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { $objWriter->startElement('definedName'); $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); $objWriter->writeAttribute('localSheetId', $pSheetId); $objWriter->writeAttribute('hidden', '1'); // Create absolute coordinate and write as raw text $range = PHPExcel_Cell::splitRange($autoFilterRange); $range = $range[0]; // Strip any worksheet ref so we can make the cell ref absolute if (strpos($range[0], '!') !== false) { list($ws, $range[0]) = explode('!', $range[0]); } $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]); $range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]); $range = implode(':', $range); $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range); $objWriter->endElement(); } } /** * Write Defined Name for PrintTitles * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet * @param int $pSheetId * @throws PHPExcel_Writer_Exception */ private function writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) { // definedName for PrintTitles if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { $objWriter->startElement('definedName'); $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); $objWriter->writeAttribute('localSheetId', $pSheetId); // Setting string $settingString = ''; // Columns to repeat if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft(); $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; } // Rows to repeat if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { $settingString .= ','; } $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop(); $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; } $objWriter->writeRawData($settingString); $objWriter->endElement(); } } /** * Write Defined Name for PrintTitles * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet $pSheet * @param int $pSheetId * @throws PHPExcel_Writer_Exception */ private function writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) { // definedName for PrintArea if ($pSheet->getPageSetup()->isPrintAreaSet()) { $objWriter->startElement('definedName'); $objWriter->writeAttribute('name', '_xlnm.Print_Area'); $objWriter->writeAttribute('localSheetId', $pSheetId); // Setting string $settingString = ''; // Print area $printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea()); $chunks = array(); foreach ($printArea as $printAreaRect) { $printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]); $printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]); $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect); } $objWriter->writeRawData(implode(',', $chunks)); $objWriter->endElement(); } } } PK!11Excel2007/StringTable.phpnu[flipStringTable($aStringTable); // Loop through cells foreach ($pSheet->getCellCollection() as $cellID) { $cell = $pSheet->getCell($cellID); $cellValue = $cell->getValue(); if (!is_object($cellValue) && ($cellValue !== null) && $cellValue !== '' && !isset($aFlippedStringTable[$cellValue]) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) { $aStringTable[] = $cellValue; $aFlippedStringTable[$cellValue] = true; } elseif ($cellValue instanceof PHPExcel_RichText && ($cellValue !== null) && !isset($aFlippedStringTable[$cellValue->getHashCode()])) { $aStringTable[] = $cellValue; $aFlippedStringTable[$cellValue->getHashCode()] = true; } } return $aStringTable; } else { throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); } } /** * Write string table to XML format * * @param string[] $pStringTable * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeStringTable($pStringTable = null) { if ($pStringTable !== null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // String table $objWriter->startElement('sst'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); $objWriter->writeAttribute('uniqueCount', count($pStringTable)); // Loop through string table foreach ($pStringTable as $textElement) { $objWriter->startElement('si'); if (! $textElement instanceof PHPExcel_RichText) { $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML($textElement); $objWriter->startElement('t'); if ($textToWrite !== trim($textToWrite)) { $objWriter->writeAttribute('xml:space', 'preserve'); } $objWriter->writeRawData($textToWrite); $objWriter->endElement(); } elseif ($textElement instanceof PHPExcel_RichText) { $this->writeRichText($objWriter, $textElement); } $objWriter->endElement(); } $objWriter->endElement(); return $objWriter->getData(); } else { throw new PHPExcel_Writer_Exception("Invalid string table array passed."); } } /** * Write Rich Text * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_RichText $pRichText Rich text * @param string $prefix Optional Namespace prefix * @throws PHPExcel_Writer_Exception */ public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix = null) { if ($prefix !== null) { $prefix .= ':'; } // Loop through rich text elements $elements = $pRichText->getRichTextElements(); foreach ($elements as $element) { // r $objWriter->startElement($prefix.'r'); // rPr if ($element instanceof PHPExcel_RichText_Run) { // rPr $objWriter->startElement($prefix.'rPr'); // rFont $objWriter->startElement($prefix.'rFont'); $objWriter->writeAttribute('val', $element->getFont()->getName()); $objWriter->endElement(); // Bold $objWriter->startElement($prefix.'b'); $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); $objWriter->endElement(); // Italic $objWriter->startElement($prefix.'i'); $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); $objWriter->endElement(); // Superscript / subscript if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { $objWriter->startElement($prefix.'vertAlign'); if ($element->getFont()->getSuperScript()) { $objWriter->writeAttribute('val', 'superscript'); } elseif ($element->getFont()->getSubScript()) { $objWriter->writeAttribute('val', 'subscript'); } $objWriter->endElement(); } // Strikethrough $objWriter->startElement($prefix.'strike'); $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); $objWriter->endElement(); // Color $objWriter->startElement($prefix.'color'); $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); $objWriter->endElement(); // Size $objWriter->startElement($prefix.'sz'); $objWriter->writeAttribute('val', $element->getFont()->getSize()); $objWriter->endElement(); // Underline $objWriter->startElement($prefix.'u'); $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); $objWriter->endElement(); $objWriter->endElement(); } // t $objWriter->startElement($prefix.'t'); $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($element->getText())); $objWriter->endElement(); $objWriter->endElement(); } } /** * Write Rich Text * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string|PHPExcel_RichText $pRichText text string or Rich text * @param string $prefix Optional Namespace prefix * @throws PHPExcel_Writer_Exception */ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix = null) { if (!$pRichText instanceof PHPExcel_RichText) { $textRun = $pRichText; $pRichText = new PHPExcel_RichText(); $pRichText->createTextRun($textRun); } if ($prefix !== null) { $prefix .= ':'; } // Loop through rich text elements $elements = $pRichText->getRichTextElements(); foreach ($elements as $element) { // r $objWriter->startElement($prefix.'r'); // rPr $objWriter->startElement($prefix.'rPr'); // Bold $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); // Italic $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); // Underline $underlineType = $element->getFont()->getUnderline(); switch ($underlineType) { case 'single': $underlineType = 'sng'; break; case 'double': $underlineType = 'dbl'; break; } $objWriter->writeAttribute('u', $underlineType); // Strikethrough $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); // rFont $objWriter->startElement($prefix.'latin'); $objWriter->writeAttribute('typeface', $element->getFont()->getName()); $objWriter->endElement(); // Superscript / subscript // if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { // $objWriter->startElement($prefix.'vertAlign'); // if ($element->getFont()->getSuperScript()) { // $objWriter->writeAttribute('val', 'superscript'); // } elseif ($element->getFont()->getSubScript()) { // $objWriter->writeAttribute('val', 'subscript'); // } // $objWriter->endElement(); // } // $objWriter->endElement(); // t $objWriter->startElement($prefix.'t'); // $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($element->getText())); $objWriter->endElement(); $objWriter->endElement(); } } /** * Flip string table (for index searching) * * @param array $stringTable Stringtable * @return array */ public function flipStringTable($stringTable = array()) { // Return value $returnValue = array(); // Loop through stringtable and add flipped items to $returnValue foreach ($stringTable as $key => $value) { if (! $value instanceof PHPExcel_RichText) { $returnValue[$value] = $key; } elseif ($value instanceof PHPExcel_RichText) { $returnValue[$value->getHashCode()] = $key; } } return $returnValue; } } PK!}ƂZZExcel2007/Drawing.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // xdr:wsDr $objWriter->startElement('xdr:wsDr'); $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); // Loop through images and write drawings $i = 1; $iterator = $pWorksheet->getDrawingCollection()->getIterator(); while ($iterator->valid()) { $this->writeDrawing($objWriter, $iterator->current(), $i); $iterator->next(); ++$i; } if ($includeCharts) { $chartCount = $pWorksheet->getChartCount(); // Loop through charts and write the chart position if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); } } } $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write drawings to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Chart $pChart * @param int $pRelationId * @throws PHPExcel_Writer_Exception */ public function writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) { $tl = $pChart->getTopLeftPosition(); $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']); $br = $pChart->getBottomRightPosition(); $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']); $objWriter->startElement('xdr:twoCellAnchor'); $objWriter->startElement('xdr:from'); $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1); $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset'])); $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1); $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset'])); $objWriter->endElement(); $objWriter->startElement('xdr:to'); $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1); $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset'])); $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1); $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset'])); $objWriter->endElement(); $objWriter->startElement('xdr:graphicFrame'); $objWriter->writeAttribute('macro', ''); $objWriter->startElement('xdr:nvGraphicFramePr'); $objWriter->startElement('xdr:cNvPr'); $objWriter->writeAttribute('name', 'Chart '.$pRelationId); $objWriter->writeAttribute('id', 1025 * $pRelationId); $objWriter->endElement(); $objWriter->startElement('xdr:cNvGraphicFramePr'); $objWriter->startElement('a:graphicFrameLocks'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('xdr:xfrm'); $objWriter->startElement('a:off'); $objWriter->writeAttribute('x', '0'); $objWriter->writeAttribute('y', '0'); $objWriter->endElement(); $objWriter->startElement('a:ext'); $objWriter->writeAttribute('cx', '0'); $objWriter->writeAttribute('cy', '0'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('a:graphic'); $objWriter->startElement('a:graphicData'); $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); $objWriter->startElement('c:chart'); $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $objWriter->writeAttribute('r:id', 'rId'.$pRelationId); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('xdr:clientData'); $objWriter->endElement(); $objWriter->endElement(); } /** * Write drawings to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Worksheet_BaseDrawing $pDrawing * @param int $pRelationId * @throws PHPExcel_Writer_Exception */ public function writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) { if ($pRelationId >= 0) { // xdr:oneCellAnchor $objWriter->startElement('xdr:oneCellAnchor'); // Image location $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); // xdr:from $objWriter->startElement('xdr:from'); $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); $objWriter->endElement(); // xdr:ext $objWriter->startElement('xdr:ext'); $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); $objWriter->endElement(); // xdr:pic $objWriter->startElement('xdr:pic'); // xdr:nvPicPr $objWriter->startElement('xdr:nvPicPr'); // xdr:cNvPr $objWriter->startElement('xdr:cNvPr'); $objWriter->writeAttribute('id', $pRelationId); $objWriter->writeAttribute('name', $pDrawing->getName()); $objWriter->writeAttribute('descr', $pDrawing->getDescription()); $objWriter->endElement(); // xdr:cNvPicPr $objWriter->startElement('xdr:cNvPicPr'); // a:picLocks $objWriter->startElement('a:picLocks'); $objWriter->writeAttribute('noChangeAspect', '1'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // xdr:blipFill $objWriter->startElement('xdr:blipFill'); // a:blip $objWriter->startElement('a:blip'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); $objWriter->endElement(); // a:stretch $objWriter->startElement('a:stretch'); $objWriter->writeElement('a:fillRect', null); $objWriter->endElement(); $objWriter->endElement(); // xdr:spPr $objWriter->startElement('xdr:spPr'); // a:xfrm $objWriter->startElement('a:xfrm'); $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); $objWriter->endElement(); // a:prstGeom $objWriter->startElement('a:prstGeom'); $objWriter->writeAttribute('prst', 'rect'); // a:avLst $objWriter->writeElement('a:avLst', null); $objWriter->endElement(); // // a:solidFill // $objWriter->startElement('a:solidFill'); // // a:srgbClr // $objWriter->startElement('a:srgbClr'); // $objWriter->writeAttribute('val', 'FFFFFF'); ///* SHADE // // a:shade // $objWriter->startElement('a:shade'); // $objWriter->writeAttribute('val', '85000'); // $objWriter->endElement(); //*/ // $objWriter->endElement(); // $objWriter->endElement(); /* // a:ln $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', '88900'); $objWriter->writeAttribute('cap', 'sq'); // a:solidFill $objWriter->startElement('a:solidFill'); // a:srgbClr $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', 'FFFFFF'); $objWriter->endElement(); $objWriter->endElement(); // a:miter $objWriter->startElement('a:miter'); $objWriter->writeAttribute('lim', '800000'); $objWriter->endElement(); $objWriter->endElement(); */ if ($pDrawing->getShadow()->getVisible()) { // a:effectLst $objWriter->startElement('a:effectLst'); // a:outerShdw $objWriter->startElement('a:outerShdw'); $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); $objWriter->writeAttribute('rotWithShape', '0'); // a:srgbClr $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); // a:alpha $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } /* // a:scene3d $objWriter->startElement('a:scene3d'); // a:camera $objWriter->startElement('a:camera'); $objWriter->writeAttribute('prst', 'orthographicFront'); $objWriter->endElement(); // a:lightRig $objWriter->startElement('a:lightRig'); $objWriter->writeAttribute('rig', 'twoPt'); $objWriter->writeAttribute('dir', 't'); // a:rot $objWriter->startElement('a:rot'); $objWriter->writeAttribute('lat', '0'); $objWriter->writeAttribute('lon', '0'); $objWriter->writeAttribute('rev', '0'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); */ /* // a:sp3d $objWriter->startElement('a:sp3d'); // a:bevelT $objWriter->startElement('a:bevelT'); $objWriter->writeAttribute('w', '25400'); $objWriter->writeAttribute('h', '19050'); $objWriter->endElement(); // a:contourClr $objWriter->startElement('a:contourClr'); // a:srgbClr $objWriter->startElement('a:srgbClr'); $objWriter->writeAttribute('val', 'FFFFFF'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); */ $objWriter->endElement(); $objWriter->endElement(); // xdr:clientData $objWriter->writeElement('xdr:clientData', null); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } /** * Write VML header/footer images to XML format * * @param PHPExcel_Worksheet $pWorksheet * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Header/footer images $images = $pWorksheet->getHeaderFooter()->getImages(); // xml $objWriter->startElement('xml'); $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); // o:shapelayout $objWriter->startElement('o:shapelayout'); $objWriter->writeAttribute('v:ext', 'edit'); // o:idmap $objWriter->startElement('o:idmap'); $objWriter->writeAttribute('v:ext', 'edit'); $objWriter->writeAttribute('data', '1'); $objWriter->endElement(); $objWriter->endElement(); // v:shapetype $objWriter->startElement('v:shapetype'); $objWriter->writeAttribute('id', '_x0000_t75'); $objWriter->writeAttribute('coordsize', '21600,21600'); $objWriter->writeAttribute('o:spt', '75'); $objWriter->writeAttribute('o:preferrelative', 't'); $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); $objWriter->writeAttribute('filled', 'f'); $objWriter->writeAttribute('stroked', 'f'); // v:stroke $objWriter->startElement('v:stroke'); $objWriter->writeAttribute('joinstyle', 'miter'); $objWriter->endElement(); // v:formulas $objWriter->startElement('v:formulas'); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'sum @0 1 0'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'prod @2 1 2'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'sum @0 0 1'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'prod @6 1 2'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); $objWriter->endElement(); // v:f $objWriter->startElement('v:f'); $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); $objWriter->endElement(); $objWriter->endElement(); // v:path $objWriter->startElement('v:path'); $objWriter->writeAttribute('o:extrusionok', 'f'); $objWriter->writeAttribute('gradientshapeok', 't'); $objWriter->writeAttribute('o:connecttype', 'rect'); $objWriter->endElement(); // o:lock $objWriter->startElement('o:lock'); $objWriter->writeAttribute('v:ext', 'edit'); $objWriter->writeAttribute('aspectratio', 't'); $objWriter->endElement(); $objWriter->endElement(); // Loop through images foreach ($images as $key => $value) { $this->writeVMLHeaderFooterImage($objWriter, $key, $value); } $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write VML comment to XML format * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pReference Reference * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image * @throws PHPExcel_Writer_Exception */ private function writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) { // Calculate object id preg_match('{(\d+)}', md5($pReference), $m); $id = 1500 + (substr($m[1], 0, 2) * 1); // Calculate offset $width = $pImage->getWidth(); $height = $pImage->getHeight(); $marginLeft = $pImage->getOffsetX(); $marginTop = $pImage->getOffsetY(); // v:shape $objWriter->startElement('v:shape'); $objWriter->writeAttribute('id', $pReference); $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); $objWriter->writeAttribute('type', '#_x0000_t75'); $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); // v:imagedata $objWriter->startElement('v:imagedata'); $objWriter->writeAttribute('o:relid', 'rId' . $pReference); $objWriter->writeAttribute('o:title', $pImage->getName()); $objWriter->endElement(); // o:lock $objWriter->startElement('o:lock'); $objWriter->writeAttribute('v:ext', 'edit'); $objWriter->writeAttribute('rotation', 't'); $objWriter->endElement(); $objWriter->endElement(); } /** * Get an array of all drawings * * @param PHPExcel $pPHPExcel * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allDrawings(PHPExcel $pPHPExcel = null) { // Get an array of all drawings $aDrawings = array(); // Loop through PHPExcel $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { // Loop through images and add to array $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator(); while ($iterator->valid()) { $aDrawings[] = $iterator->current(); $iterator->next(); } } return $aDrawings; } } PK!/ aΛmmExcel2007/Style.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // styleSheet $objWriter->startElement('styleSheet'); $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); // numFmts $objWriter->startElement('numFmts'); $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); // numFmt for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { $this->writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); } $objWriter->endElement(); // fonts $objWriter->startElement('fonts'); $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); // font for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { $this->writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); } $objWriter->endElement(); // fills $objWriter->startElement('fills'); $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); // fill for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { $this->writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); } $objWriter->endElement(); // borders $objWriter->startElement('borders'); $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); // border for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { $this->writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); } $objWriter->endElement(); // cellStyleXfs $objWriter->startElement('cellStyleXfs'); $objWriter->writeAttribute('count', 1); // xf $objWriter->startElement('xf'); $objWriter->writeAttribute('numFmtId', 0); $objWriter->writeAttribute('fontId', 0); $objWriter->writeAttribute('fillId', 0); $objWriter->writeAttribute('borderId', 0); $objWriter->endElement(); $objWriter->endElement(); // cellXfs $objWriter->startElement('cellXfs'); $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); // xf foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { $this->writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); } $objWriter->endElement(); // cellStyles $objWriter->startElement('cellStyles'); $objWriter->writeAttribute('count', 1); // cellStyle $objWriter->startElement('cellStyle'); $objWriter->writeAttribute('name', 'Normal'); $objWriter->writeAttribute('xfId', 0); $objWriter->writeAttribute('builtinId', 0); $objWriter->endElement(); $objWriter->endElement(); // dxfs $objWriter->startElement('dxfs'); $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); // dxf for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { $this->writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); } $objWriter->endElement(); // tableStyles $objWriter->startElement('tableStyles'); $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); $objWriter->endElement(); $objWriter->endElement(); // Return return $objWriter->getData(); } /** * Write Fill * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style_Fill $pFill Fill style * @throws PHPExcel_Writer_Exception */ private function writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) { // Check if this is a pattern type or gradient type if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR || $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { // Gradient fill $this->writeGradientFill($objWriter, $pFill); } elseif ($pFill->getFillType() !== null) { // Pattern fill $this->writePatternFill($objWriter, $pFill); } } /** * Write Gradient Fill * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style_Fill $pFill Fill style * @throws PHPExcel_Writer_Exception */ private function writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) { // fill $objWriter->startElement('fill'); // gradientFill $objWriter->startElement('gradientFill'); $objWriter->writeAttribute('type', $pFill->getFillType()); $objWriter->writeAttribute('degree', $pFill->getRotation()); // stop $objWriter->startElement('stop'); $objWriter->writeAttribute('position', '0'); // color $objWriter->startElement('color'); $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); $objWriter->endElement(); $objWriter->endElement(); // stop $objWriter->startElement('stop'); $objWriter->writeAttribute('position', '1'); // color $objWriter->startElement('color'); $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Pattern Fill * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style_Fill $pFill Fill style * @throws PHPExcel_Writer_Exception */ private function writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) { // fill $objWriter->startElement('fill'); // patternFill $objWriter->startElement('patternFill'); $objWriter->writeAttribute('patternType', $pFill->getFillType()); if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { // fgColor if ($pFill->getStartColor()->getARGB()) { $objWriter->startElement('fgColor'); $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); $objWriter->endElement(); } } if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { // bgColor if ($pFill->getEndColor()->getARGB()) { $objWriter->startElement('bgColor'); $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); $objWriter->endElement(); } } $objWriter->endElement(); $objWriter->endElement(); } /** * Write Font * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style_Font $pFont Font style * @throws PHPExcel_Writer_Exception */ private function writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) { // font $objWriter->startElement('font'); // Weird! The order of these elements actually makes a difference when opening Excel2007 // files in Excel2003 with the compatibility pack. It's not documented behaviour, // and makes for a real WTF! // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does // for conditional formatting). Otherwise it will apparently not be picked up in conditional // formatting style dialog if ($pFont->getBold() !== null) { $objWriter->startElement('b'); $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); $objWriter->endElement(); } // Italic if ($pFont->getItalic() !== null) { $objWriter->startElement('i'); $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); $objWriter->endElement(); } // Strikethrough if ($pFont->getStrikethrough() !== null) { $objWriter->startElement('strike'); $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); $objWriter->endElement(); } // Underline if ($pFont->getUnderline() !== null) { $objWriter->startElement('u'); $objWriter->writeAttribute('val', $pFont->getUnderline()); $objWriter->endElement(); } // Superscript / subscript if ($pFont->getSuperScript() === true || $pFont->getSubScript() === true) { $objWriter->startElement('vertAlign'); if ($pFont->getSuperScript() === true) { $objWriter->writeAttribute('val', 'superscript'); } elseif ($pFont->getSubScript() === true) { $objWriter->writeAttribute('val', 'subscript'); } $objWriter->endElement(); } // Size if ($pFont->getSize() !== null) { $objWriter->startElement('sz'); $objWriter->writeAttribute('val', $pFont->getSize()); $objWriter->endElement(); } // Foreground color if ($pFont->getColor()->getARGB() !== null) { $objWriter->startElement('color'); $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); $objWriter->endElement(); } // Name if ($pFont->getName() !== null) { $objWriter->startElement('name'); $objWriter->writeAttribute('val', $pFont->getName()); $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Border * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style_Borders $pBorders Borders style * @throws PHPExcel_Writer_Exception */ private function writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) { // Write border $objWriter->startElement('border'); // Diagonal? switch ($pBorders->getDiagonalDirection()) { case PHPExcel_Style_Borders::DIAGONAL_UP: $objWriter->writeAttribute('diagonalUp', 'true'); $objWriter->writeAttribute('diagonalDown', 'false'); break; case PHPExcel_Style_Borders::DIAGONAL_DOWN: $objWriter->writeAttribute('diagonalUp', 'false'); $objWriter->writeAttribute('diagonalDown', 'true'); break; case PHPExcel_Style_Borders::DIAGONAL_BOTH: $objWriter->writeAttribute('diagonalUp', 'true'); $objWriter->writeAttribute('diagonalDown', 'true'); break; } // BorderPr $this->writeBorderPr($objWriter, 'left', $pBorders->getLeft()); $this->writeBorderPr($objWriter, 'right', $pBorders->getRight()); $this->writeBorderPr($objWriter, 'top', $pBorders->getTop()); $this->writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); $this->writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); $objWriter->endElement(); } /** * Write Cell Style Xf * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style $pStyle Style * @param PHPExcel $pPHPExcel Workbook * @throws PHPExcel_Writer_Exception */ private function writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) { // xf $objWriter->startElement('xf'); $objWriter->writeAttribute('xfId', 0); $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); if ($pStyle->getQuotePrefix()) { $objWriter->writeAttribute('quotePrefix', 1); } if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164)); } else { $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); } $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); // Apply styles? $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { $objWriter->writeAttribute('applyProtection', 'true'); } // alignment $objWriter->startElement('alignment'); $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); $textRotation = 0; if ($pStyle->getAlignment()->getTextRotation() >= 0) { $textRotation = $pStyle->getAlignment()->getTextRotation(); } elseif ($pStyle->getAlignment()->getTextRotation() < 0) { $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); } $objWriter->writeAttribute('textRotation', $textRotation); $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); if ($pStyle->getAlignment()->getIndent() > 0) { $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); } if ($pStyle->getAlignment()->getReadorder() > 0) { $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder()); } $objWriter->endElement(); // protection if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { $objWriter->startElement('protection'); if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); } if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); } $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Cell Style Dxf * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style $pStyle Style * @throws PHPExcel_Writer_Exception */ private function writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) { // dxf $objWriter->startElement('dxf'); // font $this->writeFont($objWriter, $pStyle->getFont()); // numFmt $this->writeNumFmt($objWriter, $pStyle->getNumberFormat()); // fill $this->writeFill($objWriter, $pStyle->getFill()); // alignment $objWriter->startElement('alignment'); if ($pStyle->getAlignment()->getHorizontal() !== null) { $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); } if ($pStyle->getAlignment()->getVertical() !== null) { $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); } if ($pStyle->getAlignment()->getTextRotation() !== null) { $textRotation = 0; if ($pStyle->getAlignment()->getTextRotation() >= 0) { $textRotation = $pStyle->getAlignment()->getTextRotation(); } elseif ($pStyle->getAlignment()->getTextRotation() < 0) { $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); } $objWriter->writeAttribute('textRotation', $textRotation); } $objWriter->endElement(); // border $this->writeBorder($objWriter, $pStyle->getBorders()); // protection if (($pStyle->getProtection()->getLocked() !== null) || ($pStyle->getProtection()->getHidden() !== null)) { if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { $objWriter->startElement('protection'); if (($pStyle->getProtection()->getLocked() !== null) && ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); } if (($pStyle->getProtection()->getHidden() !== null) && ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); } $objWriter->endElement(); } } $objWriter->endElement(); } /** * Write BorderPr * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param string $pName Element name * @param PHPExcel_Style_Border $pBorder Border style * @throws PHPExcel_Writer_Exception */ private function writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) { // Write BorderPr if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { $objWriter->startElement($pName); $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); // color $objWriter->startElement('color'); $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); $objWriter->endElement(); $objWriter->endElement(); } } /** * Write NumberFormat * * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @param PHPExcel_Style_NumberFormat $pNumberFormat Number Format * @param int $pId Number Format identifier * @throws PHPExcel_Writer_Exception */ private function writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) { // Translate formatcode $formatCode = $pNumberFormat->getFormatCode(); // numFmt if ($formatCode !== null) { $objWriter->startElement('numFmt'); $objWriter->writeAttribute('numFmtId', ($pId + 164)); $objWriter->writeAttribute('formatCode', $formatCode); $objWriter->endElement(); } } /** * Get an array of all styles * * @param PHPExcel $pPHPExcel * @return PHPExcel_Style[] All styles in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allStyles(PHPExcel $pPHPExcel = null) { return $pPHPExcel->getCellXfCollection(); } /** * Get an array of all conditional styles * * @param PHPExcel $pPHPExcel * @return PHPExcel_Style_Conditional[] All conditional styles in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allConditionalStyles(PHPExcel $pPHPExcel = null) { // Get an array of all styles $aStyles = array(); $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { foreach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) { foreach ($conditionalStyles as $conditionalStyle) { $aStyles[] = $conditionalStyle; } } } return $aStyles; } /** * Get an array of all fills * * @param PHPExcel $pPHPExcel * @return PHPExcel_Style_Fill[] All fills in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allFills(PHPExcel $pPHPExcel = null) { // Get an array of unique fills $aFills = array(); // Two first fills are predefined $fill0 = new PHPExcel_Style_Fill(); $fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE); $aFills[] = $fill0; $fill1 = new PHPExcel_Style_Fill(); $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125); $aFills[] = $fill1; // The remaining fills $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) { $aFills[ $style->getFill()->getHashCode() ] = $style->getFill(); } } return $aFills; } /** * Get an array of all fonts * * @param PHPExcel $pPHPExcel * @return PHPExcel_Style_Font[] All fonts in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allFonts(PHPExcel $pPHPExcel = null) { // Get an array of unique fonts $aFonts = array(); $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) { $aFonts[ $style->getFont()->getHashCode() ] = $style->getFont(); } } return $aFonts; } /** * Get an array of all borders * * @param PHPExcel $pPHPExcel * @return PHPExcel_Style_Borders[] All borders in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allBorders(PHPExcel $pPHPExcel = null) { // Get an array of unique borders $aBorders = array(); $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) { $aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders(); } } return $aBorders; } /** * Get an array of all number formats * * @param PHPExcel $pPHPExcel * @return PHPExcel_Style_NumberFormat[] All number formats in PHPExcel * @throws PHPExcel_Writer_Exception */ public function allNumberFormats(PHPExcel $pPHPExcel = null) { // Get an array of unique number formats $aNumFmts = array(); $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) { $aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat(); } } return $aNumFmts; } } PK!,vp]Excel2007/WriterPart.phpnu[parentWriter = $pWriter; } /** * Get parent IWriter object * * @return PHPExcel_Writer_IWriter * @throws PHPExcel_Writer_Exception */ public function getParentWriter() { if (!is_null($this->parentWriter)) { return $this->parentWriter; } else { throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned."); } } /** * Set parent IWriter object * * @param PHPExcel_Writer_IWriter $pWriter * @throws PHPExcel_Writer_Exception */ public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { if (!is_null($pWriter)) { $this->parentWriter = $pWriter; } } } PK!@: Excel2007/RelsVBA.phpnu[getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', 'rId1'); $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); $objWriter->endElement(); $objWriter->endElement(); return $objWriter->getData(); } } PK! PDF.phpnu[renderer = new $rendererName($phpExcel); } /** * Magic method to handle direct calls to the configured PDF renderer wrapper class. * * @param string $name Renderer library method name * @param mixed[] $arguments Array of arguments to pass to the renderer method * @return mixed Returned data from the PDF renderer wrapper method */ public function __call($name, $arguments) { if ($this->renderer === null) { throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); } return call_user_func_array(array($this->renderer, $name), $arguments); } /** * {@inheritdoc} */ public function save($pFilename = null) { $this->renderer->save($pFilename); } } PK! ==HTML.phpnu[phpExcel = $phpExcel; $this->defaultFont = $this->phpExcel->getDefaultStyle()->getFont(); } /** * Save PHPExcel to file * * @param string $pFilename * @throws PHPExcel_Writer_Exception */ public function save($pFilename = null) { // garbage collect $this->phpExcel->garbageCollect(); $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog(); PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); // Build CSS $this->buildCSS(!$this->useInlineCss); // Open file $fileHandle = fopen($pFilename, 'wb+'); if ($fileHandle === false) { throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); } // Write headers fwrite($fileHandle, $this->generateHTMLHeader(!$this->useInlineCss)); // Write navigation (tabs) if ((!$this->isPdf) && ($this->generateSheetNavigationBlock)) { fwrite($fileHandle, $this->generateNavigation()); } // Write data fwrite($fileHandle, $this->generateSheetData()); // Write footer fwrite($fileHandle, $this->generateHTMLFooter()); // Close file fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** * Map VAlign * * @param string $vAlign Vertical alignment * @return string */ private function mapVAlign($vAlign) { switch ($vAlign) { case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: return 'bottom'; case PHPExcel_Style_Alignment::VERTICAL_TOP: return 'top'; case PHPExcel_Style_Alignment::VERTICAL_CENTER: case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: return 'middle'; default: return 'baseline'; } } /** * Map HAlign * * @param string $hAlign Horizontal alignment * @return string|false */ private function mapHAlign($hAlign) { switch ($hAlign) { case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: return false; case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: return 'left'; case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: return 'right'; case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: return 'center'; case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: return 'justify'; default: return false; } } /** * Map border style * * @param int $borderStyle Sheet index * @return string */ private function mapBorderStyle($borderStyle) { switch ($borderStyle) { case PHPExcel_Style_Border::BORDER_NONE: return 'none'; case PHPExcel_Style_Border::BORDER_DASHDOT: return '1px dashed'; case PHPExcel_Style_Border::BORDER_DASHDOTDOT: return '1px dotted'; case PHPExcel_Style_Border::BORDER_DASHED: return '1px dashed'; case PHPExcel_Style_Border::BORDER_DOTTED: return '1px dotted'; case PHPExcel_Style_Border::BORDER_DOUBLE: return '3px double'; case PHPExcel_Style_Border::BORDER_HAIR: return '1px solid'; case PHPExcel_Style_Border::BORDER_MEDIUM: return '2px solid'; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: return '2px dashed'; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: return '2px dotted'; case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: return '2px dashed'; case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: return '2px dashed'; case PHPExcel_Style_Border::BORDER_THICK: return '3px solid'; case PHPExcel_Style_Border::BORDER_THIN: return '1px solid'; default: // map others to thin return '1px solid'; } } /** * Get sheet index * * @return int */ public function getSheetIndex() { return $this->sheetIndex; } /** * Set sheet index * * @param int $pValue Sheet index * @return PHPExcel_Writer_HTML */ public function setSheetIndex($pValue = 0) { $this->sheetIndex = $pValue; return $this; } /** * Get sheet index * * @return boolean */ public function getGenerateSheetNavigationBlock() { return $this->generateSheetNavigationBlock; } /** * Set sheet index * * @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not * @return PHPExcel_Writer_HTML */ public function setGenerateSheetNavigationBlock($pValue = true) { $this->generateSheetNavigationBlock = (bool) $pValue; return $this; } /** * Write all sheets (resets sheetIndex to NULL) */ public function writeAllSheets() { $this->sheetIndex = null; return $this; } /** * Generate HTML header * * @param boolean $pIncludeStyles Include styles? * @return string * @throws PHPExcel_Writer_Exception */ public function generateHTMLHeader($pIncludeStyles = false) { // PHPExcel object known? if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Construct HTML $properties = $this->phpExcel->getProperties(); $html = '' . PHP_EOL; $html .= '' . PHP_EOL; $html .= '' . PHP_EOL; $html .= ' ' . PHP_EOL; $html .= ' ' . PHP_EOL; if ($properties->getTitle() > '') { $html .= ' ' . htmlspecialchars($properties->getTitle()) . '' . PHP_EOL; } if ($properties->getCreator() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getTitle() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getDescription() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getSubject() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getKeywords() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getCategory() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getCompany() > '') { $html .= ' ' . PHP_EOL; } if ($properties->getManager() > '') { $html .= ' ' . PHP_EOL; } if ($pIncludeStyles) { $html .= $this->generateStyles(true); } $html .= ' ' . PHP_EOL; $html .= '' . PHP_EOL; $html .= ' ' . PHP_EOL; return $html; } /** * Generate sheet data * * @return string * @throws PHPExcel_Writer_Exception */ public function generateSheetData() { // PHPExcel object known? if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Ensure that Spans have been calculated? if ($this->sheetIndex !== null || !$this->spansAreCalculated) { $this->calculateSpans(); } // Fetch sheets $sheets = array(); if (is_null($this->sheetIndex)) { $sheets = $this->phpExcel->getAllSheets(); } else { $sheets[] = $this->phpExcel->getSheet($this->sheetIndex); } // Construct HTML $html = ''; // Loop all sheets $sheetId = 0; foreach ($sheets as $sheet) { // Write table header $html .= $this->generateTableHeader($sheet); // Get worksheet dimension $dimension = explode(':', $sheet->calculateWorksheetDimension()); $dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]); $dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1; $dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]); $dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1; // row min,max $rowMin = $dimension[0][1]; $rowMax = $dimension[1][1]; // calculate start of , $tbodyStart = $rowMin; $theadStart = $theadEnd = 0; // default: no no if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) { $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop(); // we can only support repeating rows that start at top row if ($rowsToRepeatAtTop[0] == 1) { $theadStart = $rowsToRepeatAtTop[0]; $theadEnd = $rowsToRepeatAtTop[1]; $tbodyStart = $rowsToRepeatAtTop[1] + 1; } } // Loop through cells $row = $rowMin-1; while ($row++ < $rowMax) { // ? if ($row == $theadStart) { $html .= ' ' . PHP_EOL; $cellType = 'th'; } // ? if ($row == $tbodyStart) { $html .= ' ' . PHP_EOL; $cellType = 'td'; } // Write row if there are HTML table cells in it if (!isset($this->isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) { // Start a new rowData $rowData = array(); // Loop through columns $column = $dimension[0][0] - 1; while ($column++ < $dimension[1][0]) { // Cell exists? if ($sheet->cellExistsByColumnAndRow($column, $row)) { $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; } else { $rowData[$column] = ''; } } $html .= $this->generateRow($sheet, $rowData, $row - 1, $cellType); } // ? if ($row == $theadEnd) { $html .= ' ' . PHP_EOL; } } $html .= $this->extendRowsForChartsAndImages($sheet, $row); // Close table body. $html .= ' ' . PHP_EOL; // Write table footer $html .= $this->generateTableFooter(); // Writing PDF? if ($this->isPdf) { if (is_null($this->sheetIndex) && $sheetId + 1 < $this->phpExcel->getSheetCount()) { $html .= '
'; } } // Next sheet ++$sheetId; } return $html; } /** * Generate sheet tabs * * @return string * @throws PHPExcel_Writer_Exception */ public function generateNavigation() { // PHPExcel object known? if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Fetch sheets $sheets = array(); if (is_null($this->sheetIndex)) { $sheets = $this->phpExcel->getAllSheets(); } else { $sheets[] = $this->phpExcel->getSheet($this->sheetIndex); } // Construct HTML $html = ''; // Only if there are more than 1 sheets if (count($sheets) > 1) { // Loop all sheets $sheetId = 0; $html .= '' . PHP_EOL; } return $html; } private function extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { $rowMax = $row; $colMax = 'A'; if ($this->includeCharts) { foreach ($pSheet->getChartCollection() as $chart) { if ($chart instanceof PHPExcel_Chart) { $chartCoordinates = $chart->getTopLeftPosition(); $chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']); $chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]); if ($chartTL[1] > $rowMax) { $rowMax = $chartTL[1]; if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { $colMax = $chartTL[0]; } } } } } foreach ($pSheet->getDrawingCollection() as $drawing) { if ($drawing instanceof PHPExcel_Worksheet_Drawing) { $imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates()); $imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]); if ($imageTL[1] > $rowMax) { $rowMax = $imageTL[1]; if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { $colMax = $imageTL[0]; } } } } $html = ''; $colMax++; while ($row <= $rowMax) { $html .= ''; for ($col = 'A'; $col != $colMax; ++$col) { $html .= ''; $html .= $this->writeImageInCell($pSheet, $col.$row); if ($this->includeCharts) { $html .= $this->writeChartInCell($pSheet, $col.$row); } $html .= ''; } ++$row; $html .= ''; } return $html; } /** * Generate image tag in cell * * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet * @param string $coordinates Cell coordinates * @return string * @throws PHPExcel_Writer_Exception */ private function writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { // Construct HTML $html = ''; // Write images foreach ($pSheet->getDrawingCollection() as $drawing) { if ($drawing instanceof PHPExcel_Worksheet_Drawing) { if ($drawing->getCoordinates() == $coordinates) { $filename = $drawing->getPath(); // Strip off eventual '.' if (substr($filename, 0, 1) == '.') { $filename = substr($filename, 1); } // Prepend images root $filename = $this->getImagesRoot() . $filename; // Strip off eventual '.' if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') { $filename = substr($filename, 1); } // Convert UTF8 data to PCDATA $filename = htmlspecialchars($filename); $html .= PHP_EOL; if ((!$this->embedImages) || ($this->isPdf)) { $imageData = $filename; } else { $imageDetails = getimagesize($filename); if ($fp = fopen($filename, "rb", 0)) { $picture = fread($fp, filesize($filename)); fclose($fp); // base64 encode the binary data, then break it // into chunks according to RFC 2045 semantics $base64 = chunk_split(base64_encode($picture)); $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; } else { $imageData = $filename; } } $html .= '
'; $html .= ''; $html .= '
'; } } elseif ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { if ($drawing->getCoordinates() != $coordinates) { continue; } ob_start(); // Let's start output buffering. imagepng($drawing->getImageResource()); // This will normally output the image, but because of ob_start(), it won't. $contents = ob_get_contents(); // Instead, output above is saved to $contents ob_end_clean(); // End the output buffer. $dataUri = "data:image/jpeg;base64," . base64_encode($contents); // Because of the nature of tables, width is more important than height. // max-width: 100% ensures that image doesnt overflow containing cell // width: X sets width of supplied image. // As a result, images bigger than cell will be contained and images smaller will not get stretched $html .= ''; } } return $html; } /** * Generate chart tag in cell * * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet * @param string $coordinates Cell coordinates * @return string * @throws PHPExcel_Writer_Exception */ private function writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { // Construct HTML $html = ''; // Write charts foreach ($pSheet->getChartCollection() as $chart) { if ($chart instanceof PHPExcel_Chart) { $chartCoordinates = $chart->getTopLeftPosition(); if ($chartCoordinates['cell'] == $coordinates) { $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png'; if (!$chart->render($chartFileName)) { return; } $html .= PHP_EOL; $imageDetails = getimagesize($chartFileName); if ($fp = fopen($chartFileName, "rb", 0)) { $picture = fread($fp, filesize($chartFileName)); fclose($fp); // base64 encode the binary data, then break it // into chunks according to RFC 2045 semantics $base64 = chunk_split(base64_encode($picture)); $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; $html .= '
'; $html .= '' . PHP_EOL; $html .= '
'; unlink($chartFileName); } } } } // Return return $html; } /** * Generate CSS styles * * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (<style> and </style>) * @return string * @throws PHPExcel_Writer_Exception */ public function generateStyles($generateSurroundingHTML = true) { // PHPExcel object known? if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Build CSS $css = $this->buildCSS($generateSurroundingHTML); // Construct HTML $html = ''; // Start styles if ($generateSurroundingHTML) { $html .= ' ' . PHP_EOL; } // Return return $html; } /** * Build CSS styles * * @param boolean $generateSurroundingHTML Generate surrounding HTML style? (html { }) * @return array * @throws PHPExcel_Writer_Exception */ public function buildCSS($generateSurroundingHTML = true) { // PHPExcel object known? if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Cached? if (!is_null($this->cssStyles)) { return $this->cssStyles; } // Ensure that spans have been calculated if (!$this->spansAreCalculated) { $this->calculateSpans(); } // Construct CSS $css = array(); // Start styles if ($generateSurroundingHTML) { // html { } $css['html']['font-family'] = 'Calibri, Arial, Helvetica, sans-serif'; $css['html']['font-size'] = '11pt'; $css['html']['background-color'] = 'white'; } // table { } $css['table']['border-collapse'] = 'collapse'; if (!$this->isPdf) { $css['table']['page-break-after'] = 'always'; } // .gridlines td { } $css['.gridlines td']['border'] = '1px dotted black'; $css['.gridlines th']['border'] = '1px dotted black'; // .b {} $css['.b']['text-align'] = 'center'; // BOOL // .e {} $css['.e']['text-align'] = 'center'; // ERROR // .f {} $css['.f']['text-align'] = 'right'; // FORMULA // .inlineStr {} $css['.inlineStr']['text-align'] = 'left'; // INLINE // .n {} $css['.n']['text-align'] = 'right'; // NUMERIC // .s {} $css['.s']['text-align'] = 'left'; // STRING // Calculate cell style hashes foreach ($this->phpExcel->getCellXfCollection() as $index => $style) { $css['td.style' . $index] = $this->createCSSStyle($style); $css['th.style' . $index] = $this->createCSSStyle($style); } // Fetch sheets $sheets = array(); if (is_null($this->sheetIndex)) { $sheets = $this->phpExcel->getAllSheets(); } else { $sheets[] = $this->phpExcel->getSheet($this->sheetIndex); } // Build styles per sheet foreach ($sheets as $sheet) { // Calculate hash code $sheetIndex = $sheet->getParent()->getIndex($sheet); // Build styles // Calculate column widths $sheet->calculateColumnWidths(); // col elements, initialize $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; $column = -1; while ($column++ < $highestColumnIndex) { $this->columnWidths[$sheetIndex][$column] = 42; // approximation $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; } // col elements, loop through columnDimensions and set width foreach ($sheet->getColumnDimensions() as $columnDimension) { if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->defaultFont)) >= 0) { $width = PHPExcel_Shared_Drawing::pixelsToPoints($width); $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1; $this->columnWidths[$sheetIndex][$column] = $width; $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt'; if ($columnDimension->getVisible() === false) { $css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse'; $css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7 } } } // Default row height $rowDimension = $sheet->getDefaultRowDimension(); // table.sheetN tr { } $css['table.sheet' . $sheetIndex . ' tr'] = array(); if ($rowDimension->getRowHeight() == -1) { $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->phpExcel->getDefaultStyle()->getFont()); } else { $pt_height = $rowDimension->getRowHeight(); } $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt'; if ($rowDimension->getVisible() === false) { $css['table.sheet' . $sheetIndex . ' tr']['display'] = 'none'; $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden'; } // Calculate row heights foreach ($sheet->getRowDimensions() as $rowDimension) { $row = $rowDimension->getRowIndex() - 1; // table.sheetN tr.rowYYYYYY { } $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array(); if ($rowDimension->getRowHeight() == -1) { $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->phpExcel->getDefaultStyle()->getFont()); } else { $pt_height = $rowDimension->getRowHeight(); } $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt'; if ($rowDimension->getVisible() === false) { $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none'; $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden'; } } } // Cache if (is_null($this->cssStyles)) { $this->cssStyles = $css; } // Return return $css; } /** * Create CSS style * * @param PHPExcel_Style $pStyle PHPExcel_Style * @return array */ private function createCSSStyle(PHPExcel_Style $pStyle) { // Construct CSS $css = ''; // Create CSS $css = array_merge( $this->createCSSStyleAlignment($pStyle->getAlignment()), $this->createCSSStyleBorders($pStyle->getBorders()), $this->createCSSStyleFont($pStyle->getFont()), $this->createCSSStyleFill($pStyle->getFill()) ); // Return return $css; } /** * Create CSS style (PHPExcel_Style_Alignment) * * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment * @return array */ private function createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { // Construct CSS $css = array(); // Create CSS $css['vertical-align'] = $this->mapVAlign($pStyle->getVertical()); if ($textAlign = $this->mapHAlign($pStyle->getHorizontal())) { $css['text-align'] = $textAlign; if (in_array($textAlign, array('left', 'right'))) { $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; } } return $css; } /** * Create CSS style (PHPExcel_Style_Font) * * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font * @return array */ private function createCSSStyleFont(PHPExcel_Style_Font $pStyle) { // Construct CSS $css = array(); // Create CSS if ($pStyle->getBold()) { $css['font-weight'] = 'bold'; } if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) { $css['text-decoration'] = 'underline line-through'; } elseif ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { $css['text-decoration'] = 'underline'; } elseif ($pStyle->getStrikethrough()) { $css['text-decoration'] = 'line-through'; } if ($pStyle->getItalic()) { $css['font-style'] = 'italic'; } $css['color'] = '#' . $pStyle->getColor()->getRGB(); $css['font-family'] = '\'' . $pStyle->getName() . '\''; $css['font-size'] = $pStyle->getSize() . 'pt'; return $css; } /** * Create CSS style (PHPExcel_Style_Borders) * * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders * @return array */ private function createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { // Construct CSS $css = array(); // Create CSS $css['border-bottom'] = $this->createCSSStyleBorder($pStyle->getBottom()); $css['border-top'] = $this->createCSSStyleBorder($pStyle->getTop()); $css['border-left'] = $this->createCSSStyleBorder($pStyle->getLeft()); $css['border-right'] = $this->createCSSStyleBorder($pStyle->getRight()); return $css; } /** * Create CSS style (PHPExcel_Style_Border) * * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border * @return string */ private function createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { // Create CSS // $css = $this->mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); // Create CSS - add !important to non-none border styles for merged cells $borderStyle = $this->mapBorderStyle($pStyle->getBorderStyle()); $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); return $css; } /** * Create CSS style (PHPExcel_Style_Fill) * * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill * @return array */ private function createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { // Construct HTML $css = array(); // Create CSS $value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ? 'white' : '#' . $pStyle->getStartColor()->getRGB(); $css['background-color'] = $value; return $css; } /** * Generate HTML footer */ public function generateHTMLFooter() { // Construct HTML $html = ''; $html .= ' ' . PHP_EOL; $html .= '' . PHP_EOL; return $html; } /** * Generate table header * * @param PHPExcel_Worksheet $pSheet The worksheet for the table we are writing * @return string * @throws PHPExcel_Writer_Exception */ private function generateTableHeader($pSheet) { $sheetIndex = $pSheet->getParent()->getIndex($pSheet); // Construct HTML $html = ''; $html .= $this->setMargins($pSheet); if (!$this->useInlineCss) { $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; $html .= ' ' . PHP_EOL; } else { $style = isset($this->cssStyles['table']) ? $this->assembleCSS($this->cssStyles['table']) : ''; if ($this->isPdf && $pSheet->getShowGridlines()) { $html .= '
' . PHP_EOL; } else { $html .= '
' . PHP_EOL; } } // Write elements $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; $i = -1; while ($i++ < $highestColumnIndex) { if (!$this->isPdf) { if (!$this->useInlineCss) { $html .= ' ' . PHP_EOL; } else { $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; $html .= ' ' . PHP_EOL; } } } return $html; } /** * Generate table footer * * @throws PHPExcel_Writer_Exception */ private function generateTableFooter() { $html = '
' . PHP_EOL; return $html; } /** * Generate row * * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet * @param array $pValues Array containing cells in a row * @param int $pRow Row number (0-based) * @return string * @throws PHPExcel_Writer_Exception */ private function generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') { if (is_array($pValues)) { // Construct HTML $html = ''; // Sheet index $sheetIndex = $pSheet->getParent()->getIndex($pSheet); // DomPDF and breaks if ($this->isPdf && count($pSheet->getBreaks()) > 0) { $breaks = $pSheet->getBreaks(); // check if a break is needed before this row if (isset($breaks['A' . $pRow])) { // close table: $html .= $this->generateTableFooter(); // insert page break $html .= '
'; // open table again: + etc. $html .= $this->generateTableHeader($pSheet); } } // Write row start if (!$this->useInlineCss) { $html .= ' ' . PHP_EOL; } else { $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; $html .= ' ' . PHP_EOL; } // Write cells $colNum = 0; foreach ($pValues as $cellAddress) { $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : ''; $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); if (!$this->useInlineCss) { $cssClass = ''; $cssClass = 'column' . $colNum; } else { $cssClass = array(); if ($cellType == 'th') { if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) { $this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum]; } } else { if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { $this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; } } } $colSpan = 1; $rowSpan = 1; // initialize $cellData = ' '; // PHPExcel_Cell if ($cell instanceof PHPExcel_Cell) { $cellData = ''; if (is_null($cell->getParent())) { $cell->attach($pSheet); } // Value if ($cell->getValue() instanceof PHPExcel_RichText) { // Loop through rich text elements $elements = $cell->getValue()->getRichTextElements(); foreach ($elements as $element) { // Rich text start? if ($element instanceof PHPExcel_RichText_Run) { $cellData .= ''; if ($element->getFont()->getSuperScript()) { $cellData .= ''; } elseif ($element->getFont()->getSubScript()) { $cellData .= ''; } } // Convert UTF8 data to PCDATA $cellText = $element->getText(); $cellData .= htmlspecialchars($cellText); if ($element instanceof PHPExcel_RichText_Run) { if ($element->getFont()->getSuperScript()) { $cellData .= ''; } elseif ($element->getFont()->getSubScript()) { $cellData .= ''; } $cellData .= ''; } } } else { if ($this->preCalculateFormulas) { $cellData = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getCalculatedValue(), $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(), array($this, 'formatColor') ); } else { $cellData = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getValue(), $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(), array($this, 'formatColor') ); } $cellData = htmlspecialchars($cellData); if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperScript()) { $cellData = ''.$cellData.''; } elseif ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSubScript()) { $cellData = ''.$cellData.''; } } // Converts the cell content so that spaces occuring at beginning of each new line are replaced by   // Example: " Hello\n to the world" is converted to "  Hello\n to the world" $cellData = preg_replace("/(?m)(?:^|\\G) /", ' ', $cellData); // convert newline "\n" to '
' $cellData = nl2br($cellData); // Extend CSS class? if (!$this->useInlineCss) { $cssClass .= ' style' . $cell->getXfIndex(); $cssClass .= ' ' . $cell->getDataType(); } else { if ($cellType == 'th') { if (isset($this->cssStyles['th.style' . $cell->getXfIndex()])) { $cssClass = array_merge($cssClass, $this->cssStyles['th.style' . $cell->getXfIndex()]); } } else { if (isset($this->cssStyles['td.style' . $cell->getXfIndex()])) { $cssClass = array_merge($cssClass, $this->cssStyles['td.style' . $cell->getXfIndex()]); } } // General horizontal alignment: Actual horizontal alignment depends on dataType $sharedStyle = $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex()); if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL && isset($this->cssStyles['.' . $cell->getDataType()]['text-align'])) { $cssClass['text-align'] = $this->cssStyles['.' . $cell->getDataType()]['text-align']; } } } // Hyperlink? if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) { $cellData = '' . $cellData . ''; } // Should the cell be written or is it swallowed by a rowspan or colspan? $writeCell = !(isset($this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) && $this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]); // Colspan and Rowspan $colspan = 1; $rowspan = 1; if (isset($this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { $spans = $this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; $rowSpan = $spans['rowspan']; $colSpan = $spans['colspan']; // Also apply style from last cell in merge to fix borders - // relies on !important for non-none border declarations in createCSSStyleBorder $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); if (!$this->useInlineCss) { $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); } } // Write if ($writeCell) { // Column start $html .= ' <' . $cellType; if (!$this->useInlineCss) { $html .= ' class="' . $cssClass . '"'; } else { //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** // We must explicitly write the width of the $width = 0; $i = $colNum - 1; $e = $colNum + $colSpan - 1; while ($i++ < $e) { if (isset($this->columnWidths[$sheetIndex][$i])) { $width += $this->columnWidths[$sheetIndex][$i]; } } $cssClass['width'] = $width . 'pt'; // We must also explicitly write the height of the if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { $height = $this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; $cssClass['height'] = $height; } //** end of redundant code ** $html .= ' style="' . $this->assembleCSS($cssClass) . '"'; } if ($colSpan > 1) { $html .= ' colspan="' . $colSpan . '"'; } if ($rowSpan > 1) { $html .= ' rowspan="' . $rowSpan . '"'; } $html .= '>'; // Image? $html .= $this->writeImageInCell($pSheet, $coordinate); // Chart? if ($this->includeCharts) { $html .= $this->writeChartInCell($pSheet, $coordinate); } // Cell data $html .= $cellData; // Column end $html .= '' . PHP_EOL; } // Next column ++$colNum; } // Write row end $html .= ' ' . PHP_EOL; // Return return $html; } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); } } /** * Takes array where of CSS properties / values and converts to CSS string * * @param array * @return string */ private function assembleCSS($pValue = array()) { $pairs = array(); foreach ($pValue as $property => $value) { $pairs[] = $property . ':' . $value; } $string = implode('; ', $pairs); return $string; } /** * Get images root * * @return string */ public function getImagesRoot() { return $this->imagesRoot; } /** * Set images root * * @param string $pValue * @return PHPExcel_Writer_HTML */ public function setImagesRoot($pValue = '.') { $this->imagesRoot = $pValue; return $this; } /** * Get embed images * * @return boolean */ public function getEmbedImages() { return $this->embedImages; } /** * Set embed images * * @param boolean $pValue * @return PHPExcel_Writer_HTML */ public function setEmbedImages($pValue = '.') { $this->embedImages = $pValue; return $this; } /** * Get use inline CSS? * * @return boolean */ public function getUseInlineCss() { return $this->useInlineCss; } /** * Set use inline CSS? * * @param boolean $pValue * @return PHPExcel_Writer_HTML */ public function setUseInlineCss($pValue = false) { $this->useInlineCss = $pValue; return $this; } /** * Add color to formatted string as inline style * * @param string $pValue Plain formatted value without color * @param string $pFormat Format code * @return string */ public function formatColor($pValue, $pFormat) { // Color information, e.g. [Red] is always at the beginning $color = null; // initialize $matches = array(); $color_regex = '/^\\[[a-zA-Z]+\\]/'; if (preg_match($color_regex, $pFormat, $matches)) { $color = str_replace('[', '', $matches[0]); $color = str_replace(']', '', $color); $color = strtolower($color); } // convert to PCDATA $value = htmlspecialchars($pValue); // color span tag if ($color !== null) { $value = '' . $value . ''; } return $value; } /** * Calculate information about HTML colspan and rowspan which is not always the same as Excel's */ private function calculateSpans() { // Identify all cells that should be omitted in HTML due to cell merge. // In HTML only the upper-left cell should be written and it should have // appropriate rowspan / colspan attribute $sheetIndexes = $this->sheetIndex !== null ? array($this->sheetIndex) : range(0, $this->phpExcel->getSheetCount() - 1); foreach ($sheetIndexes as $sheetIndex) { $sheet = $this->phpExcel->getSheet($sheetIndex); $candidateSpannedRow = array(); // loop through all Excel merged cells foreach ($sheet->getMergeCells() as $cells) { list($cells,) = PHPExcel_Cell::splitRange($cells); $first = $cells[0]; $last = $cells[1]; list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first); $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1; list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last); $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1; // loop through the individual cells in the individual merge $r = $fr - 1; while ($r++ < $lr) { // also, flag this row as a HTML row that is candidate to be omitted $candidateSpannedRow[$r] = $r; $c = $fc - 1; while ($c++ < $lc) { if (!($c == $fc && $r == $fr)) { // not the upper-left cell (should not be written in HTML) $this->isSpannedCell[$sheetIndex][$r][$c] = array( 'baseCell' => array($fr, $fc), ); } else { // upper-left is the base cell that should hold the colspan/rowspan attribute $this->isBaseCell[$sheetIndex][$r][$c] = array( 'xlrowspan' => $lr - $fr + 1, // Excel rowspan 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change 'xlcolspan' => $lc - $fc + 1, // Excel colspan 'colspan' => $lc - $fc + 1, // HTML colspan, value may change ); } } } } // Identify which rows should be omitted in HTML. These are the rows where all the cells // participate in a merge and the where base cells are somewhere above. $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()); foreach ($candidateSpannedRow as $rowIndex) { if (isset($this->isSpannedCell[$sheetIndex][$rowIndex])) { if (count($this->isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { $this->isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; }; } } // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 if (isset($this->isSpannedRow[$sheetIndex])) { foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) { $adjustedBaseCells = array(); $c = -1; $e = $countColumns - 1; while ($c++ < $e) { $baseCell = $this->isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; if (!in_array($baseCell, $adjustedBaseCells)) { // subtract rowspan by 1 --$this->isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; $adjustedBaseCells[] = $baseCell; } } } } // TODO: Same for columns } // We have calculated the spans $this->spansAreCalculated = true; } private function setMargins(PHPExcel_Worksheet $pSheet) { $htmlPage = '@page { '; $htmlBody = 'body { '; $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; $htmlPage .= 'margin-left: ' . $left; $htmlBody .= 'margin-left: ' . $left; $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; $htmlPage .= 'margin-right: ' . $right; $htmlBody .= 'margin-right: ' . $right; $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; $htmlPage .= 'margin-top: ' . $top; $htmlBody .= 'margin-top: ' . $top; $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; $htmlPage .= 'margin-bottom: ' . $bottom; $htmlBody .= 'margin-bottom: ' . $bottom; $htmlPage .= "}\n"; $htmlBody .= "}\n"; return "\n"; } } PK! PDF/mPDF.phpnu[getSheetIndex())) { $orientation = ($this->phpExcel->getSheet(0)->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); $printMargins = $this->phpExcel->getSheet(0)->getPageMargins(); } else { $orientation = ($this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); $printMargins = $this->phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } $this->setOrientation($orientation); // Override Page Orientation if (!is_null($this->getOrientation())) { $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT : $this->getOrientation(); } $orientation = strtoupper($orientation); // Override Paper Size if (!is_null($this->getPaperSize())) { $printPaperSize = $this->getPaperSize(); } if (isset(self::$paperSizes[$printPaperSize])) { $paperSize = self::$paperSizes[$printPaperSize]; } // Create PDF $pdf = new mpdf(); $ortmp = $orientation; $pdf->_setPageSize(strtoupper($paperSize), $ortmp); $pdf->DefOrientation = $orientation; $pdf->AddPage($orientation); // Document info $pdf->SetTitle($this->phpExcel->getProperties()->getTitle()); $pdf->SetAuthor($this->phpExcel->getProperties()->getCreator()); $pdf->SetSubject($this->phpExcel->getProperties()->getSubject()); $pdf->SetKeywords($this->phpExcel->getProperties()->getKeywords()); $pdf->SetCreator($this->phpExcel->getProperties()->getCreator()); $pdf->WriteHTML( $this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter() ); // Write to file fwrite($fileHandle, $pdf->Output('', 'S')); parent::restoreStateAfterSave($fileHandle); } } PK!S / PDF/tcPDF.phpnu[getSheetIndex())) { $orientation = ($this->phpExcel->getSheet(0)->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); $printMargins = $this->phpExcel->getSheet(0)->getPageMargins(); } else { $orientation = ($this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); $printMargins = $this->phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } // Override Page Orientation if (!is_null($this->getOrientation())) { $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; } // Override Paper Size if (!is_null($this->getPaperSize())) { $printPaperSize = $this->getPaperSize(); } if (isset(self::$paperSizes[$printPaperSize])) { $paperSize = self::$paperSizes[$printPaperSize]; } // Create PDF $pdf = new TCPDF($orientation, 'pt', $paperSize); $pdf->setFontSubsetting(false); // Set margins, converting inches to points (using 72 dpi) $pdf->SetMargins($printMargins->getLeft() * 72, $printMargins->getTop() * 72, $printMargins->getRight() * 72); $pdf->SetAutoPageBreak(true, $printMargins->getBottom() * 72); $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); $pdf->AddPage(); // Set the appropriate font $pdf->SetFont($this->getFont()); $pdf->writeHTML( $this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter() ); // Document info $pdf->SetTitle($this->phpExcel->getProperties()->getTitle()); $pdf->SetAuthor($this->phpExcel->getProperties()->getCreator()); $pdf->SetSubject($this->phpExcel->getProperties()->getSubject()); $pdf->SetKeywords($this->phpExcel->getProperties()->getKeywords()); $pdf->SetCreator($this->phpExcel->getProperties()->getCreator()); // Write to file fwrite($fileHandle, $pdf->output($pFilename, 'S')); parent::restoreStateAfterSave($fileHandle); } } PK!  PDF/DomPDF.phpnu[getSheetIndex())) { $orientation = ($this->phpExcel->getSheet(0)->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); $printMargins = $this->phpExcel->getSheet(0)->getPageMargins(); } else { $orientation = ($this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); $printMargins = $this->phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; // Override Page Orientation if (!is_null($this->getOrientation())) { $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT : $this->getOrientation(); } // Override Paper Size if (!is_null($this->getPaperSize())) { $printPaperSize = $this->getPaperSize(); } if (isset(self::$paperSizes[$printPaperSize])) { $paperSize = self::$paperSizes[$printPaperSize]; } // Create PDF $pdf = new DOMPDF(); $pdf->set_paper(strtolower($paperSize), $orientation); $pdf->load_html( $this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter() ); $pdf->render(); // Write to file fwrite($fileHandle, $pdf->output()); parent::restoreStateAfterSave($fileHandle); } } PK!cS6S6 PDF/Core.phpnu[ 'LETTER', // (8.5 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_SMALL => 'LETTER', // (8.5 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID => array(792.00, 1224.00), // (11 in. by 17 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEDGER => array(1224.00, 792.00), // (17 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL => 'LEGAL', // (8.5 in. by 14 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_STATEMENT => array(396.00, 612.00), // (5.5 in. by 8.5 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_EXECUTIVE => 'EXECUTIVE', // (7.25 in. by 10.5 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3 => 'A3', // (297 mm by 420 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4 => 'A4', // (210 mm by 297 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_SMALL => 'A4', // (210 mm by 297 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5 => 'A5', // (148 mm by 210 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4 => 'B4', // (250 mm by 353 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5 => 'B5', // (176 mm by 250 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_FOLIO => 'FOLIO', // (8.5 in. by 13 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_QUARTO => array(609.45, 779.53), // (215 mm by 275 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_1 => array(720.00, 1008.00), // (10 in. by 14 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_2 => array(792.00, 1224.00), // (11 in. by 17 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_NOTE => 'LETTER', // (8.5 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO9_ENVELOPE => array(279.00, 639.00), // (3.875 in. by 8.875 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO10_ENVELOPE => array(297.00, 684.00), // (4.125 in. by 9.5 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO11_ENVELOPE => array(324.00, 747.00), // (4.5 in. by 10.375 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO12_ENVELOPE => array(342.00, 792.00), // (4.75 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO14_ENVELOPE => array(360.00, 828.00), // (5 in. by 11.5 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_C => array(1224.00, 1584.00), // (17 in. by 22 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_D => array(1584.00, 2448.00), // (22 in. by 34 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_E => array(2448.00, 3168.00), // (34 in. by 44 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_DL_ENVELOPE => array(311.81, 623.62), // (110 mm by 220 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_C5_ENVELOPE => 'C5', // (162 mm by 229 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_C3_ENVELOPE => 'C3', // (324 mm by 458 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_C4_ENVELOPE => 'C4', // (229 mm by 324 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_C6_ENVELOPE => 'C6', // (114 mm by 162 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_C65_ENVELOPE => array(323.15, 649.13), // (114 mm by 229 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4_ENVELOPE => 'B4', // (250 mm by 353 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5_ENVELOPE => 'B5', // (176 mm by 250 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_B6_ENVELOPE => array(498.90, 354.33), // (176 mm by 125 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_ITALY_ENVELOPE => array(311.81, 651.97), // (110 mm by 230 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_MONARCH_ENVELOPE => array(279.00, 540.00), // (3.875 in. by 7.5 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_6_3_4_ENVELOPE => array(261.00, 468.00), // (3.625 in. by 6.5 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_US_STANDARD_FANFOLD => array(1071.00, 792.00), // (14.875 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_STANDARD_FANFOLD => array(612.00, 864.00), // (8.5 in. by 12 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_LEGAL_FANFOLD => 'FOLIO', // (8.5 in. by 13 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B4 => 'B4', // (250 mm by 353 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_JAPANESE_DOUBLE_POSTCARD => array(566.93, 419.53), // (200 mm by 148 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_1 => array(648.00, 792.00), // (9 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_2 => array(720.00, 792.00), // (10 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_3 => array(1080.00, 792.00), // (15 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_INVITE_ENVELOPE => array(623.62, 623.62), // (220 mm by 220 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_PAPER => array(667.80, 864.00), // (9.275 in. by 12 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL_EXTRA_PAPER => array(667.80, 1080.00), // (9.275 in. by 15 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID_EXTRA_PAPER => array(841.68, 1296.00), // (11.69 in. by 18 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_EXTRA_PAPER => array(668.98, 912.76), // (236 mm by 322 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_TRANSVERSE_PAPER => array(595.80, 792.00), // (8.275 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_TRANSVERSE_PAPER => 'A4', // (210 mm by 297 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER => array(667.80, 864.00), // (9.275 in. by 12 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERA_SUPERA_A4_PAPER => array(643.46, 1009.13), // (227 mm by 356 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERB_SUPERB_A3_PAPER => array(864.57, 1380.47), // (305 mm by 487 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_PLUS_PAPER => array(612.00, 913.68), // (8.5 in. by 12.69 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_PLUS_PAPER => array(595.28, 935.43), // (210 mm by 330 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_TRANSVERSE_PAPER => 'A5', // (148 mm by 210 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_JIS_B5_TRANSVERSE_PAPER => array(515.91, 728.50), // (182 mm by 257 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_PAPER => array(912.76, 1261.42), // (322 mm by 445 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_EXTRA_PAPER => array(493.23, 666.14), // (174 mm by 235 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B5_EXTRA_PAPER => array(569.76, 782.36), // (201 mm by 276 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A2_PAPER => 'A2', // (420 mm by 594 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_TRANSVERSE_PAPER => 'A3', // (297 mm by 420 mm) PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER => array(912.76, 1261.42) // (322 mm by 445 mm) ); /** * Create a new PHPExcel_Writer_PDF * * @param PHPExcel $phpExcel PHPExcel object */ public function __construct(PHPExcel $phpExcel) { parent::__construct($phpExcel); $this->setUseInlineCss(true); $this->tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); } /** * Get Font * * @return string */ public function getFont() { return $this->font; } /** * Set font. Examples: * 'arialunicid0-chinese-simplified' * 'arialunicid0-chinese-traditional' * 'arialunicid0-korean' * 'arialunicid0-japanese' * * @param string $fontName */ public function setFont($fontName) { $this->font = $fontName; return $this; } /** * Get Paper Size * * @return int */ public function getPaperSize() { return $this->paperSize; } /** * Set Paper Size * * @param string $pValue Paper size * @return PHPExcel_Writer_PDF */ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { $this->paperSize = $pValue; return $this; } /** * Get Orientation * * @return string */ public function getOrientation() { return $this->orientation; } /** * Set Orientation * * @param string $pValue Page orientation * @return PHPExcel_Writer_PDF */ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { $this->orientation = $pValue; return $this; } /** * Get temporary storage directory * * @return string */ public function getTempDir() { return $this->tempDir; } /** * Set temporary storage directory * * @param string $pValue Temporary storage directory * @throws PHPExcel_Writer_Exception when directory does not exist * @return PHPExcel_Writer_PDF */ public function setTempDir($pValue = '') { if (is_dir($pValue)) { $this->tempDir = $pValue; } else { throw new PHPExcel_Writer_Exception("Directory does not exist: $pValue"); } return $this; } /** * Save PHPExcel to PDF file, pre-save * * @param string $pFilename Name of the file to save as * @throws PHPExcel_Writer_Exception */ protected function prepareForSave($pFilename = null) { // garbage collect $this->phpExcel->garbageCollect(); $this->saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); // Open file $fileHandle = fopen($pFilename, 'w'); if ($fileHandle === false) { throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); } // Set PDF $this->isPdf = true; // Build CSS $this->buildCSS(true); return $fileHandle; } /** * Save PHPExcel to PDF file, post-save * * @param resource $fileHandle * @throws PHPExcel_Writer_Exception */ protected function restoreStateAfterSave($fileHandle) { // Close file fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($this->saveArrayReturnType); } } PK!3CbDD IWriter.phpnu[phpExcel = $phpExcel; $this->parser = new PHPExcel_Writer_Excel5_Parser(); } /** * Save PHPExcel to file * * @param string $pFilename * @throws PHPExcel_Writer_Exception */ public function save($pFilename = null) { // garbage collect $this->phpExcel->garbageCollect(); $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog(); PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // initialize colors array $this->colors = array(); // Initialise workbook writer $this->writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->phpExcel, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser); // Initialise worksheet writers $countSheets = $this->phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { $this->writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->phpExcel->getSheet($i)); } // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. $this->buildWorksheetEschers(); $this->buildWorkbookEscher(); // add 15 identical cell style Xfs // for now, we use the first cellXf instead of cellStyleXf $cellXfCollection = $this->phpExcel->getCellXfCollection(); for ($i = 0; $i < 15; ++$i) { $this->writerWorkbook->addXfWriter($cellXfCollection[0], true); } // add all the cell Xfs foreach ($this->phpExcel->getCellXfCollection() as $style) { $this->writerWorkbook->addXfWriter($style, false); } // add fonts from rich text eleemnts for ($i = 0; $i < $countSheets; ++$i) { foreach ($this->writerWorksheets[$i]->phpSheet->getCellCollection() as $cellID) { $cell = $this->writerWorksheets[$i]->phpSheet->getCell($cellID); $cVal = $cell->getValue(); if ($cVal instanceof PHPExcel_RichText) { $elements = $cVal->getRichTextElements(); foreach ($elements as $element) { if ($element instanceof PHPExcel_RichText_Run) { $font = $element->getFont(); $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font); } } } } } // initialize OLE file $workbookStreamName = 'Workbook'; $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); // Write the worksheet streams before the global workbook stream, // because the byte sizes of these are needed in the global workbook stream $worksheetSizes = array(); for ($i = 0; $i < $countSheets; ++$i) { $this->writerWorksheets[$i]->close(); $worksheetSizes[] = $this->writerWorksheets[$i]->_datasize; } // add binary data for global workbook stream $OLE->append($this->writerWorkbook->writeWorkbook($worksheetSizes)); // add binary data for sheet streams for ($i = 0; $i < $countSheets; ++$i) { $OLE->append($this->writerWorksheets[$i]->getData()); } $this->documentSummaryInformation = $this->writeDocumentSummaryInformation(); // initialize OLE Document Summary Information if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) { $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); $OLE_DocumentSummaryInformation->append($this->documentSummaryInformation); } $this->summaryInformation = $this->writeSummaryInformation(); // initialize OLE Summary Information if (isset($this->summaryInformation) && !empty($this->summaryInformation)) { $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); $OLE_SummaryInformation->append($this->summaryInformation); } // define OLE Parts $arrRootData = array($OLE); // initialize OLE Properties file if (isset($OLE_SummaryInformation)) { $arrRootData[] = $OLE_SummaryInformation; } // initialize OLE Extended Properties file if (isset($OLE_DocumentSummaryInformation)) { $arrRootData[] = $OLE_DocumentSummaryInformation; } $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData); // save the OLE file $res = $root->save($pFilename); PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** * Set temporary storage directory * * @deprecated * @param string $pValue Temporary storage directory * @throws PHPExcel_Writer_Exception when directory does not exist * @return PHPExcel_Writer_Excel5 */ public function setTempDir($pValue = '') { return $this; } /** * Build the Worksheet Escher objects * */ private function buildWorksheetEschers() { // 1-based index to BstoreContainer $blipIndex = 0; $lastReducedSpId = 0; $lastSpId = 0; foreach ($this->phpExcel->getAllsheets() as $sheet) { // sheet index $sheetIndex = $sheet->getParent()->getIndex($sheet); $escher = null; // check if there are any shapes for this sheet $filterRange = $sheet->getAutoFilter()->getRange(); if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) { continue; } // create intermediate Escher object $escher = new PHPExcel_Shared_Escher(); // dgContainer $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); // set the drawing index (we use sheet index + 1) $dgId = $sheet->getParent()->getIndex($sheet) + 1; $dgContainer->setDgId($dgId); $escher->setDgContainer($dgContainer); // spgrContainer $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); $dgContainer->setSpgrContainer($spgrContainer); // add one shape which is the group shape $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); $spContainer->setSpgr(true); $spContainer->setSpType(0); $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10); $spgrContainer->addChild($spContainer); // add the shapes $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet foreach ($sheet->getDrawingCollection() as $drawing) { ++$blipIndex; ++$countShapes[$sheetIndex]; // add the shape $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); // set the shape type $spContainer->setSpType(0x004B); // set the shape flag $spContainer->setSpFlag(0x02); // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) $reducedSpId = $countShapes[$sheetIndex]; $spId = $reducedSpId | ($sheet->getParent()->getIndex($sheet) + 1) << 10; $spContainer->setSpId($spId); // keep track of last reducedSpId $lastReducedSpId = $reducedSpId; // keep track of last spId $lastSpId = $spId; // set the BLIP index $spContainer->setOPT(0x4104, $blipIndex); // set coordinates and offsets, client anchor $coordinates = $drawing->getCoordinates(); $offsetX = $drawing->getOffsetX(); $offsetY = $drawing->getOffsetY(); $width = $drawing->getWidth(); $height = $drawing->getHeight(); $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); $spContainer->setEndCoordinates($twoAnchor['endCoordinates']); $spContainer->setEndOffsetX($twoAnchor['endOffsetX']); $spContainer->setEndOffsetY($twoAnchor['endOffsetY']); $spgrContainer->addChild($spContainer); } // AutoFilters if (!empty($filterRange)) { $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); $iNumColStart = $rangeBounds[0][0]; $iNumColEnd = $rangeBounds[1][0]; $iInc = $iNumColStart; while ($iInc <= $iNumColEnd) { ++$countShapes[$sheetIndex]; // create an Drawing Object for the dropdown $oDrawing = new PHPExcel_Worksheet_BaseDrawing(); // get the coordinates of drawing $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; $oDrawing->setCoordinates($cDrawing); $oDrawing->setWorksheet($sheet); // add the shape $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); // set the shape type $spContainer->setSpType(0x00C9); // set the shape flag $spContainer->setSpFlag(0x01); // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) $reducedSpId = $countShapes[$sheetIndex]; $spId = $reducedSpId | ($sheet->getParent()->getIndex($sheet) + 1) << 10; $spContainer->setSpId($spId); // keep track of last reducedSpId $lastReducedSpId = $reducedSpId; // keep track of last spId $lastSpId = $spId; $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint // set coordinates and offsets, client anchor $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1)); $endCoordinates .= $rangeBounds[0][1] + 1; $spContainer->setStartCoordinates($cDrawing); $spContainer->setStartOffsetX(0); $spContainer->setStartOffsetY(0); $spContainer->setEndCoordinates($endCoordinates); $spContainer->setEndOffsetX(0); $spContainer->setEndOffsetY(0); $spgrContainer->addChild($spContainer); $iInc++; } } // identifier clusters, used for workbook Escher object $this->IDCLs[$dgId] = $lastReducedSpId; // set last shape index $dgContainer->setLastSpId($lastSpId); // set the Escher object $this->writerWorksheets[$sheetIndex]->setEscher($escher); } } /** * Build the Escher object corresponding to the MSODRAWINGGROUP record */ private function buildWorkbookEscher() { $escher = null; // any drawings in this workbook? $found = false; foreach ($this->phpExcel->getAllSheets() as $sheet) { if (count($sheet->getDrawingCollection()) > 0) { $found = true; break; } } // nothing to do if there are no drawings if (!$found) { return; } // if we reach here, then there are drawings in the workbook $escher = new PHPExcel_Shared_Escher(); // dggContainer $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); $escher->setDggContainer($dggContainer); // set IDCLs (identifier clusters) $dggContainer->setIDCLs($this->IDCLs); // this loop is for determining maximum shape identifier of all drawing $spIdMax = 0; $totalCountShapes = 0; $countDrawings = 0; foreach ($this->phpExcel->getAllsheets() as $sheet) { $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet if (count($sheet->getDrawingCollection()) > 0) { ++$countDrawings; foreach ($sheet->getDrawingCollection() as $drawing) { ++$sheetCountShapes; ++$totalCountShapes; $spId = $sheetCountShapes | ($this->phpExcel->getIndex($sheet) + 1) << 10; $spIdMax = max($spId, $spIdMax); } } } $dggContainer->setSpIdMax($spIdMax + 1); $dggContainer->setCDgSaved($countDrawings); $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing // bstoreContainer $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); $dggContainer->setBstoreContainer($bstoreContainer); // the BSE's (all the images) foreach ($this->phpExcel->getAllsheets() as $sheet) { foreach ($sheet->getDrawingCollection() as $drawing) { if ($drawing instanceof PHPExcel_Worksheet_Drawing) { $filename = $drawing->getPath(); list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); switch ($imageFormat) { case 1: // GIF, not supported by BIFF8, we convert to PNG $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; ob_start(); imagepng(imagecreatefromgif($filename)); $blipData = ob_get_contents(); ob_end_clean(); break; case 2: // JPEG $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; $blipData = file_get_contents($filename); break; case 3: // PNG $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; $blipData = file_get_contents($filename); break; case 6: // Windows DIB (BMP), we convert to PNG $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; ob_start(); imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); $blipData = ob_get_contents(); ob_end_clean(); break; default: continue 2; } $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); $blip->setData($blipData); $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); $BSE->setBlipType($blipType); $BSE->setBlip($blip); $bstoreContainer->addBSE($BSE); } elseif ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { switch ($drawing->getRenderingFunction()) { case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; $renderingFunction = 'imagejpeg'; break; case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; $renderingFunction = 'imagepng'; break; } ob_start(); call_user_func($renderingFunction, $drawing->getImageResource()); $blipData = ob_get_contents(); ob_end_clean(); $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); $blip->setData($blipData); $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); $BSE->setBlipType($blipType); $BSE->setBlip($blip); $bstoreContainer->addBSE($BSE); } } } // Set the Escher object $this->writerWorkbook->setEscher($escher); } /** * Build the OLE Part for DocumentSummary Information * @return string */ private function writeDocumentSummaryInformation() { // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) $data = pack('v', 0xFFFE); // offset: 2; size: 2; $data .= pack('v', 0x0000); // offset: 4; size: 2; OS version $data .= pack('v', 0x0106); // offset: 6; size: 2; OS indicator $data .= pack('v', 0x0002); // offset: 8; size: 16 $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); // offset: 24; size: 4; section count $data .= pack('V', 0x0001); // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9); // offset: 44; size: 4; offset of the start $data .= pack('V', 0x30); // SECTION $dataSection = array(); $dataSection_NumProps = 0; $dataSection_Summary = ''; $dataSection_Content = ''; // GKPIDDSI_CODEPAGE: CodePage $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer 'data' => array('data' => 1252)); $dataSection_NumProps++; // GKPIDDSI_CATEGORY : Category if ($this->phpExcel->getProperties()->getCategory()) { $dataProp = $this->phpExcel->getProperties()->getCategory(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // GKPIDDSI_VERSION :Version of the application that wrote the property storage $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x03), 'data' => array('pack' => 'V', 'data' => 0x000C0000)); $dataSection_NumProps++; // GKPIDDSI_SCALE : FALSE $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x0B), 'data' => array('data' => false)); $dataSection_NumProps++; // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x0B), 'data' => array('data' => false)); $dataSection_NumProps++; // GKPIDDSI_SHAREDOC : FALSE $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x0B), 'data' => array('data' => false)); $dataSection_NumProps++; // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x0B), 'data' => array('data' => false)); $dataSection_NumProps++; // GKPIDDSI_DOCSPARTS // MS-OSHARED p75 (2.3.3.2.2.1) // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9) // cElements $dataProp = pack('v', 0x0001); $dataProp .= pack('v', 0x0000); // array of UnalignedLpstr // cch $dataProp .= pack('v', 0x000A); $dataProp .= pack('v', 0x0000); // value $dataProp .= 'Worksheet'.chr(0); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x101E), 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; // GKPIDDSI_HEADINGPAIR // VtVecHeadingPairValue // cElements $dataProp = pack('v', 0x0002); $dataProp .= pack('v', 0x0000); // Array of vtHeadingPair // vtUnalignedString - headingString // stringType $dataProp .= pack('v', 0x001E); // padding $dataProp .= pack('v', 0x0000); // UnalignedLpstr // cch $dataProp .= pack('v', 0x0013); $dataProp .= pack('v', 0x0000); // value $dataProp .= 'Feuilles de calcul'; // vtUnalignedString - headingParts // wType : 0x0003 = 32 bit signed integer $dataProp .= pack('v', 0x0300); // padding $dataProp .= pack('v', 0x0000); // value $dataProp .= pack('v', 0x0100); $dataProp .= pack('v', 0x0000); $dataProp .= pack('v', 0x0000); $dataProp .= pack('v', 0x0000); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x100C), 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; // 4 Section Length // 4 Property count // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; foreach ($dataSection as $dataProp) { // Summary $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); // Offset $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); // DataType $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); // Data if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } elseif ($dataProp['type']['data'] == 0x0B) { // Boolean if ($dataProp['data']['data'] == false) { $dataSection_Content .= pack('V', 0x0000); } else { $dataSection_Content .= pack('V', 0x0001); } $dataSection_Content_Offset += 4 + 4; } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); $dataProp['data']['length'] += 1; // Complete the string with null string for being a %4 $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); $dataSection_Content .= pack('V', $dataProp['data']['length']); $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 8; } else { // Data Type Not Used at the moment $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + $dataProp['data']['length']; } } // Now $dataSection_Content_Offset contains the size of the content // section header // offset: $secOffset; size: 4; section length // + x Size of the content (summary + content) $data .= pack('V', $dataSection_Content_Offset); // offset: $secOffset+4; size: 4; property count $data .= pack('V', $dataSection_NumProps); // Section Summary $data .= $dataSection_Summary; // Section Content $data .= $dataSection_Content; return $data; } /** * Build the OLE Part for Summary Information * @return string */ private function writeSummaryInformation() { // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) $data = pack('v', 0xFFFE); // offset: 2; size: 2; $data .= pack('v', 0x0000); // offset: 4; size: 2; OS version $data .= pack('v', 0x0106); // offset: 6; size: 2; OS indicator $data .= pack('v', 0x0002); // offset: 8; size: 16 $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); // offset: 24; size: 4; section count $data .= pack('V', 0x0001); // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3); // offset: 44; size: 4; offset of the start $data .= pack('V', 0x30); // SECTION $dataSection = array(); $dataSection_NumProps = 0; $dataSection_Summary = ''; $dataSection_Content = ''; // CodePage : CP-1252 $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer 'data' => array('data' => 1252)); $dataSection_NumProps++; // Title if ($this->phpExcel->getProperties()->getTitle()) { $dataProp = $this->phpExcel->getProperties()->getTitle(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // Subject if ($this->phpExcel->getProperties()->getSubject()) { $dataProp = $this->phpExcel->getProperties()->getSubject(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // Author (Creator) if ($this->phpExcel->getProperties()->getCreator()) { $dataProp = $this->phpExcel->getProperties()->getCreator(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // Keywords if ($this->phpExcel->getProperties()->getKeywords()) { $dataProp = $this->phpExcel->getProperties()->getKeywords(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // Comments (Description) if ($this->phpExcel->getProperties()->getDescription()) { $dataProp = $this->phpExcel->getProperties()->getDescription(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // Last Saved By (LastModifiedBy) if ($this->phpExcel->getProperties()->getLastModifiedBy()) { $dataProp = $this->phpExcel->getProperties()->getLastModifiedBy(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); $dataSection_NumProps++; } // Created Date/Time if ($this->phpExcel->getProperties()->getCreated()) { $dataProp = $this->phpExcel->getProperties()->getCreated(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); $dataSection_NumProps++; } // Modified Date/Time if ($this->phpExcel->getProperties()->getModified()) { $dataProp = $this->phpExcel->getProperties()->getModified(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); $dataSection_NumProps++; } // Security $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer 'data' => array('data' => 0x00)); $dataSection_NumProps++; // 4 Section Length // 4 Property count // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; foreach ($dataSection as $dataProp) { // Summary $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); // Offset $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); // DataType $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); // Data if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); $dataProp['data']['length'] += 1; // Complete the string with null string for being a %4 $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); $dataSection_Content .= pack('V', $dataProp['data']['length']); $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 8; } else { // Data Type Not Used at the moment } } // Now $dataSection_Content_Offset contains the size of the content // section header // offset: $secOffset; size: 4; section length // + x Size of the content (summary + content) $data .= pack('V', $dataSection_Content_Offset); // offset: $secOffset+4; size: 4; property count $data .= pack('V', $dataSection_NumProps); // Section Summary $data .= $dataSection_Summary; // Section Content $data .= $dataSection_Content; return $data; } } PK!w   Exception.phpnu[line = $line; $e->file = $file; throw $e; } } PK!?jUU Excel2007.phpnu[setPHPExcel($pPHPExcel); $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', 'rels' => 'PHPExcel_Writer_Excel2007_Rels', 'theme' => 'PHPExcel_Writer_Excel2007_Theme', 'style' => 'PHPExcel_Writer_Excel2007_Style', 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', 'comments' => 'PHPExcel_Writer_Excel2007_Comments', 'chart' => 'PHPExcel_Writer_Excel2007_Chart', 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' ); // Initialise writer parts // and Assign their parent IWriters foreach ($writerPartsArray as $writer => $class) { $this->writerParts[$writer] = new $class($this); } $hashTablesArray = array( 'stylesConditionalHashTable', 'fillHashTable', 'fontHashTable', 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable', 'styleHashTable' ); // Set HashTable variables foreach ($hashTablesArray as $tableName) { $this->$tableName = new PHPExcel_HashTable(); } } /** * Get writer part * * @param string $pPartName Writer part name * @return PHPExcel_Writer_Excel2007_WriterPart */ public function getWriterPart($pPartName = '') { if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { return $this->writerParts[strtolower($pPartName)]; } else { return null; } } /** * Save PHPExcel to file * * @param string $pFilename * @throws PHPExcel_Writer_Exception */ public function save($pFilename = null) { if ($this->spreadSheet !== null) { // garbage collect $this->spreadSheet->garbageCollect(); // If $pFilename is php://output or php://stdout, make it a temporary file... $originalFilename = $pFilename; if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); if ($pFilename == '') { $pFilename = $originalFilename; } } $saveDebugLog = PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog(); PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Create string lookup table $this->stringTable = array(); for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); } // Create styles dictionaries $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet)); $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet)); $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet)); $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet)); $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet)); $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet)); // Create drawing dictionary $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet)); // Create new ZIP file and open it for writing $zipClass = PHPExcel_Settings::getZipClass(); $objZip = new $zipClass(); // Retrieve OVERWRITE and CREATE constants from the instantiated zip class // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP $ro = new ReflectionObject($objZip); $zipOverWrite = $ro->getConstant('OVERWRITE'); $zipCreate = $ro->getConstant('CREATE'); if (file_exists($pFilename)) { unlink($pFilename); } // Try opening the ZIP file if ($objZip->open($pFilename, $zipOverWrite) !== true) { if ($objZip->open($pFilename, $zipCreate) !== true) { throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing."); } } // Add [Content_Types].xml to ZIP file $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts)); //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) if ($this->spreadSheet->hasMacros()) { $macrosCode=$this->spreadSheet->getMacrosCode(); if (!is_null($macrosCode)) {// we have the code ? $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin if ($this->spreadSheet->hasMacrosCertificate()) {//signed macros ? // Yes : add the certificate file and the related rels file $objZip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate()); $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet)); } } } //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) if ($this->spreadSheet->hasRibbon()) { $tmpRibbonTarget=$this->spreadSheet->getRibbonXMLData('target'); $objZip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data')); if ($this->spreadSheet->hasRibbonBinObjects()) { $tmpRootPath=dirname($tmpRibbonTarget).'/'; $ribbonBinObjects=$this->spreadSheet->getRibbonBinObjects('data');//the files to write foreach ($ribbonBinObjects as $aPath => $aContent) { $objZip->addFromString($tmpRootPath.$aPath, $aContent); } //the rels for files $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet)); } } // Add relationships to ZIP file $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet)); $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet)); // Add document properties to ZIP file $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet)); $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet)); $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet); if ($customPropertiesPart !== null) { $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); } // Add theme to ZIP file $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet)); // Add string table to ZIP file $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable)); // Add styles to ZIP file $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet)); // Add workbook to ZIP file $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas)); $chartCount = 0; // Add worksheets for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts)); if ($this->includeCharts) { $charts = $this->spreadSheet->getSheet($i)->getChartCollection(); if (count($charts) > 0) { foreach ($charts as $chart) { $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas)); $chartCount++; } } } } $chartRef1 = $chartRef2 = 0; // Add worksheet relationships (drawings, ...) for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { // Add relationships $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); if ($this->includeCharts) { $chartCount = $this->spreadSheet->getSheet($i)->getChartCount(); } // Add drawing and image relationship parts if (($drawingCount > 0) || ($chartCount > 0)) { // Drawing relationships $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); // Drawings $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $chartRef2, $this->includeCharts)); } // Add comment relationship parts if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) { // VML Comments $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i))); // Comments $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i))); } // Add header/footer relationship parts if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { // VML Drawings $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i))); // VML Drawing relationships $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i))); // Media foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); } } } // Add media for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { $imageContents = null; $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); if (strpos($imagePath, 'zip://') !== false) { $imagePath = substr($imagePath, 6); $imagePathSplitted = explode('#', $imagePath); $imageZip = new ZipArchive(); $imageZip->open($imagePathSplitted[0]); $imageContents = $imageZip->getFromName($imagePathSplitted[1]); $imageZip->close(); unset($imageZip); } else { $imageContents = file_get_contents($imagePath); } $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { ob_start(); call_user_func( $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), $this->getDrawingHashTable()->getByIndex($i)->getImageResource() ); $imageContents = ob_get_contents(); ob_end_clean(); $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); } } PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); // Close file if ($objZip->close() === false) { throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); } // If a temporary file was used, copy it to the correct file stream if ($originalFilename != $pFilename) { if (copy($pFilename, $originalFilename) === false) { throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); } @unlink($pFilename); } } else { throw new PHPExcel_Writer_Exception("PHPExcel object unassigned."); } } /** * Get PHPExcel object * * @return PHPExcel * @throws PHPExcel_Writer_Exception */ public function getPHPExcel() { if ($this->spreadSheet !== null) { return $this->spreadSheet; } else { throw new PHPExcel_Writer_Exception("No PHPExcel object assigned."); } } /** * Set PHPExcel object * * @param PHPExcel $pPHPExcel PHPExcel object * @throws PHPExcel_Writer_Exception * @return PHPExcel_Writer_Excel2007 */ public function setPHPExcel(PHPExcel $pPHPExcel = null) { $this->spreadSheet = $pPHPExcel; return $this; } /** * Get string table * * @return string[] */ public function getStringTable() { return $this->stringTable; } /** * Get PHPExcel_Style HashTable * * @return PHPExcel_HashTable */ public function getStyleHashTable() { return $this->styleHashTable; } /** * Get PHPExcel_Style_Conditional HashTable * * @return PHPExcel_HashTable */ public function getStylesConditionalHashTable() { return $this->stylesConditionalHashTable; } /** * Get PHPExcel_Style_Fill HashTable * * @return PHPExcel_HashTable */ public function getFillHashTable() { return $this->fillHashTable; } /** * Get PHPExcel_Style_Font HashTable * * @return PHPExcel_HashTable */ public function getFontHashTable() { return $this->fontHashTable; } /** * Get PHPExcel_Style_Borders HashTable * * @return PHPExcel_HashTable */ public function getBordersHashTable() { return $this->bordersHashTable; } /** * Get PHPExcel_Style_NumberFormat HashTable * * @return PHPExcel_HashTable */ public function getNumFmtHashTable() { return $this->numFmtHashTable; } /** * Get PHPExcel_Worksheet_BaseDrawing HashTable * * @return PHPExcel_HashTable */ public function getDrawingHashTable() { return $this->drawingHashTable; } /** * Get Office2003 compatibility * * @return boolean */ public function getOffice2003Compatibility() { return $this->office2003compatibility; } /** * Set Office2003 compatibility * * @param boolean $pValue Office2003 compatibility? * @return PHPExcel_Writer_Excel2007 */ public function setOffice2003Compatibility($pValue = false) { $this->office2003compatibility = $pValue; return $this; } } PK!#OpenDocument/Mimetype.phpnu[getParentWriter()->getPHPExcel(); } $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8'); // Settings $objWriter->startElement('office:document-settings'); $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); $objWriter->writeAttribute('xmlns:config', 'urn:oasis:names:tc:opendocument:xmlns:config:1.0'); $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); $objWriter->writeAttribute('office:version', '1.2'); $objWriter->startElement('office:settings'); $objWriter->startElement('config:config-item-set'); $objWriter->writeAttribute('config:name', 'ooo:view-settings'); $objWriter->startElement('config:config-item-map-indexed'); $objWriter->writeAttribute('config:name', 'Views'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('config:config-item-set'); $objWriter->writeAttribute('config:name', 'ooo:configuration-settings'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); return $objWriter->getData(); } } PK!|F22OpenDocument/Content.phpnu[ */ class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart { const NUMBER_COLS_REPEATED_MAX = 1024; const NUMBER_ROWS_REPEATED_MAX = 1048576; /** * Write content.xml to XML format * * @param PHPExcel $pPHPExcel * @return string XML Output * @throws PHPExcel_Writer_Exception */ public function write(PHPExcel $pPHPExcel = null) { if (!$pPHPExcel) { $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */ } $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8'); // Content $objWriter->startElement('office:document-content'); $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'); $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'); $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'); $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'); $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0'); $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'); $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'); $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'); $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'); $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'); $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML'); $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'); $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'); $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer'); $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc'); $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events'); $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms'); $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema'); $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report'); $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2'); $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml'); $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table'); $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0'); $objWriter->writeAttribute('xmlns:formx', 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0'); $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/'); $objWriter->writeAttribute('office:version', '1.2'); $objWriter->writeElement('office:scripts'); $objWriter->writeElement('office:font-face-decls'); $objWriter->writeElement('office:automatic-styles'); $objWriter->startElement('office:body'); $objWriter->startElement('office:spreadsheet'); $objWriter->writeElement('table:calculation-settings'); $this->writeSheets($objWriter); $objWriter->writeElement('table:named-expressions'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); return $objWriter->getData(); } /** * Write sheets * * @param PHPExcel_Shared_XMLWriter $objWriter */ private function writeSheets(PHPExcel_Shared_XMLWriter $objWriter) { $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */ $sheet_count = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheet_count; $i++) { //$this->getWriterPart('Worksheet')->writeWorksheet()); $objWriter->startElement('table:table'); $objWriter->writeAttribute('table:name', $pPHPExcel->getSheet($i)->getTitle()); $objWriter->writeElement('office:forms'); $objWriter->startElement('table:table-column'); $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX); $objWriter->endElement(); $this->writeRows($objWriter, $pPHPExcel->getSheet($i)); $objWriter->endElement(); } } /** * Write rows of the specified sheet * * @param PHPExcel_Shared_XMLWriter $objWriter * @param PHPExcel_Worksheet $sheet */ private function writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet $sheet) { $number_rows_repeated = self::NUMBER_ROWS_REPEATED_MAX; $span_row = 0; $rows = $sheet->getRowIterator(); while ($rows->valid()) { $number_rows_repeated--; $row = $rows->current(); if ($row->getCellIterator()->valid()) { if ($span_row) { $objWriter->startElement('table:table-row'); if ($span_row > 1) { $objWriter->writeAttribute('table:number-rows-repeated', $span_row); } $objWriter->startElement('table:table-cell'); $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX); $objWriter->endElement(); $objWriter->endElement(); $span_row = 0; } $objWriter->startElement('table:table-row'); $this->writeCells($objWriter, $row); $objWriter->endElement(); } else { $span_row++; } $rows->next(); } } /** * Write cells of the specified row * * @param PHPExcel_Shared_XMLWriter $objWriter * @param PHPExcel_Worksheet_Row $row * @throws PHPExcel_Writer_Exception */ private function writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet_Row $row) { $number_cols_repeated = self::NUMBER_COLS_REPEATED_MAX; $prev_column = -1; $cells = $row->getCellIterator(); while ($cells->valid()) { $cell = $cells->current(); $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; $this->writeCellSpan($objWriter, $column, $prev_column); $objWriter->startElement('table:table-cell'); switch ($cell->getDataType()) { case PHPExcel_Cell_DataType::TYPE_BOOL: $objWriter->writeAttribute('office:value-type', 'boolean'); $objWriter->writeAttribute('office:value', $cell->getValue()); $objWriter->writeElement('text:p', $cell->getValue()); break; case PHPExcel_Cell_DataType::TYPE_ERROR: throw new PHPExcel_Writer_Exception('Writing of error not implemented yet.'); break; case PHPExcel_Cell_DataType::TYPE_FORMULA: try { $formula_value = $cell->getCalculatedValue(); } catch (Exception $e) { $formula_value = $cell->getValue(); } $objWriter->writeAttribute('table:formula', 'of:' . $cell->getValue()); if (is_numeric($formula_value)) { $objWriter->writeAttribute('office:value-type', 'float'); } else { $objWriter->writeAttribute('office:value-type', 'string'); } $objWriter->writeAttribute('office:value', $formula_value); $objWriter->writeElement('text:p', $formula_value); break; case PHPExcel_Cell_DataType::TYPE_INLINE: throw new PHPExcel_Writer_Exception('Writing of inline not implemented yet.'); break; case PHPExcel_Cell_DataType::TYPE_NUMERIC: $objWriter->writeAttribute('office:value-type', 'float'); $objWriter->writeAttribute('office:value', $cell->getValue()); $objWriter->writeElement('text:p', $cell->getValue()); break; case PHPExcel_Cell_DataType::TYPE_STRING: $objWriter->writeAttribute('office:value-type', 'string'); $objWriter->writeElement('text:p', $cell->getValue()); break; } PHPExcel_Writer_OpenDocument_Cell_Comment::write($objWriter, $cell); $objWriter->endElement(); $prev_column = $column; $cells->next(); } $number_cols_repeated = $number_cols_repeated - $prev_column - 1; if ($number_cols_repeated > 0) { if ($number_cols_repeated > 1) { $objWriter->startElement('table:table-cell'); $objWriter->writeAttribute('table:number-columns-repeated', $number_cols_repeated); $objWriter->endElement(); } else { $objWriter->writeElement('table:table-cell'); } } } /** * Write span * * @param PHPExcel_Shared_XMLWriter $objWriter * @param integer $curColumn * @param integer $prevColumn */ private function writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn, $prevColumn) { $diff = $curColumn - $prevColumn - 1; if (1 === $diff) { $objWriter->writeElement('table:table-cell'); } elseif ($diff > 1) { $objWriter->startElement('table:table-cell'); $objWriter->writeAttribute('table:number-columns-repeated', $diff); $objWriter->endElement(); } } } PK!XOpenDocument/MetaInf.phpnu[getParentWriter()->getPHPExcel(); } $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8'); // Manifest $objWriter->startElement('manifest:manifest'); $objWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'); $objWriter->writeAttribute('manifest:version', '1.2'); $objWriter->startElement('manifest:file-entry'); $objWriter->writeAttribute('manifest:full-path', '/'); $objWriter->writeAttribute('manifest:version', '1.2'); $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.spreadsheet'); $objWriter->endElement(); $objWriter->startElement('manifest:file-entry'); $objWriter->writeAttribute('manifest:full-path', 'meta.xml'); $objWriter->writeAttribute('manifest:media-type', 'text/xml'); $objWriter->endElement(); $objWriter->startElement('manifest:file-entry'); $objWriter->writeAttribute('manifest:full-path', 'settings.xml'); $objWriter->writeAttribute('manifest:media-type', 'text/xml'); $objWriter->endElement(); $objWriter->startElement('manifest:file-entry'); $objWriter->writeAttribute('manifest:full-path', 'content.xml'); $objWriter->writeAttribute('manifest:media-type', 'text/xml'); $objWriter->endElement(); $objWriter->startElement('manifest:file-entry'); $objWriter->writeAttribute('manifest:full-path', 'Thumbnails/thumbnail.png'); $objWriter->writeAttribute('manifest:media-type', 'image/png'); $objWriter->endElement(); $objWriter->startElement('manifest:file-entry'); $objWriter->writeAttribute('manifest:full-path', 'styles.xml'); $objWriter->writeAttribute('manifest:media-type', 'text/xml'); $objWriter->endElement(); $objWriter->endElement(); return $objWriter->getData(); } } PK!F?TOpenDocument/Thumbnails.phpnu[getParentWriter()->getPHPExcel(); } $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8'); // Meta $objWriter->startElement('office:document-meta'); $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); $objWriter->writeAttribute('office:version', '1.2'); $objWriter->startElement('office:meta'); $objWriter->writeElement('meta:initial-creator', $pPHPExcel->getProperties()->getCreator()); $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); $objWriter->writeElement('dc:date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); $keywords = explode(' ', $pPHPExcel->getProperties()->getKeywords()); foreach ($keywords as $keyword) { $objWriter->writeElement('meta:keyword', $keyword); } // $objWriter->startElement('meta:user-defined'); $objWriter->writeAttribute('meta:name', 'Company'); $objWriter->writeRaw($pPHPExcel->getProperties()->getCompany()); $objWriter->endElement(); $objWriter->startElement('meta:user-defined'); $objWriter->writeAttribute('meta:name', 'category'); $objWriter->writeRaw($pPHPExcel->getProperties()->getCategory()); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); return $objWriter->getData(); } } PK!.m= OpenDocument/Cell/Comment.phpnu[ */ class PHPExcel_Writer_OpenDocument_Cell_Comment { public static function write(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Cell $cell) { $comments = $cell->getWorksheet()->getComments(); if (!isset($comments[$cell->getCoordinate()])) { return; } $comment = $comments[$cell->getCoordinate()]; $objWriter->startElement('office:annotation'); //$objWriter->writeAttribute('draw:style-name', 'gr1'); //$objWriter->writeAttribute('draw:text-style-name', 'P1'); $objWriter->writeAttribute('svg:width', $comment->getWidth()); $objWriter->writeAttribute('svg:height', $comment->getHeight()); $objWriter->writeAttribute('svg:x', $comment->getMarginLeft()); $objWriter->writeAttribute('svg:y', $comment->getMarginTop()); //$objWriter->writeAttribute('draw:caption-point-x', $comment->getMarginLeft()); //$objWriter->writeAttribute('draw:caption-point-y', $comment->getMarginTop()); $objWriter->writeElement('dc:creator', $comment->getAuthor()); // TODO: Not realized in PHPExcel_Comment yet. //$objWriter->writeElement('dc:date', $comment->getDate()); $objWriter->writeElement('text:p', $comment->getText()->getPlainText()); //$objWriter->writeAttribute('draw:text-style-name', 'P1'); $objWriter->endElement(); } } PK!ʕ OpenDocument/WriterPart.phpnu[getParentWriter()->getPHPExcel(); } $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // XML header $objWriter->startDocument('1.0', 'UTF-8'); // Content $objWriter->startElement('office:document-styles'); $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'); $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'); $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'); $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'); $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0'); $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'); $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'); $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'); $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'); $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'); $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML'); $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'); $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'); $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer'); $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc'); $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events'); $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report'); $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2'); $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml'); $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table'); $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/'); $objWriter->writeAttribute('office:version', '1.2'); $objWriter->writeElement('office:font-face-decls'); $objWriter->writeElement('office:styles'); $objWriter->writeElement('office:automatic-styles'); $objWriter->writeElement('office:master-styles'); $objWriter->endElement(); return $objWriter->getData(); } } PK!؃cIIExcel5/Escher.phpnu[object = $object; } /** * Process the object to be written */ public function close() { // initialize $this->data = ''; switch (get_class($this->object)) { case 'PHPExcel_Shared_Escher': if ($dggContainer = $this->object->getDggContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); $this->data = $writer->close(); } elseif ($dgContainer = $this->object->getDgContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); $this->data = $writer->close(); $this->spOffsets = $writer->getSpOffsets(); $this->spTypes = $writer->getSpTypes(); } break; case 'PHPExcel_Shared_Escher_DggContainer': // this is a container record // initialize $innerData = ''; // write the dgg $recVer = 0x0; $recInstance = 0x0000; $recType = 0xF006; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; // dgg data $dggData = pack( 'VVVV', $this->object->getSpIdMax(), // maximum shape identifier increased by one $this->object->getCDgSaved() + 1, // number of file identifier clusters increased by one $this->object->getCSpSaved(), $this->object->getCDgSaved() // count total number of drawings saved ); // add file identifier clusters (one per drawing) $IDCLs = $this->object->getIDCLs(); foreach ($IDCLs as $dgId => $maxReducedSpId) { $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); } $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); $innerData .= $header . $dggData; // write the bstoreContainer if ($bstoreContainer = $this->object->getBstoreContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); $innerData .= $writer->close(); } // write the record $recVer = 0xF; $recInstance = 0x0000; $recType = 0xF000; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': // this is a container record // initialize $innerData = ''; // treat the inner data if ($BSECollection = $this->object->getBSECollection()) { foreach ($BSECollection as $BSE) { $writer = new PHPExcel_Writer_Excel5_Escher($BSE); $innerData .= $writer->close(); } } // write the record $recVer = 0xF; $recInstance = count($this->object->getBSECollection()); $recType = 0xF001; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': // this is a semi-container record // initialize $innerData = ''; // here we treat the inner data if ($blip = $this->object->getBlip()) { $writer = new PHPExcel_Writer_Excel5_Escher($blip); $innerData .= $writer->close(); } // initialize $data = ''; $btWin32 = $this->object->getBlipType(); $btMacOS = $this->object->getBlipType(); $data .= pack('CC', $btWin32, $btMacOS); $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo $data .= $rgbUid; $tag = 0; $size = strlen($innerData); $cRef = 1; $foDelay = 0; //todo $unused1 = 0x0; $cbName = 0x0; $unused2 = 0x0; $unused3 = 0x0; $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); $data .= $innerData; // write the record $recVer = 0x2; $recInstance = $this->object->getBlipType(); $recType = 0xF007; $length = strlen($data); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header; $this->data .= $data; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': // this is an atom record // write the record switch ($this->object->getParent()->getBlipType()) { case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: // initialize $innerData = ''; $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo $innerData .= $rgbUid1; $tag = 0xFF; // todo $innerData .= pack('C', $tag); $innerData .= $this->object->getData(); $recVer = 0x0; $recInstance = 0x46A; $recType = 0xF01D; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header; $this->data .= $innerData; break; case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: // initialize $innerData = ''; $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo $innerData .= $rgbUid1; $tag = 0xFF; // todo $innerData .= pack('C', $tag); $innerData .= $this->object->getData(); $recVer = 0x0; $recInstance = 0x6E0; $recType = 0xF01E; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header; $this->data .= $innerData; break; } break; case 'PHPExcel_Shared_Escher_DgContainer': // this is a container record // initialize $innerData = ''; // write the dg $recVer = 0x0; $recInstance = $this->object->getDgId(); $recType = 0xF008; $length = 8; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); // number of shapes in this drawing (including group shape) $countShapes = count($this->object->getSpgrContainer()->getChildren()); $innerData .= $header . pack('VV', $countShapes, $this->object->getLastSpId()); //$innerData .= $header . pack('VV', 0, 0); // write the spgrContainer if ($spgrContainer = $this->object->getSpgrContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); $innerData .= $writer->close(); // get the shape offsets relative to the spgrContainer record $spOffsets = $writer->getSpOffsets(); $spTypes = $writer->getSpTypes(); // save the shape offsets relative to dgContainer foreach ($spOffsets as & $spOffset) { $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) } $this->spOffsets = $spOffsets; $this->spTypes = $spTypes; } // write the record $recVer = 0xF; $recInstance = 0x0000; $recType = 0xF002; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': // this is a container record // initialize $innerData = ''; // initialize spape offsets $totalSize = 8; $spOffsets = array(); $spTypes = array(); // treat the inner data foreach ($this->object->getChildren() as $spContainer) { $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); $spData = $writer->close(); $innerData .= $spData; // save the shape offsets (where new shape records begin) $totalSize += strlen($spData); $spOffsets[] = $totalSize; $spTypes = array_merge($spTypes, $writer->getSpTypes()); } // write the record $recVer = 0xF; $recInstance = 0x0000; $recType = 0xF003; $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header . $innerData; $this->spOffsets = $spOffsets; $this->spTypes = $spTypes; break; case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': // initialize $data = ''; // build the data // write group shape record, if necessary? if ($this->object->getSpgr()) { $recVer = 0x1; $recInstance = 0x0000; $recType = 0xF009; $length = 0x00000010; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . pack('VVVV', 0, 0, 0, 0); } $this->spTypes[] = ($this->object->getSpType()); // write the shape record $recVer = 0x2; $recInstance = $this->object->getSpType(); // shape type $recType = 0xF00A; $length = 0x00000008; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . pack('VV', $this->object->getSpId(), $this->object->getSpgr() ? 0x0005 : 0x0A00); // the options if ($this->object->getOPTCollection()) { $optData = ''; $recVer = 0x3; $recInstance = count($this->object->getOPTCollection()); $recType = 0xF00B; foreach ($this->object->getOPTCollection() as $property => $value) { $optData .= pack('vV', $property, $value); } $length = strlen($optData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . $optData; } // the client anchor if ($this->object->getStartCoordinates()) { $clientAnchorData = ''; $recVer = 0x0; $recInstance = 0x0; $recType = 0xF010; // start coordinates list($column, $row) = PHPExcel_Cell::coordinateFromString($this->object->getStartCoordinates()); $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; $r1 = $row - 1; // start offsetX $startOffsetX = $this->object->getStartOffsetX(); // start offsetY $startOffsetY = $this->object->getStartOffsetY(); // end coordinates list($column, $row) = PHPExcel_Cell::coordinateFromString($this->object->getEndCoordinates()); $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; $r2 = $row - 1; // end offsetX $endOffsetX = $this->object->getEndOffsetX(); // end offsetY $endOffsetY = $this->object->getEndOffsetY(); $clientAnchorData = pack('vvvvvvvvv', $this->object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY); $length = strlen($clientAnchorData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . $clientAnchorData; } // the client data, just empty for now if (!$this->object->getSpgr()) { $clientDataData = ''; $recVer = 0x0; $recInstance = 0x0; $recType = 0xF011; $length = strlen($clientDataData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $data .= $header . $clientDataData; } // write the record $recVer = 0xF; $recInstance = 0x0000; $recType = 0xF004; $length = strlen($data); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); $this->data = $header . $data; break; } return $this->data; } /** * Gets the shape offsets * * @return array */ public function getSpOffsets() { return $this->spOffsets; } /** * Gets the shape types * * @return array */ public function getSpTypes() { return $this->spTypes; } } PK!31c Excel5/BIFFwriter.phpnu[ // * // * The majority of this is _NOT_ my code. I simply ported it from the // * PERL Spreadsheet::WriteExcel module. // * // * The author of the Spreadsheet::WriteExcel module is John McNamara // * // * // * I _DO_ maintain this code, and John McNamara has nothing to do with the // * porting of this code to PHP. Any questions directly related to this // * class library should be directed to me. // * // * License Information: // * // * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets // * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com // * // * This library is free software; you can redistribute it and/or // * modify it under the terms of the GNU Lesser General Public // * License as published by the Free Software Foundation; either // * version 2.1 of the License, or (at your option) any later version. // * // * This library is distributed in the hope that it will be useful, // * but WITHOUT ANY WARRANTY; without even the implied warranty of // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // * Lesser General Public License for more details. // * // * You should have received a copy of the GNU Lesser General Public // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ class PHPExcel_Writer_Excel5_BIFFwriter { /** * The byte order of this architecture. 0 => little endian, 1 => big endian * @var integer */ private static $byteOrder; /** * The string containing the data of the BIFF stream * @var string */ public $_data; /** * The size of the data in bytes. Should be the same as strlen($this->_data) * @var integer */ public $_datasize; /** * The maximum length for a BIFF record (excluding record header and length field). See addContinue() * @var integer * @see addContinue() */ private $limit = 8224; /** * Constructor */ public function __construct() { $this->_data = ''; $this->_datasize = 0; // $this->limit = 8224; } /** * Determine the byte order and store it as class data to avoid * recalculating it for each call to new(). * * @return int */ public static function getByteOrder() { if (!isset(self::$byteOrder)) { // Check if "pack" gives the required IEEE 64bit float $teststr = pack("d", 1.2345); $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); if ($number == $teststr) { $byte_order = 0; // Little Endian } elseif ($number == strrev($teststr)) { $byte_order = 1; // Big Endian } else { // Give up. I'll fix this in a later version. throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); } self::$byteOrder = $byte_order; } return self::$byteOrder; } /** * General storage function * * @param string $data binary data to append * @access private */ protected function append($data) { if (strlen($data) - 4 > $this->limit) { $data = $this->addContinue($data); } $this->_data .= $data; $this->_datasize += strlen($data); } /** * General storage function like append, but returns string instead of modifying $this->_data * * @param string $data binary data to write * @return string */ public function writeData($data) { if (strlen($data) - 4 > $this->limit) { $data = $this->addContinue($data); } $this->_datasize += strlen($data); return $data; } /** * Writes Excel BOF record to indicate the beginning of a stream or * sub-stream in the BIFF file. * * @param integer $type Type of BIFF file to write: 0x0005 Workbook, * 0x0010 Worksheet. * @access private */ protected function storeBof($type) { $record = 0x0809; // Record identifier (BIFF5-BIFF8) $length = 0x0010; // by inspection of real files, MS Office Excel 2007 writes the following $unknown = pack("VV", 0x000100D1, 0x00000406); $build = 0x0DBB; // Excel 97 $year = 0x07CC; // Excel 97 $version = 0x0600; // BIFF8 $header = pack("vv", $record, $length); $data = pack("vvvv", $version, $type, $build, $year); $this->append($header . $data . $unknown); } /** * Writes Excel EOF record to indicate the end of a BIFF stream. * * @access private */ protected function storeEof() { $record = 0x000A; // Record identifier $length = 0x0000; // Number of bytes to follow $header = pack("vv", $record, $length); $this->append($header); } /** * Writes Excel EOF record to indicate the end of a BIFF stream. * * @access private */ public function writeEof() { $record = 0x000A; // Record identifier $length = 0x0000; // Number of bytes to follow $header = pack("vv", $record, $length); return $this->writeData($header); } /** * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In * Excel 97 the limit is 8228 bytes. Records that are longer than these limits * must be split up into CONTINUE blocks. * * This function takes a long BIFF record and inserts CONTINUE records as * necessary. * * @param string $data The original binary data to be written * @return string A very convenient string of continue blocks * @access private */ private function addContinue($data) { $limit = $this->limit; $record = 0x003C; // Record identifier // The first 2080/8224 bytes remain intact. However, we have to change // the length field of the record. $tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit); $header = pack("vv", $record, $limit); // Headers for continue records // Retrieve chunks of 2080/8224 bytes +4 for the header. $data_length = strlen($data); for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) { $tmp .= $header; $tmp .= substr($data, $i, $limit); } // Retrieve the last chunk of data $header = pack("vv", $record, strlen($data) - $i); $tmp .= $header; $tmp .= substr($data, $i, strlen($data) - $i); return $tmp; } } PK!w:rrExcel5/Worksheet.phpnu[ // * // * The majority of this is _NOT_ my code. I simply ported it from the // * PERL Spreadsheet::WriteExcel module. // * // * The author of the Spreadsheet::WriteExcel module is John McNamara // * // * // * I _DO_ maintain this code, and John McNamara has nothing to do with the // * porting of this code to PHP. Any questions directly related to this // * class library should be directed to me. // * // * License Information: // * // * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets // * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com // * // * This library is free software; you can redistribute it and/or // * modify it under the terms of the GNU Lesser General Public // * License as published by the Free Software Foundation; either // * version 2.1 of the License, or (at your option) any later version. // * // * This library is distributed in the hope that it will be useful, // * but WITHOUT ANY WARRANTY; without even the implied warranty of // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // * Lesser General Public License for more details. // * // * You should have received a copy of the GNU Lesser General Public // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter { /** * Formula parser * * @var PHPExcel_Writer_Excel5_Parser */ private $parser; /** * Maximum number of characters for a string (LABEL record in BIFF5) * @var integer */ private $xlsStringMaxLength; /** * Array containing format information for columns * @var array */ private $columnInfo; /** * Array containing the selected area for the worksheet * @var array */ private $selection; /** * The active pane for the worksheet * @var integer */ private $activePane; /** * Whether to use outline. * @var integer */ private $outlineOn; /** * Auto outline styles. * @var bool */ private $outlineStyle; /** * Whether to have outline summary below. * @var bool */ private $outlineBelow; /** * Whether to have outline summary at the right. * @var bool */ private $outlineRight; /** * Reference to the total number of strings in the workbook * @var integer */ private $stringTotal; /** * Reference to the number of unique strings in the workbook * @var integer */ private $stringUnique; /** * Reference to the array containing all the unique strings in the workbook * @var array */ private $stringTable; /** * Color cache */ private $colors; /** * Index of first used row (at least 0) * @var int */ private $firstRowIndex; /** * Index of last used row. (no used rows means -1) * @var int */ private $lastRowIndex; /** * Index of first used column (at least 0) * @var int */ private $firstColumnIndex; /** * Index of last used column (no used columns means -1) * @var int */ private $lastColumnIndex; /** * Sheet object * @var PHPExcel_Worksheet */ public $phpSheet; /** * Count cell style Xfs * * @var int */ private $countCellStyleXfs; /** * Escher object corresponding to MSODRAWING * * @var PHPExcel_Shared_Escher */ private $escher; /** * Array of font hashes associated to FONT records index * * @var array */ public $fontHashIndex; /** * Constructor * * @param int &$str_total Total number of strings * @param int &$str_unique Total number of unique strings * @param array &$str_table String Table * @param array &$colors Colour Table * @param mixed $parser The formula parser created for the Workbook * @param boolean $preCalculateFormulas Flag indicating whether formulas should be calculated or just written * @param string $phpSheet The worksheet to write * @param PHPExcel_Worksheet $phpSheet */ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $parser, $preCalculateFormulas, $phpSheet) { // It needs to call its parent's constructor explicitly parent::__construct(); // change BIFFwriter limit for CONTINUE records // $this->_limit = 8224; $this->_preCalculateFormulas = $preCalculateFormulas; $this->stringTotal = &$str_total; $this->stringUnique = &$str_unique; $this->stringTable = &$str_table; $this->colors = &$colors; $this->parser = $parser; $this->phpSheet = $phpSheet; //$this->ext_sheets = array(); //$this->offset = 0; $this->xlsStringMaxLength = 255; $this->columnInfo = array(); $this->selection = array(0,0,0,0); $this->activePane = 3; $this->_print_headers = 0; $this->outlineStyle = 0; $this->outlineBelow = 1; $this->outlineRight = 1; $this->outlineOn = 1; $this->fontHashIndex = array(); // calculate values for DIMENSIONS record $minR = 1; $minC = 'A'; $maxR = $this->phpSheet->getHighestRow(); $maxC = $this->phpSheet->getHighestColumn(); // Determine lowest and highest column and row // $this->firstRowIndex = ($minR > 65535) ? 65535 : $minR; $this->lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; $this->firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); $this->lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); // if ($this->firstColumnIndex > 255) $this->firstColumnIndex = 255; if ($this->lastColumnIndex > 255) { $this->lastColumnIndex = 255; } $this->countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); } /** * Add data to the beginning of the workbook (note the reverse order) * and to the end of the workbook. * * @access public * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook() */ public function close() { $phpSheet = $this->phpSheet; $num_sheets = $phpSheet->getParent()->getSheetCount(); // Write BOF record $this->storeBof(0x0010); // Write PRINTHEADERS $this->writePrintHeaders(); // Write PRINTGRIDLINES $this->writePrintGridlines(); // Write GRIDSET $this->writeGridset(); // Calculate column widths $phpSheet->calculateColumnWidths(); // Column dimensions if (($defaultWidth = $phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($phpSheet->getParent()->getDefaultStyle()->getFont()); } $columnDimensions = $phpSheet->getColumnDimensions(); $maxCol = $this->lastColumnIndex -1; for ($i = 0; $i <= $maxCol; ++$i) { $hidden = 0; $level = 0; $xfIndex = 15; // there are 15 cell style Xfs $width = $defaultWidth; $columnLetter = PHPExcel_Cell::stringFromColumnIndex($i); if (isset($columnDimensions[$columnLetter])) { $columnDimension = $columnDimensions[$columnLetter]; if ($columnDimension->getWidth() >= 0) { $width = $columnDimension->getWidth(); } $hidden = $columnDimension->getVisible() ? 0 : 1; $level = $columnDimension->getOutlineLevel(); $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs } // Components of columnInfo: // $firstcol first column on the range // $lastcol last column on the range // $width width to set // $xfIndex The optional cell style Xf index to apply to the columns // $hidden The optional hidden atribute // $level The optional outline level $this->columnInfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); } // Write GUTS $this->writeGuts(); // Write DEFAULTROWHEIGHT $this->writeDefaultRowHeight(); // Write WSBOOL $this->writeWsbool(); // Write horizontal and vertical page breaks $this->writeBreaks(); // Write page header $this->writeHeader(); // Write page footer $this->writeFooter(); // Write page horizontal centering $this->writeHcenter(); // Write page vertical centering $this->writeVcenter(); // Write left margin $this->writeMarginLeft(); // Write right margin $this->writeMarginRight(); // Write top margin $this->writeMarginTop(); // Write bottom margin $this->writeMarginBottom(); // Write page setup $this->writeSetup(); // Write sheet protection $this->writeProtect(); // Write SCENPROTECT $this->writeScenProtect(); // Write OBJECTPROTECT $this->writeObjectProtect(); // Write sheet password $this->writePassword(); // Write DEFCOLWIDTH record $this->writeDefcol(); // Write the COLINFO records if they exist if (!empty($this->columnInfo)) { $colcount = count($this->columnInfo); for ($i = 0; $i < $colcount; ++$i) { $this->writeColinfo($this->columnInfo[$i]); } } $autoFilterRange = $phpSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { // Write AUTOFILTERINFO $this->writeAutoFilterInfo(); } // Write sheet dimensions $this->writeDimensions(); // Row dimensions foreach ($phpSheet->getRowDimensions() as $rowDimension) { $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs $this->writeRow($rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel()); } // Write Cells foreach ($phpSheet->getCellCollection() as $cellID) { $cell = $phpSheet->getCell($cellID); $row = $cell->getRow() - 1; $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; // Don't break Excel! // if ($row + 1 > 65536 or $column + 1 > 256) { if ($row > 65535 || $column > 255) { break; } // Write cell value $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs $cVal = $cell->getValue(); if ($cVal instanceof PHPExcel_RichText) { // $this->writeString($row, $column, $cVal->getPlainText(), $xfIndex); $arrcRun = array(); $str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8'); $str_pos = 0; $elements = $cVal->getRichTextElements(); foreach ($elements as $element) { // FONT Index if ($element instanceof PHPExcel_RichText_Run) { $str_fontidx = $this->fontHashIndex[$element->getFont()->getHashCode()]; } else { $str_fontidx = 0; } $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); // Position FROM $str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8'); } $this->writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); } else { switch ($cell->getDatatype()) { case PHPExcel_Cell_DataType::TYPE_STRING: case PHPExcel_Cell_DataType::TYPE_NULL: if ($cVal === '' || $cVal === null) { $this->writeBlank($row, $column, $xfIndex); } else { $this->writeString($row, $column, $cVal, $xfIndex); } break; case PHPExcel_Cell_DataType::TYPE_NUMERIC: $this->writeNumber($row, $column, $cVal, $xfIndex); break; case PHPExcel_Cell_DataType::TYPE_FORMULA: $calculatedValue = $this->_preCalculateFormulas ? $cell->getCalculatedValue() : null; $this->writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); break; case PHPExcel_Cell_DataType::TYPE_BOOL: $this->writeBoolErr($row, $column, $cVal, 0, $xfIndex); break; case PHPExcel_Cell_DataType::TYPE_ERROR: $this->writeBoolErr($row, $column, self::mapErrorCode($cVal), 1, $xfIndex); break; } } } // Append $this->writeMsoDrawing(); // Write WINDOW2 record $this->writeWindow2(); // Write PLV record $this->writePageLayoutView(); // Write ZOOM record $this->writeZoom(); if ($phpSheet->getFreezePane()) { $this->writePanes(); } // Write SELECTION record $this->writeSelection(); // Write MergedCellsTable Record $this->writeMergedCells(); // Hyperlinks foreach ($phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate); $url = $hyperlink->getUrl(); if (strpos($url, 'sheet://') !== false) { // internal to current workbook $url = str_replace('sheet://', 'internal:', $url); } elseif (preg_match('/^(http:|https:|ftp:|mailto:)/', $url)) { // URL // $url = $url; } else { // external (local file) $url = 'external:' . $url; } $this->writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); } $this->writeDataValidity(); $this->writeSheetLayout(); // Write SHEETPROTECTION record $this->writeSheetProtection(); $this->writeRangeProtection(); $arrConditionalStyles = $phpSheet->getConditionalStylesCollection(); if (!empty($arrConditionalStyles)) { $arrConditional = array(); // @todo CFRule & CFHeader // Write CFHEADER record $this->writeCFHeader(); // Write ConditionalFormattingTable records foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { if (!in_array($conditional->getHashCode(), $arrConditional)) { $arrConditional[] = $conditional->getHashCode(); // Write CFRULE record $this->writeCFRule($conditional); } } } } } $this->storeEof(); } /** * Write a cell range address in BIFF8 * always fixed range * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format * * @param string $range E.g. 'A1' or 'A1:B6' * @return string Binary data */ private function writeBIFF8CellRangeAddressFixed($range = 'A1') { $explodes = explode(':', $range); // extract first cell, e.g. 'A1' $firstCell = $explodes[0]; // extract last cell, e.g. 'B6' if (count($explodes) == 1) { $lastCell = $firstCell; } else { $lastCell = $explodes[1]; } $firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1) $lastCellCoordinates = PHPExcel_Cell::coordinateFromString($lastCell); // e.g. array(1, 6) return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1); } /** * Retrieves data from memory in one chunk, or from disk in $buffer * sized chunks. * * @return string The data */ public function getData() { $buffer = 4096; // Return data stored in memory if (isset($this->_data)) { $tmp = $this->_data; unset($this->_data); return $tmp; } // No data to return return false; } /** * Set the option to print the row and column headers on the printed page. * * @access public * @param integer $print Whether to print the headers or not. Defaults to 1 (print). */ public function printRowColHeaders($print = 1) { $this->_print_headers = $print; } /** * This method sets the properties for outlining and grouping. The defaults * correspond to Excel's defaults. * * @param bool $visible * @param bool $symbols_below * @param bool $symbols_right * @param bool $auto_style */ public function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) { $this->outlineOn = $visible; $this->outlineBelow = $symbols_below; $this->outlineRight = $symbols_right; $this->outlineStyle = $auto_style; // Ensure this is a boolean vale for Window2 if ($this->outlineOn) { $this->outlineOn = 1; } } /** * Write a double to the specified row and column (zero indexed). * An integer can be written as a double. Excel will display an * integer. $format is optional. * * Returns 0 : normal termination * -2 : row or column out of range * * @param integer $row Zero indexed row * @param integer $col Zero indexed column * @param float $num The number to write * @param mixed $xfIndex The optional XF format * @return integer */ private function writeNumber($row, $col, $num, $xfIndex) { $record = 0x0203; // Record identifier $length = 0x000E; // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex); $xl_double = pack("d", $num); if (self::getByteOrder()) { // if it's Big Endian $xl_double = strrev($xl_double); } $this->append($header.$data.$xl_double); return(0); } /** * Write a LABELSST record or a LABEL record. Which one depends on BIFF version * * @param int $row Row index (0-based) * @param int $col Column index (0-based) * @param string $str The string * @param int $xfIndex Index to XF record */ private function writeString($row, $col, $str, $xfIndex) { $this->writeLabelSst($row, $col, $str, $xfIndex); } /** * Write a LABELSST record or a LABEL record. Which one depends on BIFF version * It differs from writeString by the writing of rich text strings. * @param int $row Row index (0-based) * @param int $col Column index (0-based) * @param string $str The string * @param mixed $xfIndex The XF format index for the cell * @param array $arrcRun Index to Font record and characters beginning */ private function writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) { $record = 0x00FD; // Record identifier $length = 0x000A; // Bytes to follow $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); /* check if string is already present */ if (!isset($this->stringTable[$str])) { $this->stringTable[$str] = $this->stringUnique++; } $this->stringTotal++; $header = pack('vv', $record, $length); $data = pack('vvvV', $row, $col, $xfIndex, $this->stringTable[$str]); $this->append($header.$data); } /** * Write a string to the specified row and column (zero indexed). * NOTE: there is an Excel 5 defined limit of 255 characters. * $format is optional. * Returns 0 : normal termination * -2 : row or column out of range * -3 : long string truncated to 255 chars * * @access public * @param integer $row Zero indexed row * @param integer $col Zero indexed column * @param string $str The string to write * @param mixed $xfIndex The XF format index for the cell * @return integer */ private function writeLabel($row, $col, $str, $xfIndex) { $strlen = strlen($str); $record = 0x0204; // Record identifier $length = 0x0008 + $strlen; // Bytes to follow $str_error = 0; if ($strlen > $this->xlsStringMaxLength) { // LABEL must be < 255 chars $str = substr($str, 0, $this->xlsStringMaxLength); $length = 0x0008 + $this->xlsStringMaxLength; $strlen = $this->xlsStringMaxLength; $str_error = -3; } $header = pack("vv", $record, $length); $data = pack("vvvv", $row, $col, $xfIndex, $strlen); $this->append($header . $data . $str); return($str_error); } /** * Write a string to the specified row and column (zero indexed). * This is the BIFF8 version (no 255 chars limit). * $format is optional. * Returns 0 : normal termination * -2 : row or column out of range * -3 : long string truncated to 255 chars * * @access public * @param integer $row Zero indexed row * @param integer $col Zero indexed column * @param string $str The string to write * @param mixed $xfIndex The XF format index for the cell * @return integer */ private function writeLabelSst($row, $col, $str, $xfIndex) { $record = 0x00FD; // Record identifier $length = 0x000A; // Bytes to follow $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str); /* check if string is already present */ if (!isset($this->stringTable[$str])) { $this->stringTable[$str] = $this->stringUnique++; } $this->stringTotal++; $header = pack('vv', $record, $length); $data = pack('vvvV', $row, $col, $xfIndex, $this->stringTable[$str]); $this->append($header.$data); } /** * Writes a note associated with the cell given by the row and column. * NOTE records don't have a length limit. * * @param integer $row Zero indexed row * @param integer $col Zero indexed column * @param string $note The note to write */ private function writeNote($row, $col, $note) { $note_length = strlen($note); $record = 0x001C; // Record identifier $max_length = 2048; // Maximun length for a NOTE record // Length for this record is no more than 2048 + 6 $length = 0x0006 + min($note_length, 2048); $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $note_length); $this->append($header . $data . substr($note, 0, 2048)); for ($i = $max_length; $i < $note_length; $i += $max_length) { $chunk = substr($note, $i, $max_length); $length = 0x0006 + strlen($chunk); $header = pack("vv", $record, $length); $data = pack("vvv", -1, 0, strlen($chunk)); $this->append($header.$data.$chunk); } return(0); } /** * Write a blank cell to the specified row and column (zero indexed). * A blank cell is used to specify formatting without adding a string * or a number. * * A blank cell without a format serves no purpose. Therefore, we don't write * a BLANK record unless a format is specified. * * Returns 0 : normal termination (including no format) * -1 : insufficient number of arguments * -2 : row or column out of range * * @param integer $row Zero indexed row * @param integer $col Zero indexed column * @param mixed $xfIndex The XF format index */ public function writeBlank($row, $col, $xfIndex) { $record = 0x0201; // Record identifier $length = 0x0006; // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex); $this->append($header . $data); return 0; } /** * Write a boolean or an error type to the specified row and column (zero indexed) * * @param int $row Row index (0-based) * @param int $col Column index (0-based) * @param int $value * @param boolean $isError Error or Boolean? * @param int $xfIndex */ private function writeBoolErr($row, $col, $value, $isError, $xfIndex) { $record = 0x0205; $length = 8; $header = pack("vv", $record, $length); $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); $this->append($header . $data); return 0; } /** * Write a formula to the specified row and column (zero indexed). * The textual representation of the formula is passed to the parser in * Parser.php which returns a packed binary string. * * Returns 0 : normal termination * -1 : formula errors (bad formula) * -2 : row or column out of range * * @param integer $row Zero indexed row * @param integer $col Zero indexed column * @param string $formula The formula text string * @param mixed $xfIndex The XF format index * @param mixed $calculatedValue Calculated value * @return integer */ private function writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) { $record = 0x0006; // Record identifier // Initialize possible additional value for STRING record that should be written after the FORMULA record? $stringValue = null; // calculated value if (isset($calculatedValue)) { // Since we can't yet get the data type of the calculated value, // we use best effort to determine data type if (is_bool($calculatedValue)) { // Boolean value $num = pack('CCCvCv', 0x01, 0x00, (int)$calculatedValue, 0x00, 0x00, 0xFFFF); } elseif (is_int($calculatedValue) || is_float($calculatedValue)) { // Numeric value $num = pack('d', $calculatedValue); } elseif (is_string($calculatedValue)) { if (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) { // Error value $num = pack('CCCvCv', 0x02, 0x00, self::mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); } elseif ($calculatedValue === '') { // Empty string (and BIFF8) $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF); } else { // Non-empty string value (or empty string BIFF5) $stringValue = $calculatedValue; $num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF); } } else { // We are really not supposed to reach here $num = pack('d', 0x00); } } else { $num = pack('d', 0x00); } $grbit = 0x03; // Option flags $unknown = 0x0000; // Must be zero // Strip the '=' or '@' sign at the beginning of the formula string if ($formula{0} == '=') { $formula = substr($formula, 1); } else { // Error handling $this->writeString($row, $col, 'Unrecognised character for formula'); return -1; } // Parse the formula using the parser in Parser.php try { $error = $this->parser->parse($formula); $formula = $this->parser->toReversePolish(); $formlen = strlen($formula); // Length of the binary string $length = 0x16 + $formlen; // Length of the record data $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex) . $num . pack("vVv", $grbit, $unknown, $formlen); $this->append($header . $data . $formula); // Append also a STRING record if necessary if ($stringValue !== null) { $this->writeStringRecord($stringValue); } return 0; } catch (PHPExcel_Exception $e) { // do nothing } } /** * Write a STRING record. This * * @param string $stringValue */ private function writeStringRecord($stringValue) { $record = 0x0207; // Record identifier $data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue); $length = strlen($data); $header = pack('vv', $record, $length); $this->append($header . $data); } /** * Write a hyperlink. * This is comprised of two elements: the visible label and * the invisible link. The visible label is the same as the link unless an * alternative string is specified. The label is written using the * writeString() method. Therefore the 255 characters string limit applies. * $string and $format are optional. * * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external * directory url. * * Returns 0 : normal termination * -2 : row or column out of range * -3 : long string truncated to 255 chars * * @param integer $row Row * @param integer $col Column * @param string $url URL string * @return integer */ private function writeUrl($row, $col, $url) { // Add start row and col to arg list return($this->writeUrlRange($row, $col, $row, $col, $url)); } /** * This is the more general form of writeUrl(). It allows a hyperlink to be * written to a range of cells. This function also decides the type of hyperlink * to be written. These are either, Web (http, ftp, mailto), Internal * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). * * @access private * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row * @param integer $col2 End column * @param string $url URL string * @return integer */ public function writeUrlRange($row1, $col1, $row2, $col2, $url) { // Check for internal/external sheet links or default to web link if (preg_match('[^internal:]', $url)) { return($this->writeUrlInternal($row1, $col1, $row2, $col2, $url)); } if (preg_match('[^external:]', $url)) { return($this->writeUrlExternal($row1, $col1, $row2, $col2, $url)); } return($this->writeUrlWeb($row1, $col1, $row2, $col2, $url)); } /** * Used to write http, ftp and mailto hyperlinks. * The link type ($options) is 0x03 is the same as absolute dir ref without * sheet. However it is differentiated by the $unknown2 data stream. * * @access private * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row * @param integer $col2 End column * @param string $url URL string * @return integer */ public function writeUrlWeb($row1, $col1, $row2, $col2, $url) { $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow // Pack the undocumented parts of the hyperlink stream $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); // Pack the option flags $options = pack("V", 0x03); // Convert URL to a null terminated wchar string $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); $url = $url . "\0\0\0"; // Pack the length of the URL $url_len = pack("V", strlen($url)); // Calculate the data length $length = 0x34 + strlen($url); // Pack the header data $header = pack("vv", $record, $length); $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data $this->append($header . $data . $unknown1 . $options . $unknown2 . $url_len . $url); return 0; } /** * Used to write internal reference hyperlinks such as "Sheet1!A1". * * @access private * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row * @param integer $col2 End column * @param string $url URL string * @return integer */ public function writeUrlInternal($row1, $col1, $row2, $col2, $url) { $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow // Strip URL type $url = preg_replace('/^internal:/', '', $url); // Pack the undocumented parts of the hyperlink stream $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); // Pack the option flags $options = pack("V", 0x08); // Convert the URL type and to a null terminated wchar string $url .= "\0"; // character count $url_len = PHPExcel_Shared_String::CountCharacters($url); $url_len = pack('V', $url_len); $url = PHPExcel_Shared_String::ConvertEncoding($url, 'UTF-16LE', 'UTF-8'); // Calculate the data length $length = 0x24 + strlen($url); // Pack the header data $header = pack("vv", $record, $length); $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data $this->append($header . $data . $unknown1 . $options . $url_len . $url); return 0; } /** * Write links to external directory names such as 'c:\foo.xls', * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. * * Note: Excel writes some relative links with the $dir_long string. We ignore * these cases for the sake of simpler code. * * @access private * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row * @param integer $col2 End column * @param string $url URL string * @return integer */ public function writeUrlExternal($row1, $col1, $row2, $col2, $url) { // Network drives are different. We will handle them separately // MS/Novell network drives and shares start with \\ if (preg_match('[^external:\\\\]', $url)) { return; //($this->writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); } $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow // Strip URL type and change Unix dir separator to Dos style (if needed) // $url = preg_replace('/^external:/', '', $url); $url = preg_replace('/\//', "\\", $url); // Determine if the link is relative or absolute: // relative if link contains no dir separator, "somefile.xls" // relative if link starts with up-dir, "..\..\somefile.xls" // otherwise, absolute $absolute = 0x00; // relative path if (preg_match('/^[A-Z]:/', $url)) { $absolute = 0x02; // absolute path on Windows, e.g. C:\... } $link_type = 0x01 | $absolute; // Determine if the link contains a sheet reference and change some of the // parameters accordingly. // Split the dir name and sheet name (if it exists) $dir_long = $url; if (preg_match("/\#/", $url)) { $link_type |= 0x08; } // Pack the link type $link_type = pack("V", $link_type); // Calculate the up-level dir count e.g.. (..\..\..\ == 3) $up_count = preg_match_all("/\.\.\\\/", $dir_long, $useless); $up_count = pack("v", $up_count); // Store the short dos dir name (null terminated) $dir_short = preg_replace("/\.\.\\\/", '', $dir_long) . "\0"; // Store the long dir name as a wchar string (non-null terminated) $dir_long = $dir_long . "\0"; // Pack the lengths of the dir strings $dir_short_len = pack("V", strlen($dir_short)); $dir_long_len = pack("V", strlen($dir_long)); $stream_len = pack("V", 0); //strlen($dir_long) + 0x06); // Pack the undocumented parts of the hyperlink stream $unknown1 = pack("H*", 'D0C9EA79F9BACE118C8200AA004BA90B02000000'); $unknown2 = pack("H*", '0303000000000000C000000000000046'); $unknown3 = pack("H*", 'FFFFADDE000000000000000000000000000000000000000'); $unknown4 = pack("v", 0x03); // Pack the main data stream $data = pack("vvvv", $row1, $row2, $col1, $col2) . $unknown1 . $link_type . $unknown2 . $up_count . $dir_short_len. $dir_short . $unknown3 . $stream_len ;/*. $dir_long_len . $unknown4 . $dir_long . $sheet_len . $sheet ;*/ // Pack the header data $length = strlen($data); $header = pack("vv", $record, $length); // Write the packed data $this->append($header. $data); return 0; } /** * This method is used to set the height and format for a row. * * @param integer $row The row to set * @param integer $height Height we are giving to the row. * Use null to set XF without setting height * @param integer $xfIndex The optional cell style Xf index to apply to the columns * @param bool $hidden The optional hidden attribute * @param integer $level The optional outline level for row, in range [0,7] */ private function writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) { $record = 0x0208; // Record identifier $length = 0x0010; // Number of bytes to follow $colMic = 0x0000; // First defined column $colMac = 0x0000; // Last defined column $irwMac = 0x0000; // Used by Excel to optimise loading $reserved = 0x0000; // Reserved $grbit = 0x0000; // Option flags $ixfe = $xfIndex; if ($height < 0) { $height = null; } // Use writeRow($row, null, $XF) to set XF format without setting height if ($height != null) { $miyRw = $height * 20; // row height } else { $miyRw = 0xff; // default row height is 256 } // Set the options flags. fUnsynced is used to show that the font and row // heights are not compatible. This is usually the case for WriteExcel. // The collapsed flag 0x10 doesn't seem to be used to indicate that a row // is collapsed. Instead it is used to indicate that the previous row is // collapsed. The zero height flag, 0x20, is used to collapse a row. $grbit |= $level; if ($hidden) { $grbit |= 0x0030; } if ($height !== null) { $grbit |= 0x0040; // fUnsynced } if ($xfIndex !== 0xF) { $grbit |= 0x0080; } $grbit |= 0x0100; $header = pack("vv", $record, $length); $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, $irwMac, $reserved, $grbit, $ixfe); $this->append($header.$data); } /** * Writes Excel DIMENSIONS to define the area in which there is data. */ private function writeDimensions() { $record = 0x0200; // Record identifier $length = 0x000E; $data = pack('VVvvv', $this->firstRowIndex, $this->lastRowIndex + 1, $this->firstColumnIndex, $this->lastColumnIndex + 1, 0x0000); // reserved $header = pack("vv", $record, $length); $this->append($header.$data); } /** * Write BIFF record Window2. */ private function writeWindow2() { $record = 0x023E; // Record identifier $length = 0x0012; $grbit = 0x00B6; // Option flags $rwTop = 0x0000; // Top row visible in window $colLeft = 0x0000; // Leftmost column visible in window // The options flags that comprise $grbit $fDspFmla = 0; // 0 - bit $fDspGrid = $this->phpSheet->getShowGridlines() ? 1 : 0; // 1 $fDspRwCol = $this->phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 $fFrozen = $this->phpSheet->getFreezePane() ? 1 : 0; // 3 $fDspZeros = 1; // 4 $fDefaultHdr = 1; // 5 $fArabic = $this->phpSheet->getRightToLeft() ? 1 : 0; // 6 $fDspGuts = $this->outlineOn; // 7 $fFrozenNoSplit = 0; // 0 - bit // no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet $fSelected = ($this->phpSheet === $this->phpSheet->getParent()->getActiveSheet()) ? 1 : 0; $fPaged = 1; // 2 $fPageBreakPreview = $this->phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; $grbit = $fDspFmla; $grbit |= $fDspGrid << 1; $grbit |= $fDspRwCol << 2; $grbit |= $fFrozen << 3; $grbit |= $fDspZeros << 4; $grbit |= $fDefaultHdr << 5; $grbit |= $fArabic << 6; $grbit |= $fDspGuts << 7; $grbit |= $fFrozenNoSplit << 8; $grbit |= $fSelected << 9; $grbit |= $fPaged << 10; $grbit |= $fPageBreakPreview << 11; $header = pack("vv", $record, $length); $data = pack("vvv", $grbit, $rwTop, $colLeft); // FIXME !!! $rgbHdr = 0x0040; // Row/column heading and gridline color index $zoom_factor_page_break = ($fPageBreakPreview ? $this->phpSheet->getSheetView()->getZoomScale() : 0x0000); $zoom_factor_normal = $this->phpSheet->getSheetView()->getZoomScaleNormal(); $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); $this->append($header.$data); } /** * Write BIFF record DEFAULTROWHEIGHT. */ private function writeDefaultRowHeight() { $defaultRowHeight = $this->phpSheet->getDefaultRowDimension()->getRowHeight(); if ($defaultRowHeight < 0) { return; } // convert to twips $defaultRowHeight = (int) 20 * $defaultRowHeight; $record = 0x0225; // Record identifier $length = 0x0004; // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("vv", 1, $defaultRowHeight); $this->append($header . $data); } /** * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. */ private function writeDefcol() { $defaultColWidth = 8; $record = 0x0055; // Record identifier $length = 0x0002; // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("v", $defaultColWidth); $this->append($header . $data); } /** * Write BIFF record COLINFO to define column widths * * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C * length record. * * @param array $col_array This is the only parameter received and is composed of the following: * 0 => First formatted column, * 1 => Last formatted column, * 2 => Col width (8.43 is Excel default), * 3 => The optional XF format of the column, * 4 => Option flags. * 5 => Optional outline level */ private function writeColinfo($col_array) { if (isset($col_array[0])) { $colFirst = $col_array[0]; } if (isset($col_array[1])) { $colLast = $col_array[1]; } if (isset($col_array[2])) { $coldx = $col_array[2]; } else { $coldx = 8.43; } if (isset($col_array[3])) { $xfIndex = $col_array[3]; } else { $xfIndex = 15; } if (isset($col_array[4])) { $grbit = $col_array[4]; } else { $grbit = 0; } if (isset($col_array[5])) { $level = $col_array[5]; } else { $level = 0; } $record = 0x007D; // Record identifier $length = 0x000C; // Number of bytes to follow $coldx *= 256; // Convert to units of 1/256 of a char $ixfe = $xfIndex; $reserved = 0x0000; // Reserved $level = max(0, min($level, 7)); $grbit |= $level << 8; $header = pack("vv", $record, $length); $data = pack("vvvvvv", $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved); $this->append($header.$data); } /** * Write BIFF record SELECTION. */ private function writeSelection() { // look up the selected cell range $selectedCells = $this->phpSheet->getSelectedCells(); $selectedCells = PHPExcel_Cell::splitRange($this->phpSheet->getSelectedCells()); $selectedCells = $selectedCells[0]; if (count($selectedCells) == 2) { list($first, $last) = $selectedCells; } else { $first = $selectedCells[0]; $last = $selectedCells[0]; } list($colFirst, $rwFirst) = PHPExcel_Cell::coordinateFromString($first); $colFirst = PHPExcel_Cell::columnIndexFromString($colFirst) - 1; // base 0 column index --$rwFirst; // base 0 row index list($colLast, $rwLast) = PHPExcel_Cell::coordinateFromString($last); $colLast = PHPExcel_Cell::columnIndexFromString($colLast) - 1; // base 0 column index --$rwLast; // base 0 row index // make sure we are not out of bounds $colFirst = min($colFirst, 255); $colLast = min($colLast, 255); $rwFirst = min($rwFirst, 65535); $rwLast = min($rwLast, 65535); $record = 0x001D; // Record identifier $length = 0x000F; // Number of bytes to follow $pnn = $this->activePane; // Pane position $rwAct = $rwFirst; // Active row $colAct = $colFirst; // Active column $irefAct = 0; // Active cell ref $cref = 1; // Number of refs if (!isset($rwLast)) { $rwLast = $rwFirst; // Last row in reference } if (!isset($colLast)) { $colLast = $colFirst; // Last col in reference } // Swap last row/col for first row/col as necessary if ($rwFirst > $rwLast) { list($rwFirst, $rwLast) = array($rwLast, $rwFirst); } if ($colFirst > $colLast) { list($colFirst, $colLast) = array($colLast, $colFirst); } $header = pack("vv", $record, $length); $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, $irefAct, $cref, $rwFirst, $rwLast, $colFirst, $colLast); $this->append($header . $data); } /** * Store the MERGEDCELLS records for all ranges of merged cells */ private function writeMergedCells() { $mergeCells = $this->phpSheet->getMergeCells(); $countMergeCells = count($mergeCells); if ($countMergeCells == 0) { return; } // maximum allowed number of merged cells per record $maxCountMergeCellsPerRecord = 1027; // record identifier $record = 0x00E5; // counter for total number of merged cells treated so far by the writer $i = 0; // counter for number of merged cells written in record currently being written $j = 0; // initialize record data $recordData = ''; // loop through the merged cells foreach ($mergeCells as $mergeCell) { ++$i; ++$j; // extract the row and column indexes $range = PHPExcel_Cell::splitRange($mergeCell); list($first, $last) = $range[0]; list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($first); list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($last); $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, PHPExcel_Cell::columnIndexFromString($firstColumn) - 1, PHPExcel_Cell::columnIndexFromString($lastColumn) - 1); // flush record if we have reached limit for number of merged cells, or reached final merged cell if ($j == $maxCountMergeCellsPerRecord or $i == $countMergeCells) { $recordData = pack('v', $j) . $recordData; $length = strlen($recordData); $header = pack('vv', $record, $length); $this->append($header . $recordData); // initialize for next record, if any $recordData = ''; $j = 0; } } } /** * Write SHEETLAYOUT record */ private function writeSheetLayout() { if (!$this->phpSheet->isTabColorSet()) { return; } $recordData = pack( 'vvVVVvv', 0x0862, 0x0000, // unused 0x00000000, // unused 0x00000000, // unused 0x00000014, // size of record data $this->colors[$this->phpSheet->getTabColor()->getRGB()], // color index 0x0000 // unused ); $length = strlen($recordData); $record = 0x0862; // Record identifier $header = pack('vv', $record, $length); $this->append($header . $recordData); } /** * Write SHEETPROTECTION */ private function writeSheetProtection() { // record identifier $record = 0x0867; // prepare options $options = (int) !$this->phpSheet->getProtection()->getObjects() | (int) !$this->phpSheet->getProtection()->getScenarios() << 1 | (int) !$this->phpSheet->getProtection()->getFormatCells() << 2 | (int) !$this->phpSheet->getProtection()->getFormatColumns() << 3 | (int) !$this->phpSheet->getProtection()->getFormatRows() << 4 | (int) !$this->phpSheet->getProtection()->getInsertColumns() << 5 | (int) !$this->phpSheet->getProtection()->getInsertRows() << 6 | (int) !$this->phpSheet->getProtection()->getInsertHyperlinks() << 7 | (int) !$this->phpSheet->getProtection()->getDeleteColumns() << 8 | (int) !$this->phpSheet->getProtection()->getDeleteRows() << 9 | (int) !$this->phpSheet->getProtection()->getSelectLockedCells() << 10 | (int) !$this->phpSheet->getProtection()->getSort() << 11 | (int) !$this->phpSheet->getProtection()->getAutoFilter() << 12 | (int) !$this->phpSheet->getProtection()->getPivotTables() << 13 | (int) !$this->phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; // record data $recordData = pack( 'vVVCVVvv', 0x0867, // repeated record identifier 0x0000, // not used 0x0000, // not used 0x00, // not used 0x01000200, // unknown data 0xFFFFFFFF, // unknown data $options, // options 0x0000 // not used ); $length = strlen($recordData); $header = pack('vv', $record, $length); $this->append($header . $recordData); } /** * Write BIFF record RANGEPROTECTION * * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records */ private function writeRangeProtection() { foreach ($this->phpSheet->getProtectedCells() as $range => $password) { // number of ranges, e.g. 'A1:B3 C20:D25' $cellRanges = explode(' ', $range); $cref = count($cellRanges); $recordData = pack( 'vvVVvCVvVv', 0x0868, 0x00, 0x0000, 0x0000, 0x02, 0x0, 0x0000, $cref, 0x0000, 0x00 ); foreach ($cellRanges as $cellRange) { $recordData .= $this->writeBIFF8CellRangeAddressFixed($cellRange); } // the rgbFeat structure $recordData .= pack( 'VV', 0x0000, hexdec($password) ); $recordData .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong('p' . md5($recordData)); $length = strlen($recordData); $record = 0x0868; // Record identifier $header = pack("vv", $record, $length); $this->append($header . $recordData); } } /** * Write BIFF record EXTERNCOUNT to indicate the number of external sheet * references in a worksheet. * * Excel only stores references to external sheets that are used in formulas. * For simplicity we store references to all the sheets in the workbook * regardless of whether they are used or not. This reduces the overall * complexity and eliminates the need for a two way dialogue between the formula * parser the worksheet objects. * * @param integer $count The number of external sheet references in this worksheet */ private function writeExterncount($count) { $record = 0x0016; // Record identifier $length = 0x0002; // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("v", $count); $this->append($header . $data); } /** * Writes the Excel BIFF EXTERNSHEET record. These references are used by * formulas. A formula references a sheet name via an index. Since we store a * reference to all of the external worksheets the EXTERNSHEET index is the same * as the worksheet index. * * @param string $sheetname The name of a external worksheet */ private function writeExternsheet($sheetname) { $record = 0x0017; // Record identifier // References to the current sheet are encoded differently to references to // external sheets. // if ($this->phpSheet->getTitle() == $sheetname) { $sheetname = ''; $length = 0x02; // The following 2 bytes $cch = 1; // The following byte $rgch = 0x02; // Self reference } else { $length = 0x02 + strlen($sheetname); $cch = strlen($sheetname); $rgch = 0x03; // Reference to a sheet in the current workbook } $header = pack("vv", $record, $length); $data = pack("CC", $cch, $rgch); $this->append($header . $data . $sheetname); } /** * Writes the Excel BIFF PANE record. * The panes can either be frozen or thawed (unfrozen). * Frozen panes are specified in terms of an integer number of rows and columns. * Thawed panes are specified in terms of Excel's units for rows and columns. */ private function writePanes() { $panes = array(); if ($freezePane = $this->phpSheet->getFreezePane()) { list($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane); $panes[0] = $row - 1; $panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1; } else { // thaw panes return; } $y = isset($panes[0]) ? $panes[0] : null; $x = isset($panes[1]) ? $panes[1] : null; $rwTop = isset($panes[2]) ? $panes[2] : null; $colLeft = isset($panes[3]) ? $panes[3] : null; if (count($panes) > 4) { // if Active pane was received $pnnAct = $panes[4]; } else { $pnnAct = null; } $record = 0x0041; // Record identifier $length = 0x000A; // Number of bytes to follow // Code specific to frozen or thawed panes. if ($this->phpSheet->getFreezePane()) { // Set default values for $rwTop and $colLeft if (!isset($rwTop)) { $rwTop = $y; } if (!isset($colLeft)) { $colLeft = $x; } } else { // Set default values for $rwTop and $colLeft if (!isset($rwTop)) { $rwTop = 0; } if (!isset($colLeft)) { $colLeft = 0; } // Convert Excel's row and column units to the internal units. // The default row height is 12.75 // The default column width is 8.43 // The following slope and intersection values were interpolated. // $y = 20*$y + 255; $x = 113.879*$x + 390; } // Determine which pane should be active. There is also the undocumented // option to override this should it be necessary: may be removed later. // if (!isset($pnnAct)) { if ($x != 0 && $y != 0) { $pnnAct = 0; // Bottom right } if ($x != 0 && $y == 0) { $pnnAct = 1; // Top right } if ($x == 0 && $y != 0) { $pnnAct = 2; // Bottom left } if ($x == 0 && $y == 0) { $pnnAct = 3; // Top left } } $this->activePane = $pnnAct; // Used in writeSelection $header = pack("vv", $record, $length); $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); $this->append($header . $data); } /** * Store the page setup SETUP BIFF record. */ private function writeSetup() { $record = 0x00A1; // Record identifier $length = 0x0022; // Number of bytes to follow $iPaperSize = $this->phpSheet->getPageSetup()->getPaperSize(); // Paper size $iScale = $this->phpSheet->getPageSetup()->getScale() ? $this->phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor $iPageStart = 0x01; // Starting page number $iFitWidth = (int) $this->phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide $iFitHeight = (int) $this->phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high $grbit = 0x00; // Option flags $iRes = 0x0258; // Print resolution $iVRes = 0x0258; // Vertical print resolution $numHdr = $this->phpSheet->getPageMargins()->getHeader(); // Header Margin $numFtr = $this->phpSheet->getPageMargins()->getFooter(); // Footer Margin $iCopies = 0x01; // Number of copies $fLeftToRight = 0x0; // Print over then down // Page orientation $fLandscape = ($this->phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 0x0 : 0x1; $fNoPls = 0x0; // Setup not read from printer $fNoColor = 0x0; // Print black and white $fDraft = 0x0; // Print draft quality $fNotes = 0x0; // Print notes $fNoOrient = 0x0; // Orientation not set $fUsePage = 0x0; // Use custom starting page $grbit = $fLeftToRight; $grbit |= $fLandscape << 1; $grbit |= $fNoPls << 2; $grbit |= $fNoColor << 3; $grbit |= $fDraft << 4; $grbit |= $fNotes << 5; $grbit |= $fNoOrient << 6; $grbit |= $fUsePage << 7; $numHdr = pack("d", $numHdr); $numFtr = pack("d", $numFtr); if (self::getByteOrder()) { // if it's Big Endian $numHdr = strrev($numHdr); $numFtr = strrev($numFtr); } $header = pack("vv", $record, $length); $data1 = pack("vvvvvvvv", $iPaperSize, $iScale, $iPageStart, $iFitWidth, $iFitHeight, $grbit, $iRes, $iVRes); $data2 = $numHdr.$numFtr; $data3 = pack("v", $iCopies); $this->append($header . $data1 . $data2 . $data3); } /** * Store the header caption BIFF record. */ private function writeHeader() { $record = 0x0014; // Record identifier /* removing for now // need to fix character count (multibyte!) if (strlen($this->phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { $str = $this->phpSheet->getHeaderFooter()->getOddHeader(); // header string } else { $str = ''; } */ $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->phpSheet->getHeaderFooter()->getOddHeader()); $length = strlen($recordData); $header = pack("vv", $record, $length); $this->append($header . $recordData); } /** * Store the footer caption BIFF record. */ private function writeFooter() { $record = 0x0015; // Record identifier /* removing for now // need to fix character count (multibyte!) if (strlen($this->phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { $str = $this->phpSheet->getHeaderFooter()->getOddFooter(); } else { $str = ''; } */ $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->phpSheet->getHeaderFooter()->getOddFooter()); $length = strlen($recordData); $header = pack("vv", $record, $length); $this->append($header . $recordData); } /** * Store the horizontal centering HCENTER BIFF record. * * @access private */ private function writeHcenter() { $record = 0x0083; // Record identifier $length = 0x0002; // Bytes to follow $fHCenter = $this->phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering $header = pack("vv", $record, $length); $data = pack("v", $fHCenter); $this->append($header.$data); } /** * Store the vertical centering VCENTER BIFF record. */ private function writeVcenter() { $record = 0x0084; // Record identifier $length = 0x0002; // Bytes to follow $fVCenter = $this->phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering $header = pack("vv", $record, $length); $data = pack("v", $fVCenter); $this->append($header . $data); } /** * Store the LEFTMARGIN BIFF record. */ private function writeMarginLeft() { $record = 0x0026; // Record identifier $length = 0x0008; // Bytes to follow $margin = $this->phpSheet->getPageMargins()->getLeft(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } $this->append($header . $data); } /** * Store the RIGHTMARGIN BIFF record. */ private function writeMarginRight() { $record = 0x0027; // Record identifier $length = 0x0008; // Bytes to follow $margin = $this->phpSheet->getPageMargins()->getRight(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } $this->append($header . $data); } /** * Store the TOPMARGIN BIFF record. */ private function writeMarginTop() { $record = 0x0028; // Record identifier $length = 0x0008; // Bytes to follow $margin = $this->phpSheet->getPageMargins()->getTop(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } $this->append($header . $data); } /** * Store the BOTTOMMARGIN BIFF record. */ private function writeMarginBottom() { $record = 0x0029; // Record identifier $length = 0x0008; // Bytes to follow $margin = $this->phpSheet->getPageMargins()->getBottom(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } $this->append($header . $data); } /** * Write the PRINTHEADERS BIFF record. */ private function writePrintHeaders() { $record = 0x002a; // Record identifier $length = 0x0002; // Bytes to follow $fPrintRwCol = $this->_print_headers; // Boolean flag $header = pack("vv", $record, $length); $data = pack("v", $fPrintRwCol); $this->append($header . $data); } /** * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the * GRIDSET record. */ private function writePrintGridlines() { $record = 0x002b; // Record identifier $length = 0x0002; // Bytes to follow $fPrintGrid = $this->phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag $header = pack("vv", $record, $length); $data = pack("v", $fPrintGrid); $this->append($header . $data); } /** * Write the GRIDSET BIFF record. Must be used in conjunction with the * PRINTGRIDLINES record. */ private function writeGridset() { $record = 0x0082; // Record identifier $length = 0x0002; // Bytes to follow $fGridSet = !$this->phpSheet->getPrintGridlines(); // Boolean flag $header = pack("vv", $record, $length); $data = pack("v", $fGridSet); $this->append($header . $data); } /** * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. */ private function writeAutoFilterInfo() { $record = 0x009D; // Record identifier $length = 0x0002; // Bytes to follow $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->phpSheet->getAutoFilter()->getRange()); $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; $header = pack("vv", $record, $length); $data = pack("v", $iNumFilters); $this->append($header . $data); } /** * Write the GUTS BIFF record. This is used to configure the gutter margins * where Excel outline symbols are displayed. The visibility of the gutters is * controlled by a flag in WSBOOL. * * @see writeWsbool() */ private function writeGuts() { $record = 0x0080; // Record identifier $length = 0x0008; // Bytes to follow $dxRwGut = 0x0000; // Size of row gutter $dxColGut = 0x0000; // Size of col gutter // determine maximum row outline level $maxRowOutlineLevel = 0; foreach ($this->phpSheet->getRowDimensions() as $rowDimension) { $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel()); } $col_level = 0; // Calculate the maximum column outline level. The equivalent calculation // for the row outline level is carried out in writeRow(). $colcount = count($this->columnInfo); for ($i = 0; $i < $colcount; ++$i) { $col_level = max($this->columnInfo[$i][5], $col_level); } // Set the limits for the outline levels (0 <= x <= 7). $col_level = max(0, min($col_level, 7)); // The displayed level is one greater than the max outline levels if ($maxRowOutlineLevel) { ++$maxRowOutlineLevel; } if ($col_level) { ++$col_level; } $header = pack("vv", $record, $length); $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); $this->append($header.$data); } /** * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction * with the SETUP record. */ private function writeWsbool() { $record = 0x0081; // Record identifier $length = 0x0002; // Bytes to follow $grbit = 0x0000; // The only option that is of interest is the flag for fit to page. So we // set all the options in one go. // // Set the option flags $grbit |= 0x0001; // Auto page breaks visible if ($this->outlineStyle) { $grbit |= 0x0020; // Auto outline styles } if ($this->phpSheet->getShowSummaryBelow()) { $grbit |= 0x0040; // Outline summary below } if ($this->phpSheet->getShowSummaryRight()) { $grbit |= 0x0080; // Outline summary right } if ($this->phpSheet->getPageSetup()->getFitToPage()) { $grbit |= 0x0100; // Page setup fit to page } if ($this->outlineOn) { $grbit |= 0x0400; // Outline symbols displayed } $header = pack("vv", $record, $length); $data = pack("v", $grbit); $this->append($header . $data); } /** * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records. */ private function writeBreaks() { // initialize $vbreaks = array(); $hbreaks = array(); foreach ($this->phpSheet->getBreaks() as $cell => $breakType) { // Fetch coordinates $coordinates = PHPExcel_Cell::coordinateFromString($cell); // Decide what to do by the type of break switch ($breakType) { case PHPExcel_Worksheet::BREAK_COLUMN: // Add to list of vertical breaks $vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1; break; case PHPExcel_Worksheet::BREAK_ROW: // Add to list of horizontal breaks $hbreaks[] = $coordinates[1]; break; case PHPExcel_Worksheet::BREAK_NONE: default: // Nothing to do break; } } //horizontal page breaks if (!empty($hbreaks)) { // Sort and filter array of page breaks sort($hbreaks, SORT_NUMERIC); if ($hbreaks[0] == 0) { // don't use first break if it's 0 array_shift($hbreaks); } $record = 0x001b; // Record identifier $cbrk = count($hbreaks); // Number of page breaks $length = 2 + 6 * $cbrk; // Bytes to follow $header = pack("vv", $record, $length); $data = pack("v", $cbrk); // Append each page break foreach ($hbreaks as $hbreak) { $data .= pack("vvv", $hbreak, 0x0000, 0x00ff); } $this->append($header . $data); } // vertical page breaks if (!empty($vbreaks)) { // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. // It is slightly higher in Excel 97/200, approx. 1026 $vbreaks = array_slice($vbreaks, 0, 1000); // Sort and filter array of page breaks sort($vbreaks, SORT_NUMERIC); if ($vbreaks[0] == 0) { // don't use first break if it's 0 array_shift($vbreaks); } $record = 0x001a; // Record identifier $cbrk = count($vbreaks); // Number of page breaks $length = 2 + 6 * $cbrk; // Bytes to follow $header = pack("vv", $record, $length); $data = pack("v", $cbrk); // Append each page break foreach ($vbreaks as $vbreak) { $data .= pack("vvv", $vbreak, 0x0000, 0xffff); } $this->append($header . $data); } } /** * Set the Biff PROTECT record to indicate that the worksheet is protected. */ private function writeProtect() { // Exit unless sheet protection has been specified if (!$this->phpSheet->getProtection()->getSheet()) { return; } $record = 0x0012; // Record identifier $length = 0x0002; // Bytes to follow $fLock = 1; // Worksheet is protected $header = pack("vv", $record, $length); $data = pack("v", $fLock); $this->append($header.$data); } /** * Write SCENPROTECT */ private function writeScenProtect() { // Exit if sheet protection is not active if (!$this->phpSheet->getProtection()->getSheet()) { return; } // Exit if scenarios are not protected if (!$this->phpSheet->getProtection()->getScenarios()) { return; } $record = 0x00DD; // Record identifier $length = 0x0002; // Bytes to follow $header = pack('vv', $record, $length); $data = pack('v', 1); $this->append($header . $data); } /** * Write OBJECTPROTECT */ private function writeObjectProtect() { // Exit if sheet protection is not active if (!$this->phpSheet->getProtection()->getSheet()) { return; } // Exit if objects are not protected if (!$this->phpSheet->getProtection()->getObjects()) { return; } $record = 0x0063; // Record identifier $length = 0x0002; // Bytes to follow $header = pack('vv', $record, $length); $data = pack('v', 1); $this->append($header . $data); } /** * Write the worksheet PASSWORD record. */ private function writePassword() { // Exit unless sheet protection and password have been specified if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword()) { return; } $record = 0x0013; // Record identifier $length = 0x0002; // Bytes to follow $wPassword = hexdec($this->phpSheet->getProtection()->getPassword()); // Encoded password $header = pack("vv", $record, $length); $data = pack("v", $wPassword); $this->append($header . $data); } /** * Insert a 24bit bitmap image in a worksheet. * * @access public * @param integer $row The row we are going to insert the bitmap into * @param integer $col The column we are going to insert the bitmap into * @param mixed $bitmap The bitmap filename or GD-image resource * @param integer $x The horizontal position (offset) of the image inside the cell. * @param integer $y The vertical position (offset) of the image inside the cell. * @param float $scale_x The horizontal scale * @param float $scale_y The vertical scale */ public function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) { $bitmap_array = (is_resource($bitmap) ? $this->processBitmapGd($bitmap) : $this->processBitmap($bitmap)); list($width, $height, $size, $data) = $bitmap_array; //$this->processBitmap($bitmap); // Scale the frame of the image. $width *= $scale_x; $height *= $scale_y; // Calculate the vertices of the image and write the OBJ record $this->positionImage($col, $row, $x, $y, $width, $height); // Write the IMDATA record to store the bitmap data $record = 0x007f; $length = 8 + $size; $cf = 0x09; $env = 0x01; $lcb = $size; $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); $this->append($header.$data); } /** * Calculate the vertices that define the position of the image as required by * the OBJ record. * * +------------+------------+ * | A | B | * +-----+------------+------------+ * | |(x1,y1) | | * | 1 |(A1)._______|______ | * | | | | | * | | | | | * +-----+----| BITMAP |-----+ * | | | | | * | 2 | |______________. | * | | | (B2)| * | | | (x2,y2)| * +---- +------------+------------+ * * Example of a bitmap that covers some of the area from cell A1 to cell B2. * * Based on the width and height of the bitmap we need to calculate 8 vars: * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. * The width and height of the cells are also variable and have to be taken into * account. * The values of $col_start and $row_start are passed in from the calling * function. The values of $col_end and $row_end are calculated by subtracting * the width and height of the bitmap from the width and height of the * underlying cells. * The vertices are expressed as a percentage of the underlying cell width as * follows (rhs values are in pixels): * * x1 = X / W *1024 * y1 = Y / H *256 * x2 = (X-1) / W *1024 * y2 = (Y-1) / H *256 * * Where: X is distance from the left side of the underlying cell * Y is distance from the top of the underlying cell * W is the width of the cell * H is the height of the cell * The SDK incorrectly states that the height should be expressed as a * percentage of 1024. * * @access private * @param integer $col_start Col containing upper left corner of object * @param integer $row_start Row containing top left corner of object * @param integer $x1 Distance to left side of object * @param integer $y1 Distance to top of object * @param integer $width Width of image frame * @param integer $height Height of image frame */ public function positionImage($col_start, $row_start, $x1, $y1, $width, $height) { // Initialise end cell to the same as the start cell $col_end = $col_start; // Col containing lower right corner of object $row_end = $row_start; // Row containing bottom right corner of object // Zero the specified offset if greater than the cell dimensions if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { $x1 = 0; } if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_start + 1)) { $y1 = 0; } $width = $width + $x1 -1; $height = $height + $y1 -1; // Subtract the underlying cell widths to find the end cell of the image while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { $width -= PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); ++$col_end; } // Subtract the underlying cell heights to find the end cell of the image while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1)) { $height -= PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1); ++$row_end; } // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell // with zero eight or width. // if (PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { return; } if (PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { return; } if (PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_start + 1) == 0) { return; } if (PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1) == 0) { return; } // Convert the pixel values to the percentage value expected by Excel $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_start + 1) * 256; $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1) * 256; // Distance to bottom of object $this->writeObjPicture($col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2); } /** * Store the OBJ record that precedes an IMDATA record. This could be generalise * to support other Excel objects. * * @param integer $colL Column containing upper left corner of object * @param integer $dxL Distance from left side of cell * @param integer $rwT Row containing top left corner of object * @param integer $dyT Distance from top of cell * @param integer $colR Column containing lower right corner of object * @param integer $dxR Distance from right of cell * @param integer $rwB Row containing bottom right corner of object * @param integer $dyB Distance from bottom of cell */ private function writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $dyB) { $record = 0x005d; // Record identifier $length = 0x003c; // Bytes to follow $cObj = 0x0001; // Count of objects in file (set to 1) $OT = 0x0008; // Object type. 8 = Picture $id = 0x0001; // Object ID $grbit = 0x0614; // Option flags $cbMacro = 0x0000; // Length of FMLA structure $Reserved1 = 0x0000; // Reserved $Reserved2 = 0x0000; // Reserved $icvBack = 0x09; // Background colour $icvFore = 0x09; // Foreground colour $fls = 0x00; // Fill pattern $fAuto = 0x00; // Automatic fill $icv = 0x08; // Line colour $lns = 0xff; // Line style $lnw = 0x01; // Line weight $fAutoB = 0x00; // Automatic border $frs = 0x0000; // Frame style $cf = 0x0009; // Image format, 9 = bitmap $Reserved3 = 0x0000; // Reserved $cbPictFmla = 0x0000; // Length of FMLA structure $Reserved4 = 0x0000; // Reserved $grbit2 = 0x0001; // Option flags $Reserved5 = 0x0000; // Reserved $header = pack("vv", $record, $length); $data = pack("V", $cObj); $data .= pack("v", $OT); $data .= pack("v", $id); $data .= pack("v", $grbit); $data .= pack("v", $colL); $data .= pack("v", $dxL); $data .= pack("v", $rwT); $data .= pack("v", $dyT); $data .= pack("v", $colR); $data .= pack("v", $dxR); $data .= pack("v", $rwB); $data .= pack("v", $dyB); $data .= pack("v", $cbMacro); $data .= pack("V", $Reserved1); $data .= pack("v", $Reserved2); $data .= pack("C", $icvBack); $data .= pack("C", $icvFore); $data .= pack("C", $fls); $data .= pack("C", $fAuto); $data .= pack("C", $icv); $data .= pack("C", $lns); $data .= pack("C", $lnw); $data .= pack("C", $fAutoB); $data .= pack("v", $frs); $data .= pack("V", $cf); $data .= pack("v", $Reserved3); $data .= pack("v", $cbPictFmla); $data .= pack("v", $Reserved4); $data .= pack("v", $grbit2); $data .= pack("V", $Reserved5); $this->append($header . $data); } /** * Convert a GD-image into the internal format. * * @access private * @param resource $image The image to process * @return array Array with data and properties of the bitmap */ public function processBitmapGd($image) { $width = imagesx($image); $height = imagesy($image); $data = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); for ($j=$height; $j--;) { for ($i=0; $i < $width; ++$i) { $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); foreach (array("red", "green", "blue") as $key) { $color[$key] = $color[$key] + round((255 - $color[$key]) * $color["alpha"] / 127); } $data .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]); } if (3*$width % 4) { $data .= str_repeat("\x00", 4 - 3*$width % 4); } } return array($width, $height, strlen($data), $data); } /** * Convert a 24 bit bitmap into the modified internal format used by Windows. * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the * MSDN library. * * @access private * @param string $bitmap The bitmap to process * @return array Array with data and properties of the bitmap */ public function processBitmap($bitmap) { // Open file. $bmp_fd = @fopen($bitmap, "rb"); if (!$bmp_fd) { throw new PHPExcel_Writer_Exception("Couldn't import $bitmap"); } // Slurp the file into a string. $data = fread($bmp_fd, filesize($bitmap)); // Check that the file is big enough to be a bitmap. if (strlen($data) <= 0x36) { throw new PHPExcel_Writer_Exception("$bitmap doesn't contain enough data.\n"); } // The first 2 bytes are used to identify the bitmap. $identity = unpack("A2ident", $data); if ($identity['ident'] != "BM") { throw new PHPExcel_Writer_Exception("$bitmap doesn't appear to be a valid bitmap image.\n"); } // Remove bitmap data: ID. $data = substr($data, 2); // Read and remove the bitmap size. This is more reliable than reading // the data size at offset 0x22. // $size_array = unpack("Vsa", substr($data, 0, 4)); $size = $size_array['sa']; $data = substr($data, 4); $size -= 0x36; // Subtract size of bitmap header. $size += 0x0C; // Add size of BIFF header. // Remove bitmap data: reserved, offset, header length. $data = substr($data, 12); // Read and remove the bitmap width and height. Verify the sizes. $width_and_height = unpack("V2", substr($data, 0, 8)); $width = $width_and_height[1]; $height = $width_and_height[2]; $data = substr($data, 8); if ($width > 0xFFFF) { throw new PHPExcel_Writer_Exception("$bitmap: largest image width supported is 65k.\n"); } if ($height > 0xFFFF) { throw new PHPExcel_Writer_Exception("$bitmap: largest image height supported is 65k.\n"); } // Read and remove the bitmap planes and bpp data. Verify them. $planes_and_bitcount = unpack("v2", substr($data, 0, 4)); $data = substr($data, 4); if ($planes_and_bitcount[2] != 24) { // Bitcount throw new PHPExcel_Writer_Exception("$bitmap isn't a 24bit true color bitmap.\n"); } if ($planes_and_bitcount[1] != 1) { throw new PHPExcel_Writer_Exception("$bitmap: only 1 plane supported in bitmap image.\n"); } // Read and remove the bitmap compression. Verify compression. $compression = unpack("Vcomp", substr($data, 0, 4)); $data = substr($data, 4); //$compression = 0; if ($compression['comp'] != 0) { throw new PHPExcel_Writer_Exception("$bitmap: compression not supported in bitmap image.\n"); } // Remove bitmap data: data size, hres, vres, colours, imp. colours. $data = substr($data, 20); // Add the BITMAPCOREHEADER data $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); $data = $header . $data; return (array($width, $height, $size, $data)); } /** * Store the window zoom factor. This should be a reduced fraction but for * simplicity we will store all fractions with a numerator of 100. */ private function writeZoom() { // If scale is 100 we don't need to write a record if ($this->phpSheet->getSheetView()->getZoomScale() == 100) { return; } $record = 0x00A0; // Record identifier $length = 0x0004; // Bytes to follow $header = pack("vv", $record, $length); $data = pack("vv", $this->phpSheet->getSheetView()->getZoomScale(), 100); $this->append($header . $data); } /** * Get Escher object * * @return PHPExcel_Shared_Escher */ public function getEscher() { return $this->escher; } /** * Set Escher object * * @param PHPExcel_Shared_Escher $pValue */ public function setEscher(PHPExcel_Shared_Escher $pValue = null) { $this->escher = $pValue; } /** * Write MSODRAWING record */ private function writeMsoDrawing() { // write the Escher stream if necessary if (isset($this->escher)) { $writer = new PHPExcel_Writer_Excel5_Escher($this->escher); $data = $writer->close(); $spOffsets = $writer->getSpOffsets(); $spTypes = $writer->getSpTypes(); // write the neccesary MSODRAWING, OBJ records // split the Escher stream $spOffsets[0] = 0; $nm = count($spOffsets) - 1; // number of shapes excluding first shape for ($i = 1; $i <= $nm; ++$i) { // MSODRAWING record $record = 0x00EC; // Record identifier // chunk of Escher stream for one shape $dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]); $length = strlen($dataChunk); $header = pack("vv", $record, $length); $this->append($header . $dataChunk); // OBJ record $record = 0x005D; // record identifier $objData = ''; // ftCmo if ($spTypes[$i] == 0x00C9) { // Add ftCmo (common object data) subobject $objData .= pack( 'vvvvvVVV', 0x0015, // 0x0015 = ftCmo 0x0012, // length of ftCmo data 0x0014, // object type, 0x0014 = filter $i, // object id number, Excel seems to use 1-based index, local for the sheet 0x2101, // option flags, 0x2001 is what OpenOffice.org uses 0, // reserved 0, // reserved 0 // reserved ); // Add ftSbs Scroll bar subobject $objData .= pack('vv', 0x00C, 0x0014); $objData .= pack('H*', '0000000000000000640001000A00000010000100'); // Add ftLbsData (List box data) subobject $objData .= pack('vv', 0x0013, 0x1FEE); $objData .= pack('H*', '00000000010001030000020008005700'); } else { // Add ftCmo (common object data) subobject $objData .= pack( 'vvvvvVVV', 0x0015, // 0x0015 = ftCmo 0x0012, // length of ftCmo data 0x0008, // object type, 0x0008 = picture $i, // object id number, Excel seems to use 1-based index, local for the sheet 0x6011, // option flags, 0x6011 is what OpenOffice.org uses 0, // reserved 0, // reserved 0 // reserved ); } // ftEnd $objData .= pack( 'vv', 0x0000, // 0x0000 = ftEnd 0x0000 // length of ftEnd data ); $length = strlen($objData); $header = pack('vv', $record, $length); $this->append($header . $objData); } } } /** * Store the DATAVALIDATIONS and DATAVALIDATION records. */ private function writeDataValidity() { // Datavalidation collection $dataValidationCollection = $this->phpSheet->getDataValidationCollection(); // Write data validations? if (!empty($dataValidationCollection)) { // DATAVALIDATIONS record $record = 0x01B2; // Record identifier $length = 0x0012; // Bytes to follow $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position $verPos = 0x00000000; // Vertical position of prompt box, if fixed position $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible $header = pack('vv', $record, $length); $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, count($dataValidationCollection)); $this->append($header.$data); // DATAVALIDATION records $record = 0x01BE; // Record identifier foreach ($dataValidationCollection as $cellCoordinate => $dataValidation) { // initialize record data $data = ''; // options $options = 0x00000000; // data type $type = $dataValidation->getType(); switch ($type) { case PHPExcel_Cell_DataValidation::TYPE_NONE: $type = 0x00; break; case PHPExcel_Cell_DataValidation::TYPE_WHOLE: $type = 0x01; break; case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: $type = 0x02; break; case PHPExcel_Cell_DataValidation::TYPE_LIST: $type = 0x03; break; case PHPExcel_Cell_DataValidation::TYPE_DATE: $type = 0x04; break; case PHPExcel_Cell_DataValidation::TYPE_TIME: $type = 0x05; break; case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: $type = 0x06; break; case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: $type = 0x07; break; } $options |= $type << 0; // error style $errorStyle = $dataValidation->getType(); switch ($errorStyle) { case PHPExcel_Cell_DataValidation::STYLE_STOP: $errorStyle = 0x00; break; case PHPExcel_Cell_DataValidation::STYLE_WARNING: $errorStyle = 0x01; break; case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: $errorStyle = 0x02; break; } $options |= $errorStyle << 4; // explicit formula? if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) { $options |= 0x01 << 7; } // empty cells allowed $options |= $dataValidation->getAllowBlank() << 8; // show drop down $options |= (!$dataValidation->getShowDropDown()) << 9; // show input message $options |= $dataValidation->getShowInputMessage() << 18; // show error message $options |= $dataValidation->getShowErrorMessage() << 19; // condition operator $operator = $dataValidation->getOperator(); switch ($operator) { case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00; break; case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01; break; case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02; break; case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03; break; case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04; break; case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05; break; case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06; break; case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07; break; } $options |= $operator << 20; $data = pack('V', $options); // prompt title $promptTitle = $dataValidation->getPromptTitle() !== '' ? $dataValidation->getPromptTitle() : chr(0); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($promptTitle); // error title $errorTitle = $dataValidation->getErrorTitle() !== '' ? $dataValidation->getErrorTitle() : chr(0); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($errorTitle); // prompt text $prompt = $dataValidation->getPrompt() !== '' ? $dataValidation->getPrompt() : chr(0); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($prompt); // error text $error = $dataValidation->getError() !== '' ? $dataValidation->getError() : chr(0); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($error); // formula 1 try { $formula1 = $dataValidation->getFormula1(); if ($type == 0x03) { // list type $formula1 = str_replace(',', chr(0), $formula1); } $this->parser->parse($formula1); $formula1 = $this->parser->toReversePolish(); $sz1 = strlen($formula1); } catch (PHPExcel_Exception $e) { $sz1 = 0; $formula1 = ''; } $data .= pack('vv', $sz1, 0x0000); $data .= $formula1; // formula 2 try { $formula2 = $dataValidation->getFormula2(); if ($formula2 === '') { throw new PHPExcel_Writer_Exception('No formula2'); } $this->parser->parse($formula2); $formula2 = $this->parser->toReversePolish(); $sz2 = strlen($formula2); } catch (PHPExcel_Exception $e) { $sz2 = 0; $formula2 = ''; } $data .= pack('vv', $sz2, 0x0000); $data .= $formula2; // cell range address list $data .= pack('v', 0x0001); $data .= $this->writeBIFF8CellRangeAddressFixed($cellCoordinate); $length = strlen($data); $header = pack("vv", $record, $length); $this->append($header . $data); } } } /** * Map Error code * * @param string $errorCode * @return int */ private static function mapErrorCode($errorCode) { switch ($errorCode) { case '#NULL!': return 0x00; case '#DIV/0!': return 0x07; case '#VALUE!': return 0x0F; case '#REF!': return 0x17; case '#NAME?': return 0x1D; case '#NUM!': return 0x24; case '#N/A': return 0x2A; } return 0; } /** * Write PLV Record */ private function writePageLayoutView() { $record = 0x088B; // Record identifier $length = 0x0010; // Bytes to follow $rt = 0x088B; // 2 $grbitFrt = 0x0000; // 2 $reserved = 0x0000000000000000; // 8 $wScalvePLV = $this->phpSheet->getSheetView()->getZoomScale(); // 2 // The options flags that comprise $grbit if ($this->phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { $fPageLayoutView = 1; } else { $fPageLayoutView = 0; } $fRulerVisible = 0; $fWhitespaceHidden = 0; $grbit = $fPageLayoutView; // 2 $grbit |= $fRulerVisible << 1; $grbit |= $fWhitespaceHidden << 3; $header = pack("vv", $record, $length); $data = pack("vvVVvv", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit); $this->append($header . $data); } /** * Write CFRule Record * @param PHPExcel_Style_Conditional $conditional */ private function writeCFRule(PHPExcel_Style_Conditional $conditional) { $record = 0x01B1; // Record identifier // $type : Type of the CF // $operatorType : Comparison operator if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { $type = 0x02; $operatorType = 0x00; } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { $type = 0x01; switch ($conditional->getOperatorType()) { case PHPExcel_Style_Conditional::OPERATOR_NONE: $operatorType = 0x00; break; case PHPExcel_Style_Conditional::OPERATOR_EQUAL: $operatorType = 0x03; break; case PHPExcel_Style_Conditional::OPERATOR_GREATERTHAN: $operatorType = 0x05; break; case PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL: $operatorType = 0x07; break; case PHPExcel_Style_Conditional::OPERATOR_LESSTHAN: $operatorType = 0x06; break; case PHPExcel_Style_Conditional::OPERATOR_LESSTHANOREQUAL: $operatorType = 0x08; break; case PHPExcel_Style_Conditional::OPERATOR_NOTEQUAL: $operatorType = 0x04; break; case PHPExcel_Style_Conditional::OPERATOR_BETWEEN: $operatorType = 0x01; break; // not OPERATOR_NOTBETWEEN 0x02 } } // $szValue1 : size of the formula data for first value or formula // $szValue2 : size of the formula data for second value or formula $arrConditions = $conditional->getConditions(); $numConditions = sizeof($arrConditions); if ($numConditions == 1) { $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); $szValue2 = 0x0000; $operand1 = pack('Cv', 0x1E, $arrConditions[0]); $operand2 = null; } elseif ($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)) { $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); $operand1 = pack('Cv', 0x1E, $arrConditions[0]); $operand2 = pack('Cv', 0x1E, $arrConditions[1]); } else { $szValue1 = 0x0000; $szValue2 = 0x0000; $operand1 = null; $operand2 = null; } // $flags : Option flags // Alignment $bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0); $bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0); $bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0); $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0); $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0); $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0); if ($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0) { $bFormatAlign = 1; } else { $bFormatAlign = 0; } // Protection $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0); $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0); if ($bProtLocked == 0 || $bProtHidden == 0) { $bFormatProt = 1; } else { $bFormatProt = 0; } // Border $bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK && $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); $bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK && $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); $bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); if ($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0) { $bFormatBorder = 1; } else { $bFormatBorder = 0; } // Pattern $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1); $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1); $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1); if ($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0) { $bFormatFill = 1; } else { $bFormatFill = 0; } // Font if ($conditional->getStyle()->getFont()->getName() != null || $conditional->getStyle()->getFont()->getSize() != null || $conditional->getStyle()->getFont()->getBold() != null || $conditional->getStyle()->getFont()->getItalic() != null || $conditional->getStyle()->getFont()->getSuperScript() != null || $conditional->getStyle()->getFont()->getSubScript() != null || $conditional->getStyle()->getFont()->getUnderline() != null || $conditional->getStyle()->getFont()->getStrikethrough() != null || $conditional->getStyle()->getFont()->getColor()->getARGB() != null) { $bFormatFont = 1; } else { $bFormatFont = 0; } // Alignment $flags = 0; $flags |= (1 == $bAlignHz ? 0x00000001 : 0); $flags |= (1 == $bAlignVt ? 0x00000002 : 0); $flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0); $flags |= (1 == $bTxRotation ? 0x00000008 : 0); // Justify last line flag $flags |= (1 == 1 ? 0x00000010 : 0); $flags |= (1 == $bIndent ? 0x00000020 : 0); $flags |= (1 == $bShrinkToFit ? 0x00000040 : 0); // Default $flags |= (1 == 1 ? 0x00000080 : 0); // Protection $flags |= (1 == $bProtLocked ? 0x00000100 : 0); $flags |= (1 == $bProtHidden ? 0x00000200 : 0); // Border $flags |= (1 == $bBorderLeft ? 0x00000400 : 0); $flags |= (1 == $bBorderRight ? 0x00000800 : 0); $flags |= (1 == $bBorderTop ? 0x00001000 : 0); $flags |= (1 == $bBorderBottom ? 0x00002000 : 0); $flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border $flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border // Pattern $flags |= (1 == $bFillStyle ? 0x00010000 : 0); $flags |= (1 == $bFillColor ? 0x00020000 : 0); $flags |= (1 == $bFillColorBg ? 0x00040000 : 0); $flags |= (1 == 1 ? 0x00380000 : 0); // Font $flags |= (1 == $bFormatFont ? 0x04000000 : 0); // Alignment: $flags |= (1 == $bFormatAlign ? 0x08000000 : 0); // Border $flags |= (1 == $bFormatBorder ? 0x10000000 : 0); // Pattern $flags |= (1 == $bFormatFill ? 0x20000000 : 0); // Protection $flags |= (1 == $bFormatProt ? 0x40000000 : 0); // Text direction $flags |= (1 == 0 ? 0x80000000 : 0); // Data Blocks if ($bFormatFont == 1) { // Font Name if ($conditional->getStyle()->getFont()->getName() == null) { $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); } else { $dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName()); } // Font Size if ($conditional->getStyle()->getFont()->getSize() == null) { $dataBlockFont .= pack('V', 20 * 11); } else { $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize()); } // Font Options $dataBlockFont .= pack('V', 0); // Font weight if ($conditional->getStyle()->getFont()->getBold() == true) { $dataBlockFont .= pack('v', 0x02BC); } else { $dataBlockFont .= pack('v', 0x0190); } // Escapement type if ($conditional->getStyle()->getFont()->getSubScript() == true) { $dataBlockFont .= pack('v', 0x02); $fontEscapement = 0; } elseif ($conditional->getStyle()->getFont()->getSuperScript() == true) { $dataBlockFont .= pack('v', 0x01); $fontEscapement = 0; } else { $dataBlockFont .= pack('v', 0x00); $fontEscapement = 1; } // Underline type switch ($conditional->getStyle()->getFont()->getUnderline()) { case PHPExcel_Style_Font::UNDERLINE_NONE: $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break; case PHPExcel_Style_Font::UNDERLINE_DOUBLE: $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break; case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING: $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break; case PHPExcel_Style_Font::UNDERLINE_SINGLE: $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break; case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING: $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break; default: $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break; } // Not used (3) $dataBlockFont .= pack('vC', 0x0000, 0x00); // Font color index switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) { case '000000': $colorIdx = 0x08; break; case 'FFFFFF': $colorIdx = 0x09; break; case 'FF0000': $colorIdx = 0x0A; break; case '00FF00': $colorIdx = 0x0B; break; case '0000FF': $colorIdx = 0x0C; break; case 'FFFF00': $colorIdx = 0x0D; break; case 'FF00FF': $colorIdx = 0x0E; break; case '00FFFF': $colorIdx = 0x0F; break; case '800000': $colorIdx = 0x10; break; case '008000': $colorIdx = 0x11; break; case '000080': $colorIdx = 0x12; break; case '808000': $colorIdx = 0x13; break; case '800080': $colorIdx = 0x14; break; case '008080': $colorIdx = 0x15; break; case 'C0C0C0': $colorIdx = 0x16; break; case '808080': $colorIdx = 0x17; break; case '9999FF': $colorIdx = 0x18; break; case '993366': $colorIdx = 0x19; break; case 'FFFFCC': $colorIdx = 0x1A; break; case 'CCFFFF': $colorIdx = 0x1B; break; case '660066': $colorIdx = 0x1C; break; case 'FF8080': $colorIdx = 0x1D; break; case '0066CC': $colorIdx = 0x1E; break; case 'CCCCFF': $colorIdx = 0x1F; break; case '000080': $colorIdx = 0x20; break; case 'FF00FF': $colorIdx = 0x21; break; case 'FFFF00': $colorIdx = 0x22; break; case '00FFFF': $colorIdx = 0x23; break; case '800080': $colorIdx = 0x24; break; case '800000': $colorIdx = 0x25; break; case '008080': $colorIdx = 0x26; break; case '0000FF': $colorIdx = 0x27; break; case '00CCFF': $colorIdx = 0x28; break; case 'CCFFFF': $colorIdx = 0x29; break; case 'CCFFCC': $colorIdx = 0x2A; break; case 'FFFF99': $colorIdx = 0x2B; break; case '99CCFF': $colorIdx = 0x2C; break; case 'FF99CC': $colorIdx = 0x2D; break; case 'CC99FF': $colorIdx = 0x2E; break; case 'FFCC99': $colorIdx = 0x2F; break; case '3366FF': $colorIdx = 0x30; break; case '33CCCC': $colorIdx = 0x31; break; case '99CC00': $colorIdx = 0x32; break; case 'FFCC00': $colorIdx = 0x33; break; case 'FF9900': $colorIdx = 0x34; break; case 'FF6600': $colorIdx = 0x35; break; case '666699': $colorIdx = 0x36; break; case '969696': $colorIdx = 0x37; break; case '003366': $colorIdx = 0x38; break; case '339966': $colorIdx = 0x39; break; case '003300': $colorIdx = 0x3A; break; case '333300': $colorIdx = 0x3B; break; case '993300': $colorIdx = 0x3C; break; case '993366': $colorIdx = 0x3D; break; case '333399': $colorIdx = 0x3E; break; case '333333': $colorIdx = 0x3F; break; default: $colorIdx = 0x00; break; } $dataBlockFont .= pack('V', $colorIdx); // Not used (4) $dataBlockFont .= pack('V', 0x00000000); // Options flags for modified font attributes $optionsFlags = 0; $optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0); $optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0); $optionsFlags |= (1 == 1 ? 0x00000008 : 0); $optionsFlags |= (1 == 1 ? 0x00000010 : 0); $optionsFlags |= (1 == 0 ? 0x00000020 : 0); $optionsFlags |= (1 == 1 ? 0x00000080 : 0); $dataBlockFont .= pack('V', $optionsFlags); // Escapement type $dataBlockFont .= pack('V', $fontEscapement); // Underline type $dataBlockFont .= pack('V', $fontUnderline); // Always $dataBlockFont .= pack('V', 0x00000000); // Always $dataBlockFont .= pack('V', 0x00000000); // Not used (8) $dataBlockFont .= pack('VV', 0x00000000, 0x00000000); // Always $dataBlockFont .= pack('v', 0x0001); } if ($bFormatAlign == 1) { $blockAlign = 0; // Alignment and text break switch ($conditional->getStyle()->getAlignment()->getHorizontal()) { case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: $blockAlign = 0; break; case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: $blockAlign = 1; break; case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: $blockAlign = 3; break; case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: $blockAlign = 2; break; case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: $blockAlign = 6; break; case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: $blockAlign = 5; break; } if ($conditional->getStyle()->getAlignment()->getWrapText() == true) { $blockAlign |= 1 << 3; } else { $blockAlign |= 0 << 3; } switch ($conditional->getStyle()->getAlignment()->getVertical()) { case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: $blockAlign = 2 << 4; break; case PHPExcel_Style_Alignment::VERTICAL_TOP: $blockAlign = 0 << 4; break; case PHPExcel_Style_Alignment::VERTICAL_CENTER: $blockAlign = 1 << 4; break; case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: $blockAlign = 3 << 4; break; } $blockAlign |= 0 << 7; // Text rotation angle $blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation(); // Indentation $blockIndent = $conditional->getStyle()->getAlignment()->getIndent(); if ($conditional->getStyle()->getAlignment()->getShrinkToFit() == true) { $blockIndent |= 1 << 4; } else { $blockIndent |= 0 << 4; } $blockIndent |= 0 << 6; // Relative indentation $blockIndentRelative = 255; $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000); } if ($bFormatBorder == 1) { $blockLineStyle = 0; switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()) { case PHPExcel_Style_Border::BORDER_NONE: $blockLineStyle |= 0x00; break; case PHPExcel_Style_Border::BORDER_THIN: $blockLineStyle |= 0x01; break; case PHPExcel_Style_Border::BORDER_MEDIUM: $blockLineStyle |= 0x02; break; case PHPExcel_Style_Border::BORDER_DASHED: $blockLineStyle |= 0x03; break; case PHPExcel_Style_Border::BORDER_DOTTED: $blockLineStyle |= 0x04; break; case PHPExcel_Style_Border::BORDER_THICK: $blockLineStyle |= 0x05; break; case PHPExcel_Style_Border::BORDER_DOUBLE: $blockLineStyle |= 0x06; break; case PHPExcel_Style_Border::BORDER_HAIR: $blockLineStyle |= 0x07; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: $blockLineStyle |= 0x08; break; case PHPExcel_Style_Border::BORDER_DASHDOT: $blockLineStyle |= 0x09; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: $blockLineStyle |= 0x0A; break; case PHPExcel_Style_Border::BORDER_DASHDOTDOT: $blockLineStyle |= 0x0B; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: $blockLineStyle |= 0x0C; break; case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: $blockLineStyle |= 0x0D; break; } switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()) { case PHPExcel_Style_Border::BORDER_NONE: $blockLineStyle |= 0x00 << 4; break; case PHPExcel_Style_Border::BORDER_THIN: $blockLineStyle |= 0x01 << 4; break; case PHPExcel_Style_Border::BORDER_MEDIUM: $blockLineStyle |= 0x02 << 4; break; case PHPExcel_Style_Border::BORDER_DASHED: $blockLineStyle |= 0x03 << 4; break; case PHPExcel_Style_Border::BORDER_DOTTED: $blockLineStyle |= 0x04 << 4; break; case PHPExcel_Style_Border::BORDER_THICK: $blockLineStyle |= 0x05 << 4; break; case PHPExcel_Style_Border::BORDER_DOUBLE: $blockLineStyle |= 0x06 << 4; break; case PHPExcel_Style_Border::BORDER_HAIR: $blockLineStyle |= 0x07 << 4; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: $blockLineStyle |= 0x08 << 4; break; case PHPExcel_Style_Border::BORDER_DASHDOT: $blockLineStyle |= 0x09 << 4; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: $blockLineStyle |= 0x0A << 4; break; case PHPExcel_Style_Border::BORDER_DASHDOTDOT: $blockLineStyle |= 0x0B << 4; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: $blockLineStyle |= 0x0C << 4; break; case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: $blockLineStyle |= 0x0D << 4; break; } switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()) { case PHPExcel_Style_Border::BORDER_NONE: $blockLineStyle |= 0x00 << 8; break; case PHPExcel_Style_Border::BORDER_THIN: $blockLineStyle |= 0x01 << 8; break; case PHPExcel_Style_Border::BORDER_MEDIUM: $blockLineStyle |= 0x02 << 8; break; case PHPExcel_Style_Border::BORDER_DASHED: $blockLineStyle |= 0x03 << 8; break; case PHPExcel_Style_Border::BORDER_DOTTED: $blockLineStyle |= 0x04 << 8; break; case PHPExcel_Style_Border::BORDER_THICK: $blockLineStyle |= 0x05 << 8; break; case PHPExcel_Style_Border::BORDER_DOUBLE: $blockLineStyle |= 0x06 << 8; break; case PHPExcel_Style_Border::BORDER_HAIR: $blockLineStyle |= 0x07 << 8; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: $blockLineStyle |= 0x08 << 8; break; case PHPExcel_Style_Border::BORDER_DASHDOT: $blockLineStyle |= 0x09 << 8; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: $blockLineStyle |= 0x0A << 8; break; case PHPExcel_Style_Border::BORDER_DASHDOTDOT: $blockLineStyle |= 0x0B << 8; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: $blockLineStyle |= 0x0C << 8; break; case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: $blockLineStyle |= 0x0D << 8; break; } switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()) { case PHPExcel_Style_Border::BORDER_NONE: $blockLineStyle |= 0x00 << 12; break; case PHPExcel_Style_Border::BORDER_THIN: $blockLineStyle |= 0x01 << 12; break; case PHPExcel_Style_Border::BORDER_MEDIUM: $blockLineStyle |= 0x02 << 12; break; case PHPExcel_Style_Border::BORDER_DASHED: $blockLineStyle |= 0x03 << 12; break; case PHPExcel_Style_Border::BORDER_DOTTED: $blockLineStyle |= 0x04 << 12; break; case PHPExcel_Style_Border::BORDER_THICK: $blockLineStyle |= 0x05 << 12; break; case PHPExcel_Style_Border::BORDER_DOUBLE: $blockLineStyle |= 0x06 << 12; break; case PHPExcel_Style_Border::BORDER_HAIR: $blockLineStyle |= 0x07 << 12; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: $blockLineStyle |= 0x08 << 12; break; case PHPExcel_Style_Border::BORDER_DASHDOT: $blockLineStyle |= 0x09 << 12; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: $blockLineStyle |= 0x0A << 12; break; case PHPExcel_Style_Border::BORDER_DASHDOTDOT: $blockLineStyle |= 0x0B << 12; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: $blockLineStyle |= 0x0C << 12; break; case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: $blockLineStyle |= 0x0D << 12; break; } //@todo writeCFRule() => $blockLineStyle => Index Color for left line //@todo writeCFRule() => $blockLineStyle => Index Color for right line //@todo writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off //@todo writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off $blockColor = 0; //@todo writeCFRule() => $blockColor => Index Color for top line //@todo writeCFRule() => $blockColor => Index Color for bottom line //@todo writeCFRule() => $blockColor => Index Color for diagonal line switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()) { case PHPExcel_Style_Border::BORDER_NONE: $blockColor |= 0x00 << 21; break; case PHPExcel_Style_Border::BORDER_THIN: $blockColor |= 0x01 << 21; break; case PHPExcel_Style_Border::BORDER_MEDIUM: $blockColor |= 0x02 << 21; break; case PHPExcel_Style_Border::BORDER_DASHED: $blockColor |= 0x03 << 21; break; case PHPExcel_Style_Border::BORDER_DOTTED: $blockColor |= 0x04 << 21; break; case PHPExcel_Style_Border::BORDER_THICK: $blockColor |= 0x05 << 21; break; case PHPExcel_Style_Border::BORDER_DOUBLE: $blockColor |= 0x06 << 21; break; case PHPExcel_Style_Border::BORDER_HAIR: $blockColor |= 0x07 << 21; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: $blockColor |= 0x08 << 21; break; case PHPExcel_Style_Border::BORDER_DASHDOT: $blockColor |= 0x09 << 21; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: $blockColor |= 0x0A << 21; break; case PHPExcel_Style_Border::BORDER_DASHDOTDOT: $blockColor |= 0x0B << 21; break; case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: $blockColor |= 0x0C << 21; break; case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: $blockColor |= 0x0D << 21; break; } $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor); } if ($bFormatFill == 1) { // Fill Patern Style $blockFillPatternStyle = 0; switch ($conditional->getStyle()->getFill()->getFillType()) { case PHPExcel_Style_Fill::FILL_NONE: $blockFillPatternStyle = 0x00; break; case PHPExcel_Style_Fill::FILL_SOLID: $blockFillPatternStyle = 0x01; break; case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY: $blockFillPatternStyle = 0x02; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY: $blockFillPatternStyle = 0x03; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY: $blockFillPatternStyle = 0x04; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL: $blockFillPatternStyle = 0x05; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL: $blockFillPatternStyle = 0x06; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN: $blockFillPatternStyle = 0x07; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP: $blockFillPatternStyle = 0x08; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID: $blockFillPatternStyle = 0x09; break; case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS: $blockFillPatternStyle = 0x0A; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL: $blockFillPatternStyle = 0x0B; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL: $blockFillPatternStyle = 0x0C; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN: $blockFillPatternStyle = 0x0D; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP: $blockFillPatternStyle = 0x0E; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID: $blockFillPatternStyle = 0x0F; break; case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS: $blockFillPatternStyle = 0x10; break; case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125: $blockFillPatternStyle = 0x11; break; case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625: $blockFillPatternStyle = 0x12; break; case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR: $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 case PHPExcel_Style_Fill::FILL_GRADIENT_PATH: $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 default: $blockFillPatternStyle = 0x00; break; } // Color switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) { case '000000': $colorIdxBg = 0x08; break; case 'FFFFFF': $colorIdxBg = 0x09; break; case 'FF0000': $colorIdxBg = 0x0A; break; case '00FF00': $colorIdxBg = 0x0B; break; case '0000FF': $colorIdxBg = 0x0C; break; case 'FFFF00': $colorIdxBg = 0x0D; break; case 'FF00FF': $colorIdxBg = 0x0E; break; case '00FFFF': $colorIdxBg = 0x0F; break; case '800000': $colorIdxBg = 0x10; break; case '008000': $colorIdxBg = 0x11; break; case '000080': $colorIdxBg = 0x12; break; case '808000': $colorIdxBg = 0x13; break; case '800080': $colorIdxBg = 0x14; break; case '008080': $colorIdxBg = 0x15; break; case 'C0C0C0': $colorIdxBg = 0x16; break; case '808080': $colorIdxBg = 0x17; break; case '9999FF': $colorIdxBg = 0x18; break; case '993366': $colorIdxBg = 0x19; break; case 'FFFFCC': $colorIdxBg = 0x1A; break; case 'CCFFFF': $colorIdxBg = 0x1B; break; case '660066': $colorIdxBg = 0x1C; break; case 'FF8080': $colorIdxBg = 0x1D; break; case '0066CC': $colorIdxBg = 0x1E; break; case 'CCCCFF': $colorIdxBg = 0x1F; break; case '000080': $colorIdxBg = 0x20; break; case 'FF00FF': $colorIdxBg = 0x21; break; case 'FFFF00': $colorIdxBg = 0x22; break; case '00FFFF': $colorIdxBg = 0x23; break; case '800080': $colorIdxBg = 0x24; break; case '800000': $colorIdxBg = 0x25; break; case '008080': $colorIdxBg = 0x26; break; case '0000FF': $colorIdxBg = 0x27; break; case '00CCFF': $colorIdxBg = 0x28; break; case 'CCFFFF': $colorIdxBg = 0x29; break; case 'CCFFCC': $colorIdxBg = 0x2A; break; case 'FFFF99': $colorIdxBg = 0x2B; break; case '99CCFF': $colorIdxBg = 0x2C; break; case 'FF99CC': $colorIdxBg = 0x2D; break; case 'CC99FF': $colorIdxBg = 0x2E; break; case 'FFCC99': $colorIdxBg = 0x2F; break; case '3366FF': $colorIdxBg = 0x30; break; case '33CCCC': $colorIdxBg = 0x31; break; case '99CC00': $colorIdxBg = 0x32; break; case 'FFCC00': $colorIdxBg = 0x33; break; case 'FF9900': $colorIdxBg = 0x34; break; case 'FF6600': $colorIdxBg = 0x35; break; case '666699': $colorIdxBg = 0x36; break; case '969696': $colorIdxBg = 0x37; break; case '003366': $colorIdxBg = 0x38; break; case '339966': $colorIdxBg = 0x39; break; case '003300': $colorIdxBg = 0x3A; break; case '333300': $colorIdxBg = 0x3B; break; case '993300': $colorIdxBg = 0x3C; break; case '993366': $colorIdxBg = 0x3D; break; case '333399': $colorIdxBg = 0x3E; break; case '333333': $colorIdxBg = 0x3F; break; default: $colorIdxBg = 0x41; break; } // Fg Color switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) { case '000000': $colorIdxFg = 0x08; break; case 'FFFFFF': $colorIdxFg = 0x09; break; case 'FF0000': $colorIdxFg = 0x0A; break; case '00FF00': $colorIdxFg = 0x0B; break; case '0000FF': $colorIdxFg = 0x0C; break; case 'FFFF00': $colorIdxFg = 0x0D; break; case 'FF00FF': $colorIdxFg = 0x0E; break; case '00FFFF': $colorIdxFg = 0x0F; break; case '800000': $colorIdxFg = 0x10; break; case '008000': $colorIdxFg = 0x11; break; case '000080': $colorIdxFg = 0x12; break; case '808000': $colorIdxFg = 0x13; break; case '800080': $colorIdxFg = 0x14; break; case '008080': $colorIdxFg = 0x15; break; case 'C0C0C0': $colorIdxFg = 0x16; break; case '808080': $colorIdxFg = 0x17; break; case '9999FF': $colorIdxFg = 0x18; break; case '993366': $colorIdxFg = 0x19; break; case 'FFFFCC': $colorIdxFg = 0x1A; break; case 'CCFFFF': $colorIdxFg = 0x1B; break; case '660066': $colorIdxFg = 0x1C; break; case 'FF8080': $colorIdxFg = 0x1D; break; case '0066CC': $colorIdxFg = 0x1E; break; case 'CCCCFF': $colorIdxFg = 0x1F; break; case '000080': $colorIdxFg = 0x20; break; case 'FF00FF': $colorIdxFg = 0x21; break; case 'FFFF00': $colorIdxFg = 0x22; break; case '00FFFF': $colorIdxFg = 0x23; break; case '800080': $colorIdxFg = 0x24; break; case '800000': $colorIdxFg = 0x25; break; case '008080': $colorIdxFg = 0x26; break; case '0000FF': $colorIdxFg = 0x27; break; case '00CCFF': $colorIdxFg = 0x28; break; case 'CCFFFF': $colorIdxFg = 0x29; break; case 'CCFFCC': $colorIdxFg = 0x2A; break; case 'FFFF99': $colorIdxFg = 0x2B; break; case '99CCFF': $colorIdxFg = 0x2C; break; case 'FF99CC': $colorIdxFg = 0x2D; break; case 'CC99FF': $colorIdxFg = 0x2E; break; case 'FFCC99': $colorIdxFg = 0x2F; break; case '3366FF': $colorIdxFg = 0x30; break; case '33CCCC': $colorIdxFg = 0x31; break; case '99CC00': $colorIdxFg = 0x32; break; case 'FFCC00': $colorIdxFg = 0x33; break; case 'FF9900': $colorIdxFg = 0x34; break; case 'FF6600': $colorIdxFg = 0x35; break; case '666699': $colorIdxFg = 0x36; break; case '969696': $colorIdxFg = 0x37; break; case '003366': $colorIdxFg = 0x38; break; case '339966': $colorIdxFg = 0x39; break; case '003300': $colorIdxFg = 0x3A; break; case '333300': $colorIdxFg = 0x3B; break; case '993300': $colorIdxFg = 0x3C; break; case '993366': $colorIdxFg = 0x3D; break; case '333399': $colorIdxFg = 0x3E; break; case '333333': $colorIdxFg = 0x3F; break; default: $colorIdxFg = 0x40; break; } $dataBlockFill = pack('v', $blockFillPatternStyle); $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7)); } if ($bFormatProt == 1) { $dataBlockProtection = 0; if ($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED) { $dataBlockProtection = 1; } if ($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED) { $dataBlockProtection = 1 << 1; } } $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000); if ($bFormatFont == 1) { // Block Formatting : OK $data .= $dataBlockFont; } if ($bFormatAlign == 1) { $data .= $dataBlockAlign; } if ($bFormatBorder == 1) { $data .= $dataBlockBorder; } if ($bFormatFill == 1) { // Block Formatting : OK $data .= $dataBlockFill; } if ($bFormatProt == 1) { $data .= $dataBlockProtection; } if (!is_null($operand1)) { $data .= $operand1; } if (!is_null($operand2)) { $data .= $operand2; } $header = pack('vv', $record, strlen($data)); $this->append($header . $data); } /** * Write CFHeader record */ private function writeCFHeader() { $record = 0x01B0; // Record identifier $length = 0x0016; // Bytes to follow $numColumnMin = null; $numColumnMax = null; $numRowMin = null; $numRowMax = null; $arrConditional = array(); foreach ($this->phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { if (!in_array($conditional->getHashCode(), $arrConditional)) { $arrConditional[] = $conditional->getHashCode(); } // Cells $arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate); if (!is_numeric($arrCoord[0])) { $arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]); } if (is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])) { $numColumnMin = $arrCoord[0]; } if (is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])) { $numColumnMax = $arrCoord[0]; } if (is_null($numRowMin) || ($numRowMin > $arrCoord[1])) { $numRowMin = $arrCoord[1]; } if (is_null($numRowMax) || ($numRowMax < $arrCoord[1])) { $numRowMax = $arrCoord[1]; } } } } $needRedraw = 1; $cellRange = pack('vvvv', $numRowMin-1, $numRowMax-1, $numColumnMin-1, $numColumnMax-1); $header = pack('vv', $record, $length); $data = pack('vv', count($arrConditional), $needRedraw); $data .= $cellRange; $data .= pack('v', 0x0001); $data .= $cellRange; $this->append($header . $data); } } PK!hhExcel5/Font.phpnu[colorIndex = 0x7FFF; $this->font = $font; } /** * Set the color index * * @param int $colorIndex */ public function setColorIndex($colorIndex) { $this->colorIndex = $colorIndex; } /** * Get font record data * * @return string */ public function writeFont() { $font_outline = 0; $font_shadow = 0; $icv = $this->colorIndex; // Index to color palette if ($this->font->getSuperScript()) { $sss = 1; } elseif ($this->font->getSubScript()) { $sss = 2; } else { $sss = 0; } $bFamily = 0; // Font family $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->font->getName()); // Character set $record = 0x31; // Record identifier $reserved = 0x00; // Reserved $grbit = 0x00; // Font attributes if ($this->font->getItalic()) { $grbit |= 0x02; } if ($this->font->getStrikethrough()) { $grbit |= 0x08; } if ($font_outline) { $grbit |= 0x10; } if ($font_shadow) { $grbit |= 0x20; } $data = pack( "vvvvvCCCC", // Fontsize (in twips) $this->font->getSize() * 20, $grbit, // Colour $icv, // Font weight self::mapBold($this->font->getBold()), // Superscript/Subscript $sss, self::mapUnderline($this->font->getUnderline()), $bFamily, $bCharSet, $reserved ); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->font->getName()); $length = strlen($data); $header = pack("vv", $record, $length); return($header . $data); } /** * Map to BIFF5-BIFF8 codes for bold * * @param boolean $bold * @return int */ private static function mapBold($bold) { if ($bold) { return 0x2BC; // 700 = Bold font weight } return 0x190; // 400 = Normal font weight } /** * Map of BIFF2-BIFF8 codes for underline styles * @static array of int * */ private static $mapUnderline = array( PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, ); /** * Map underline * * @param string * @return int */ private static function mapUnderline($underline) { if (isset(self::$mapUnderline[$underline])) { return self::$mapUnderline[$underline]; } return 0x00; } } PK!̿{$I$I Excel5/Xf.phpnu[ // * // * The majority of this is _NOT_ my code. I simply ported it from the // * PERL Spreadsheet::WriteExcel module. // * // * The author of the Spreadsheet::WriteExcel module is John McNamara // * // * // * I _DO_ maintain this code, and John McNamara has nothing to do with the // * porting of this code to PHP. Any questions directly related to this // * class library should be directed to me. // * // * License Information: // * // * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets // * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com // * // * This library is free software; you can redistribute it and/or // * modify it under the terms of the GNU Lesser General Public // * License as published by the Free Software Foundation; either // * version 2.1 of the License, or (at your option) any later version. // * // * This library is distributed in the hope that it will be useful, // * but WITHOUT ANY WARRANTY; without even the implied warranty of // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // * Lesser General Public License for more details. // * // * You should have received a copy of the GNU Lesser General Public // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ class PHPExcel_Writer_Excel5_Xf { /** * Style XF or a cell XF ? * * @var boolean */ private $isStyleXf; /** * Index to the FONT record. Index 4 does not exist * @var integer */ private $fontIndex; /** * An index (2 bytes) to a FORMAT record (number format). * @var integer */ private $numberFormatIndex; /** * 1 bit, apparently not used. * @var integer */ private $textJustLast; /** * The cell's foreground color. * @var integer */ private $foregroundColor; /** * The cell's background color. * @var integer */ private $backgroundColor; /** * Color of the bottom border of the cell. * @var integer */ private $bottomBorderColor; /** * Color of the top border of the cell. * @var integer */ private $topBorderColor; /** * Color of the left border of the cell. * @var integer */ private $leftBorderColor; /** * Color of the right border of the cell. * @var integer */ private $rightBorderColor; /** * Constructor * * @access public * @param PHPExcel_Style The XF format */ public function __construct(PHPExcel_Style $style = null) { $this->isStyleXf = false; $this->fontIndex = 0; $this->numberFormatIndex = 0; $this->textJustLast = 0; $this->foregroundColor = 0x40; $this->backgroundColor = 0x41; $this->_diag = 0; $this->bottomBorderColor = 0x40; $this->topBorderColor = 0x40; $this->leftBorderColor = 0x40; $this->rightBorderColor = 0x40; $this->_diag_color = 0x40; $this->_style = $style; } /** * Generate an Excel BIFF XF record (style or cell). * * @return string The XF record */ public function writeXf() { // Set the type of the XF record and some of the attributes. if ($this->isStyleXf) { $style = 0xFFF5; } else { $style = self::mapLocked($this->_style->getProtection()->getLocked()); $style |= self::mapHidden($this->_style->getProtection()->getHidden()) << 1; } // Flags to indicate if attributes have been set. $atr_num = ($this->numberFormatIndex != 0)?1:0; $atr_fnt = ($this->fontIndex != 0)?1:0; $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; $atr_bdr = (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; $atr_pat = (($this->foregroundColor != 0x40) || ($this->backgroundColor != 0x41) || self::mapFillType($this->_style->getFill()->getFillType()))?1:0; $atr_prot = self::mapLocked($this->_style->getProtection()->getLocked()) | self::mapHidden($this->_style->getProtection()->getHidden()); // Zero the default border colour if the border has not been set. if (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { $this->bottomBorderColor = 0; } if (self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { $this->topBorderColor = 0; } if (self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { $this->rightBorderColor = 0; } if (self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { $this->leftBorderColor = 0; } if (self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { $this->_diag_color = 0; } $record = 0x00E0; // Record identifier $length = 0x0014; // Number of bytes to follow $ifnt = $this->fontIndex; // Index to FONT record $ifmt = $this->numberFormatIndex; // Index to FORMAT record $align = $this->mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; $align |= self::mapVAlign($this->_style->getAlignment()->getVertical()) << 4; $align |= $this->textJustLast << 7; $used_attrib = $atr_num << 2; $used_attrib |= $atr_fnt << 3; $used_attrib |= $atr_alc << 4; $used_attrib |= $atr_bdr << 5; $used_attrib |= $atr_pat << 6; $used_attrib |= $atr_prot << 7; $icv = $this->foregroundColor; // fg and bg pattern colors $icv |= $this->backgroundColor << 7; $border1 = self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color $border1 |= self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; $border1 |= self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; $border1 |= self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; $border1 |= $this->leftBorderColor << 16; $border1 |= $this->rightBorderColor << 23; $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; $border1 |= $diag_tl_to_rb << 30; $border1 |= $diag_tr_to_lb << 31; $border2 = $this->topBorderColor; // Border color $border2 |= $this->bottomBorderColor << 7; $border2 |= $this->_diag_color << 14; $border2 |= self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; $border2 |= self::mapFillType($this->_style->getFill()->getFillType()) << 26; $header = pack("vv", $record, $length); //BIFF8 options: identation, shrinkToFit and text direction $biff8_options = $this->_style->getAlignment()->getIndent(); $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; $data = pack("vvvC", $ifnt, $ifmt, $style, $align); $data .= pack("CCC", self::mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib); $data .= pack("VVv", $border1, $border2, $icv); return($header . $data); } /** * Is this a style XF ? * * @param boolean $value */ public function setIsStyleXf($value) { $this->isStyleXf = $value; } /** * Sets the cell's bottom border color * * @access public * @param int $colorIndex Color index */ public function setBottomColor($colorIndex) { $this->bottomBorderColor = $colorIndex; } /** * Sets the cell's top border color * * @access public * @param int $colorIndex Color index */ public function setTopColor($colorIndex) { $this->topBorderColor = $colorIndex; } /** * Sets the cell's left border color * * @access public * @param int $colorIndex Color index */ public function setLeftColor($colorIndex) { $this->leftBorderColor = $colorIndex; } /** * Sets the cell's right border color * * @access public * @param int $colorIndex Color index */ public function setRightColor($colorIndex) { $this->rightBorderColor = $colorIndex; } /** * Sets the cell's diagonal border color * * @access public * @param int $colorIndex Color index */ public function setDiagColor($colorIndex) { $this->_diag_color = $colorIndex; } /** * Sets the cell's foreground color * * @access public * @param int $colorIndex Color index */ public function setFgColor($colorIndex) { $this->foregroundColor = $colorIndex; } /** * Sets the cell's background color * * @access public * @param int $colorIndex Color index */ public function setBgColor($colorIndex) { $this->backgroundColor = $colorIndex; } /** * Sets the index to the number format record * It can be date, time, currency, etc... * * @access public * @param integer $numberFormatIndex Index to format record */ public function setNumberFormatIndex($numberFormatIndex) { $this->numberFormatIndex = $numberFormatIndex; } /** * Set the font index. * * @param int $value Font index, note that value 4 does not exist */ public function setFontIndex($value) { $this->fontIndex = $value; } /** * Map of BIFF2-BIFF8 codes for border styles * @static array of int * */ private static $mapBorderStyles = array( PHPExcel_Style_Border::BORDER_NONE => 0x00, PHPExcel_Style_Border::BORDER_THIN => 0x01, PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, PHPExcel_Style_Border::BORDER_DASHED => 0x03, PHPExcel_Style_Border::BORDER_DOTTED => 0x04, PHPExcel_Style_Border::BORDER_THICK => 0x05, PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, PHPExcel_Style_Border::BORDER_HAIR => 0x07, PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, ); /** * Map border style * * @param string $borderStyle * @return int */ private static function mapBorderStyle($borderStyle) { if (isset(self::$mapBorderStyles[$borderStyle])) { return self::$mapBorderStyles[$borderStyle]; } return 0x00; } /** * Map of BIFF2-BIFF8 codes for fill types * @static array of int * */ private static $mapFillTypes = array( PHPExcel_Style_Fill::FILL_NONE => 0x00, PHPExcel_Style_Fill::FILL_SOLID => 0x01, PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 ); /** * Map fill type * * @param string $fillType * @return int */ private static function mapFillType($fillType) { if (isset(self::$mapFillTypes[$fillType])) { return self::$mapFillTypes[$fillType]; } return 0x00; } /** * Map of BIFF2-BIFF8 codes for horizontal alignment * @static array of int * */ private static $mapHAlignments = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, ); /** * Map to BIFF2-BIFF8 codes for horizontal alignment * * @param string $hAlign * @return int */ private function mapHAlign($hAlign) { if (isset(self::$mapHAlignments[$hAlign])) { return self::$mapHAlignments[$hAlign]; } return 0; } /** * Map of BIFF2-BIFF8 codes for vertical alignment * @static array of int * */ private static $mapVAlignments = array( PHPExcel_Style_Alignment::VERTICAL_TOP => 0, PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, ); /** * Map to BIFF2-BIFF8 codes for vertical alignment * * @param string $vAlign * @return int */ private static function mapVAlign($vAlign) { if (isset(self::$mapVAlignments[$vAlign])) { return self::$mapVAlignments[$vAlign]; } return 2; } /** * Map to BIFF8 codes for text rotation angle * * @param int $textRotation * @return int */ private static function mapTextRotation($textRotation) { if ($textRotation >= 0) { return $textRotation; } elseif ($textRotation == -165) { return 255; } elseif ($textRotation < 0) { return 90 - $textRotation; } } /** * Map locked * * @param string * @return int */ private static function mapLocked($locked) { switch ($locked) { case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; default: return 1; } } /** * Map hidden * * @param string * @return int */ private static function mapHidden($hidden) { switch ($hidden) { case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; default: return 0; } } } PK!ckExcel5/Workbook.phpnu[ // * // * The majority of this is _NOT_ my code. I simply ported it from the // * PERL Spreadsheet::WriteExcel module. // * // * The author of the Spreadsheet::WriteExcel module is John McNamara // * // * // * I _DO_ maintain this code, and John McNamara has nothing to do with the // * porting of this code to PHP. Any questions directly related to this // * class library should be directed to me. // * // * License Information: // * // * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets // * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com // * // * This library is free software; you can redistribute it and/or // * modify it under the terms of the GNU Lesser General Public // * License as published by the Free Software Foundation; either // * version 2.1 of the License, or (at your option) any later version. // * // * This library is distributed in the hope that it will be useful, // * but WITHOUT ANY WARRANTY; without even the implied warranty of // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // * Lesser General Public License for more details. // * // * You should have received a copy of the GNU Lesser General Public // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter { /** * Formula parser * * @var PHPExcel_Writer_Excel5_Parser */ private $parser; /** * The BIFF file size for the workbook. * @var integer * @see calcSheetOffsets() */ private $biffSize; /** * XF Writers * @var PHPExcel_Writer_Excel5_Xf[] */ private $xfWriters = array(); /** * Array containing the colour palette * @var array */ private $palette; /** * The codepage indicates the text encoding used for strings * @var integer */ private $codepage; /** * The country code used for localization * @var integer */ private $countryCode; /** * Workbook * @var PHPExcel */ private $phpExcel; /** * Fonts writers * * @var PHPExcel_Writer_Excel5_Font[] */ private $fontWriters = array(); /** * Added fonts. Maps from font's hash => index in workbook * * @var array */ private $addedFonts = array(); /** * Shared number formats * * @var array */ private $numberFormats = array(); /** * Added number formats. Maps from numberFormat's hash => index in workbook * * @var array */ private $addedNumberFormats = array(); /** * Sizes of the binary worksheet streams * * @var array */ private $worksheetSizes = array(); /** * Offsets of the binary worksheet streams relative to the start of the global workbook stream * * @var array */ private $worksheetOffsets = array(); /** * Total number of shared strings in workbook * * @var int */ private $stringTotal; /** * Number of unique shared strings in workbook * * @var int */ private $stringUnique; /** * Array of unique shared strings in workbook * * @var array */ private $stringTable; /** * Color cache */ private $colors; /** * Escher object corresponding to MSODRAWINGGROUP * * @var PHPExcel_Shared_Escher */ private $escher; /** * Class constructor * * @param PHPExcel $phpExcel The Workbook * @param int &$str_total Total number of strings * @param int &$str_unique Total number of unique strings * @param array &$str_table String Table * @param array &$colors Colour Table * @param mixed $parser The formula parser created for the Workbook */ public function __construct(PHPExcel $phpExcel = null, &$str_total, &$str_unique, &$str_table, &$colors, $parser) { // It needs to call its parent's constructor explicitly parent::__construct(); $this->parser = $parser; $this->biffSize = 0; $this->palette = array(); $this->countryCode = -1; $this->stringTotal = &$str_total; $this->stringUnique = &$str_unique; $this->stringTable = &$str_table; $this->colors = &$colors; $this->setPaletteXl97(); $this->phpExcel = $phpExcel; // set BIFFwriter limit for CONTINUE records // $this->_limit = 8224; $this->codepage = 0x04B0; // Add empty sheets and Build color cache $countSheets = $phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { $phpSheet = $phpExcel->getSheet($i); $this->parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser $supbook_index = 0x00; $ref = pack('vvv', $supbook_index, $i, $i); $this->parser->references[] = $ref; // Register reference with parser // Sheet tab colors? if ($phpSheet->isTabColorSet()) { $this->addColor($phpSheet->getTabColor()->getRGB()); } } } /** * Add a new XF writer * * @param PHPExcel_Style * @param boolean Is it a style XF? * @return int Index to XF record */ public function addXfWriter($style, $isStyleXf = false) { $xfWriter = new PHPExcel_Writer_Excel5_Xf($style); $xfWriter->setIsStyleXf($isStyleXf); // Add the font if not already added $fontIndex = $this->addFont($style->getFont()); // Assign the font index to the xf record $xfWriter->setFontIndex($fontIndex); // Background colors, best to treat these after the font so black will come after white in custom palette $xfWriter->setFgColor($this->addColor($style->getFill()->getStartColor()->getRGB())); $xfWriter->setBgColor($this->addColor($style->getFill()->getEndColor()->getRGB())); $xfWriter->setBottomColor($this->addColor($style->getBorders()->getBottom()->getColor()->getRGB())); $xfWriter->setTopColor($this->addColor($style->getBorders()->getTop()->getColor()->getRGB())); $xfWriter->setRightColor($this->addColor($style->getBorders()->getRight()->getColor()->getRGB())); $xfWriter->setLeftColor($this->addColor($style->getBorders()->getLeft()->getColor()->getRGB())); $xfWriter->setDiagColor($this->addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); // Add the number format if it is not a built-in one and not already added if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { $numberFormatHashCode = $style->getNumberFormat()->getHashCode(); if (isset($this->addedNumberFormats[$numberFormatHashCode])) { $numberFormatIndex = $this->addedNumberFormats[$numberFormatHashCode]; } else { $numberFormatIndex = 164 + count($this->numberFormats); $this->numberFormats[$numberFormatIndex] = $style->getNumberFormat(); $this->addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; } } else { $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode(); } // Assign the number format index to xf record $xfWriter->setNumberFormatIndex($numberFormatIndex); $this->xfWriters[] = $xfWriter; $xfIndex = count($this->xfWriters) - 1; return $xfIndex; } /** * Add a font to added fonts * * @param PHPExcel_Style_Font $font * @return int Index to FONT record */ public function addFont(PHPExcel_Style_Font $font) { $fontHashCode = $font->getHashCode(); if (isset($this->addedFonts[$fontHashCode])) { $fontIndex = $this->addedFonts[$fontHashCode]; } else { $countFonts = count($this->fontWriters); $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; $fontWriter = new PHPExcel_Writer_Excel5_Font($font); $fontWriter->setColorIndex($this->addColor($font->getColor()->getRGB())); $this->fontWriters[] = $fontWriter; $this->addedFonts[$fontHashCode] = $fontIndex; } return $fontIndex; } /** * Alter color palette adding a custom color * * @param string $rgb E.g. 'FF00AA' * @return int Color index */ private function addColor($rgb) { if (!isset($this->colors[$rgb])) { if (count($this->colors) < 57) { // then we add a custom color altering the palette $colorIndex = 8 + count($this->colors); $this->palette[$colorIndex] = array( hexdec(substr($rgb, 0, 2)), hexdec(substr($rgb, 2, 2)), hexdec(substr($rgb, 4)), 0 ); $this->colors[$rgb] = $colorIndex; } else { // no room for more custom colors, just map to black $colorIndex = 0; } } else { // fetch already added custom color $colorIndex = $this->colors[$rgb]; } return $colorIndex; } /** * Sets the colour palette to the Excel 97+ default. * * @access private */ private function setPaletteXl97() { $this->palette = array( 0x08 => array(0x00, 0x00, 0x00, 0x00), 0x09 => array(0xff, 0xff, 0xff, 0x00), 0x0A => array(0xff, 0x00, 0x00, 0x00), 0x0B => array(0x00, 0xff, 0x00, 0x00), 0x0C => array(0x00, 0x00, 0xff, 0x00), 0x0D => array(0xff, 0xff, 0x00, 0x00), 0x0E => array(0xff, 0x00, 0xff, 0x00), 0x0F => array(0x00, 0xff, 0xff, 0x00), 0x10 => array(0x80, 0x00, 0x00, 0x00), 0x11 => array(0x00, 0x80, 0x00, 0x00), 0x12 => array(0x00, 0x00, 0x80, 0x00), 0x13 => array(0x80, 0x80, 0x00, 0x00), 0x14 => array(0x80, 0x00, 0x80, 0x00), 0x15 => array(0x00, 0x80, 0x80, 0x00), 0x16 => array(0xc0, 0xc0, 0xc0, 0x00), 0x17 => array(0x80, 0x80, 0x80, 0x00), 0x18 => array(0x99, 0x99, 0xff, 0x00), 0x19 => array(0x99, 0x33, 0x66, 0x00), 0x1A => array(0xff, 0xff, 0xcc, 0x00), 0x1B => array(0xcc, 0xff, 0xff, 0x00), 0x1C => array(0x66, 0x00, 0x66, 0x00), 0x1D => array(0xff, 0x80, 0x80, 0x00), 0x1E => array(0x00, 0x66, 0xcc, 0x00), 0x1F => array(0xcc, 0xcc, 0xff, 0x00), 0x20 => array(0x00, 0x00, 0x80, 0x00), 0x21 => array(0xff, 0x00, 0xff, 0x00), 0x22 => array(0xff, 0xff, 0x00, 0x00), 0x23 => array(0x00, 0xff, 0xff, 0x00), 0x24 => array(0x80, 0x00, 0x80, 0x00), 0x25 => array(0x80, 0x00, 0x00, 0x00), 0x26 => array(0x00, 0x80, 0x80, 0x00), 0x27 => array(0x00, 0x00, 0xff, 0x00), 0x28 => array(0x00, 0xcc, 0xff, 0x00), 0x29 => array(0xcc, 0xff, 0xff, 0x00), 0x2A => array(0xcc, 0xff, 0xcc, 0x00), 0x2B => array(0xff, 0xff, 0x99, 0x00), 0x2C => array(0x99, 0xcc, 0xff, 0x00), 0x2D => array(0xff, 0x99, 0xcc, 0x00), 0x2E => array(0xcc, 0x99, 0xff, 0x00), 0x2F => array(0xff, 0xcc, 0x99, 0x00), 0x30 => array(0x33, 0x66, 0xff, 0x00), 0x31 => array(0x33, 0xcc, 0xcc, 0x00), 0x32 => array(0x99, 0xcc, 0x00, 0x00), 0x33 => array(0xff, 0xcc, 0x00, 0x00), 0x34 => array(0xff, 0x99, 0x00, 0x00), 0x35 => array(0xff, 0x66, 0x00, 0x00), 0x36 => array(0x66, 0x66, 0x99, 0x00), 0x37 => array(0x96, 0x96, 0x96, 0x00), 0x38 => array(0x00, 0x33, 0x66, 0x00), 0x39 => array(0x33, 0x99, 0x66, 0x00), 0x3A => array(0x00, 0x33, 0x00, 0x00), 0x3B => array(0x33, 0x33, 0x00, 0x00), 0x3C => array(0x99, 0x33, 0x00, 0x00), 0x3D => array(0x99, 0x33, 0x66, 0x00), 0x3E => array(0x33, 0x33, 0x99, 0x00), 0x3F => array(0x33, 0x33, 0x33, 0x00), ); } /** * Assemble worksheets into a workbook and send the BIFF data to an OLE * storage. * * @param array $pWorksheetSizes The sizes in bytes of the binary worksheet streams * @return string Binary data for workbook stream */ public function writeWorkbook($pWorksheetSizes = null) { $this->worksheetSizes = $pWorksheetSizes; // Calculate the number of selected worksheet tabs and call the finalization // methods for each worksheet $total_worksheets = $this->phpExcel->getSheetCount(); // Add part 1 of the Workbook globals, what goes before the SHEET records $this->storeBof(0x0005); $this->writeCodepage(); $this->writeWindow1(); $this->writeDateMode(); $this->writeAllFonts(); $this->writeAllNumberFormats(); $this->writeAllXfs(); $this->writeAllStyles(); $this->writePalette(); // Prepare part 3 of the workbook global stream, what goes after the SHEET records $part3 = ''; if ($this->countryCode != -1) { $part3 .= $this->writeCountry(); } $part3 .= $this->writeRecalcId(); $part3 .= $this->writeSupbookInternal(); /* TODO: store external SUPBOOK records and XCT and CRN records in case of external references for BIFF8 */ $part3 .= $this->writeExternalsheetBiff8(); $part3 .= $this->writeAllDefinedNamesBiff8(); $part3 .= $this->writeMsoDrawingGroup(); $part3 .= $this->writeSharedStringsTable(); $part3 .= $this->writeEof(); // Add part 2 of the Workbook globals, the SHEET records $this->calcSheetOffsets(); for ($i = 0; $i < $total_worksheets; ++$i) { $this->writeBoundSheet($this->phpExcel->getSheet($i), $this->worksheetOffsets[$i]); } // Add part 3 of the Workbook globals $this->_data .= $part3; return $this->_data; } /** * Calculate offsets for Worksheet BOF records. * * @access private */ private function calcSheetOffsets() { $boundsheet_length = 10; // fixed length for a BOUNDSHEET record // size of Workbook globals part 1 + 3 $offset = $this->_datasize; // add size of Workbook globals part 2, the length of the SHEET records $total_worksheets = count($this->phpExcel->getAllSheets()); foreach ($this->phpExcel->getWorksheetIterator() as $sheet) { $offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle())); } // add the sizes of each of the Sheet substreams, respectively for ($i = 0; $i < $total_worksheets; ++$i) { $this->worksheetOffsets[$i] = $offset; $offset += $this->worksheetSizes[$i]; } $this->biffSize = $offset; } /** * Store the Excel FONT records. */ private function writeAllFonts() { foreach ($this->fontWriters as $fontWriter) { $this->append($fontWriter->writeFont()); } } /** * Store user defined numerical formats i.e. FORMAT records */ private function writeAllNumberFormats() { foreach ($this->numberFormats as $numberFormatIndex => $numberFormat) { $this->writeNumberFormat($numberFormat->getFormatCode(), $numberFormatIndex); } } /** * Write all XF records. */ private function writeAllXfs() { foreach ($this->xfWriters as $xfWriter) { $this->append($xfWriter->writeXf()); } } /** * Write all STYLE records. */ private function writeAllStyles() { $this->writeStyle(); } /** * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for * the NAME records. */ private function writeExternals() { $countSheets = $this->phpExcel->getSheetCount(); // Create EXTERNCOUNT with number of worksheets $this->writeExternalCount($countSheets); // Create EXTERNSHEET for each worksheet for ($i = 0; $i < $countSheets; ++$i) { $this->writeExternalSheet($this->phpExcel->getSheet($i)->getTitle()); } } /** * Write the NAME record to define the print area and the repeat rows and cols. */ private function writeNames() { // total number of sheets $total_worksheets = $this->phpExcel->getSheetCount(); // Create the print area NAME records for ($i = 0; $i < $total_worksheets; ++$i) { $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); // Write a Name record if the print area has been defined if ($sheetSetup->isPrintAreaSet()) { // Print area $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); $printArea = $printArea[0]; $printArea[0] = PHPExcel_Cell::coordinateFromString($printArea[0]); $printArea[1] = PHPExcel_Cell::coordinateFromString($printArea[1]); $print_rowmin = $printArea[0][1] - 1; $print_rowmax = $printArea[1][1] - 1; $print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1; $print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1; $this->writeNameShort( $i, // sheet index 0x06, // NAME type $print_rowmin, $print_rowmax, $print_colmin, $print_colmax ); } } // Create the print title NAME records for ($i = 0; $i < $total_worksheets; ++$i) { $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); // simultaneous repeatColumns repeatRows if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; $repeat = $sheetSetup->getRowsToRepeatAtTop(); $rowmin = $repeat[0] - 1; $rowmax = $repeat[1] - 1; $this->writeNameLong( $i, // sheet index 0x07, // NAME type $rowmin, $rowmax, $colmin, $colmax ); // (exclusive) either repeatColumns or repeatRows } elseif ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { // Columns to repeat if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; } else { $colmin = 0; $colmax = 255; } // Rows to repeat if ($sheetSetup->isRowsToRepeatAtTopSet()) { $repeat = $sheetSetup->getRowsToRepeatAtTop(); $rowmin = $repeat[0] - 1; $rowmax = $repeat[1] - 1; } else { $rowmin = 0; $rowmax = 65535; } $this->writeNameShort( $i, // sheet index 0x07, // NAME type $rowmin, $rowmax, $colmin, $colmax ); } } } /** * Writes all the DEFINEDNAME records (BIFF8). * So far this is only used for repeating rows/columns (print titles) and print areas */ private function writeAllDefinedNamesBiff8() { $chunk = ''; // Named ranges if (count($this->phpExcel->getNamedRanges()) > 0) { // Loop named ranges $namedRanges = $this->phpExcel->getNamedRanges(); foreach ($namedRanges as $namedRange) { // Create absolute coordinate $range = PHPExcel_Cell::splitRange($namedRange->getRange()); for ($i = 0; $i < count($range); $i++) { $range[$i][0] = '\'' . str_replace("'", "''", $namedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]); if (isset($range[$i][1])) { $range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]); } } $range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2 // parse formula try { $error = $this->parser->parse($range); $formulaData = $this->parser->toReversePolish(); // make sure tRef3d is of type tRef3dR (0x3A) if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { $formulaData = "\x3A" . substr($formulaData, 1); } if ($namedRange->getLocalOnly()) { // local scope $scope = $this->phpExcel->getIndex($namedRange->getScope()) + 1; } else { // global scope $scope = 0; } $chunk .= $this->writeData($this->writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); } catch (PHPExcel_Exception $e) { // do nothing } } } // total number of sheets $total_worksheets = $this->phpExcel->getSheetCount(); // write the print titles (repeating rows, columns), if any for ($i = 0; $i < $total_worksheets; ++$i) { $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); // simultaneous repeatColumns repeatRows if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; $repeat = $sheetSetup->getRowsToRepeatAtTop(); $rowmin = $repeat[0] - 1; $rowmax = $repeat[1] - 1; // construct formula data manually $formulaData = pack('Cv', 0x29, 0x17); // tMemFunc $formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d $formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d $formulaData .= pack('C', 0x10); // tList // store the DEFINEDNAME record $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); // (exclusive) either repeatColumns or repeatRows } elseif ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { // Columns to repeat if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; } else { $colmin = 0; $colmax = 255; } // Rows to repeat if ($sheetSetup->isRowsToRepeatAtTopSet()) { $repeat = $sheetSetup->getRowsToRepeatAtTop(); $rowmin = $repeat[0] - 1; $rowmax = $repeat[1] - 1; } else { $rowmin = 0; $rowmax = 65535; } // construct formula data manually because parser does not recognize absolute 3d cell references $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); // store the DEFINEDNAME record $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); } } // write the print areas, if any for ($i = 0; $i < $total_worksheets; ++$i) { $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); if ($sheetSetup->isPrintAreaSet()) { // Print area, e.g. A3:J6,H1:X20 $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); $countPrintArea = count($printArea); $formulaData = ''; for ($j = 0; $j < $countPrintArea; ++$j) { $printAreaRect = $printArea[$j]; // e.g. A3:J6 $printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]); $printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]); $print_rowmin = $printAreaRect[0][1] - 1; $print_rowmax = $printAreaRect[1][1] - 1; $print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1; $print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1; // construct formula data manually because parser does not recognize absolute 3d cell references $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); if ($j > 0) { $formulaData .= pack('C', 0x10); // list operator token ',' } } // store the DEFINEDNAME record $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); } } // write autofilters, if any for ($i = 0; $i < $total_worksheets; ++$i) { $sheetAutoFilter = $this->phpExcel->getSheet($i)->getAutoFilter(); $autoFilterRange = $sheetAutoFilter->getRange(); if (!empty($autoFilterRange)) { $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); //Autofilter built in name $name = pack('C', 0x0D); $chunk .= $this->writeData($this->writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); } } return $chunk; } /** * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data * * @param string $name The name in UTF-8 * @param string $formulaData The binary formula data * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global * @param boolean $isBuiltIn Built-in name? * @return string Complete binary record data */ private function writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) { $record = 0x0018; // option flags $options = $isBuiltIn ? 0x20 : 0x00; // length of the name, character count $nlen = PHPExcel_Shared_String::CountCharacters($name); // name with stripped length field $name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2); // size of the formula (in bytes) $sz = strlen($formulaData); // combine the parts $data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0) . $name . $formulaData; $length = strlen($data); $header = pack('vv', $record, $length); return $header . $data; } /** * Write a short NAME record * * @param string $name * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global * @param integer[][] $rangeBounds range boundaries * @param boolean $isHidden * @return string Complete binary record data * */ private function writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false) { $record = 0x0018; // option flags $options = ($isHidden ? 0x21 : 0x00); $extra = pack( 'Cvvvvv', 0x3B, $sheetIndex - 1, $rangeBounds[0][1] - 1, $rangeBounds[1][1] - 1, $rangeBounds[0][0] - 1, $rangeBounds[1][0] - 1 ); // size of the formula (in bytes) $sz = strlen($extra); // combine the parts $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) . $name . $extra; $length = strlen($data); $header = pack('vv', $record, $length); return $header . $data; } /** * Stores the CODEPAGE biff record. */ private function writeCodepage() { $record = 0x0042; // Record identifier $length = 0x0002; // Number of bytes to follow $cv = $this->codepage; // The code page $header = pack('vv', $record, $length); $data = pack('v', $cv); $this->append($header . $data); } /** * Write Excel BIFF WINDOW1 record. */ private function writeWindow1() { $record = 0x003D; // Record identifier $length = 0x0012; // Number of bytes to follow $xWn = 0x0000; // Horizontal position of window $yWn = 0x0000; // Vertical position of window $dxWn = 0x25BC; // Width of window $dyWn = 0x1572; // Height of window $grbit = 0x0038; // Option flags // not supported by PHPExcel, so there is only one selected sheet, the active $ctabsel = 1; // Number of workbook tabs selected $wTabRatio = 0x0258; // Tab to scrollbar ratio // not supported by PHPExcel, set to 0 $itabFirst = 0; // 1st displayed worksheet $itabCur = $this->phpExcel->getActiveSheetIndex(); // Active worksheet $header = pack("vv", $record, $length); $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, $grbit, $itabCur, $itabFirst, $ctabsel, $wTabRatio); $this->append($header . $data); } /** * Writes Excel BIFF BOUNDSHEET record. * * @param PHPExcel_Worksheet $sheet Worksheet name * @param integer $offset Location of worksheet BOF */ private function writeBoundSheet($sheet, $offset) { $sheetname = $sheet->getTitle(); $record = 0x0085; // Record identifier // sheet state switch ($sheet->getSheetState()) { case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: $ss = 0x00; break; case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: $ss = 0x01; break; case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; default: $ss = 0x00; break; } // sheet type $st = 0x00; $grbit = 0x0000; // Visibility and sheet type $data = pack("VCC", $offset, $ss, $st); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); $length = strlen($data); $header = pack("vv", $record, $length); $this->append($header . $data); } /** * Write Internal SUPBOOK record */ private function writeSupbookInternal() { $record = 0x01AE; // Record identifier $length = 0x0004; // Bytes to follow $header = pack("vv", $record, $length); $data = pack("vv", $this->phpExcel->getSheetCount(), 0x0401); return $this->writeData($header . $data); } /** * Writes the Excel BIFF EXTERNSHEET record. These references are used by * formulas. * */ private function writeExternalsheetBiff8() { $totalReferences = count($this->parser->references); $record = 0x0017; // Record identifier $length = 2 + 6 * $totalReferences; // Number of bytes to follow $supbook_index = 0; // FIXME: only using internal SUPBOOK record $header = pack("vv", $record, $length); $data = pack('v', $totalReferences); for ($i = 0; $i < $totalReferences; ++$i) { $data .= $this->parser->references[$i]; } return $this->writeData($header . $data); } /** * Write Excel BIFF STYLE records. */ private function writeStyle() { $record = 0x0293; // Record identifier $length = 0x0004; // Bytes to follow $ixfe = 0x8000; // Index to cell style XF $BuiltIn = 0x00; // Built-in style $iLevel = 0xff; // Outline style level $header = pack("vv", $record, $length); $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); $this->append($header . $data); } /** * Writes Excel FORMAT record for non "built-in" numerical formats. * * @param string $format Custom format string * @param integer $ifmt Format index code */ private function writeNumberFormat($format, $ifmt) { $record = 0x041E; // Record identifier $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); $length = 2 + strlen($numberFormatString); // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("v", $ifmt) . $numberFormatString; $this->append($header . $data); } /** * Write DATEMODE record to indicate the date system in use (1904 or 1900). */ private function writeDateMode() { $record = 0x0022; // Record identifier $length = 0x0002; // Bytes to follow $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? 1 : 0; // Flag for 1904 date system $header = pack("vv", $record, $length); $data = pack("v", $f1904); $this->append($header . $data); } /** * Write BIFF record EXTERNCOUNT to indicate the number of external sheet * references in the workbook. * * Excel only stores references to external sheets that are used in NAME. * The workbook NAME record is required to define the print area and the repeat * rows and columns. * * A similar method is used in Worksheet.php for a slightly different purpose. * * @param integer $cxals Number of external references */ private function writeExternalCount($cxals) { $record = 0x0016; // Record identifier $length = 0x0002; // Number of bytes to follow $header = pack("vv", $record, $length); $data = pack("v", $cxals); $this->append($header . $data); } /** * Writes the Excel BIFF EXTERNSHEET record. These references are used by * formulas. NAME record is required to define the print area and the repeat * rows and columns. * * A similar method is used in Worksheet.php for a slightly different purpose. * * @param string $sheetname Worksheet name */ private function writeExternalSheet($sheetname) { $record = 0x0017; // Record identifier $length = 0x02 + strlen($sheetname); // Number of bytes to follow $cch = strlen($sheetname); // Length of sheet name $rgch = 0x03; // Filename encoding $header = pack("vv", $record, $length); $data = pack("CC", $cch, $rgch); $this->append($header . $data . $sheetname); } /** * Store the NAME record in the short format that is used for storing the print * area, repeat rows only and repeat columns only. * * @param integer $index Sheet index * @param integer $type Built-in name type * @param integer $rowmin Start row * @param integer $rowmax End row * @param integer $colmin Start colum * @param integer $colmax End column */ private function writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) { $record = 0x0018; // Record identifier $length = 0x0024; // Number of bytes to follow $grbit = 0x0020; // Option flags $chKey = 0x00; // Keyboard shortcut $cch = 0x01; // Length of text name $cce = 0x0015; // Length of text definition $ixals = $index + 1; // Sheet index $itab = $ixals; // Equal to ixals $cchCustMenu = 0x00; // Length of cust menu text $cchDescription = 0x00; // Length of description text $cchHelptopic = 0x00; // Length of help topic text $cchStatustext = 0x00; // Length of status bar text $rgch = $type; // Built-in name type $unknown03 = 0x3b; $unknown04 = 0xffff - $index; $unknown05 = 0x0000; $unknown06 = 0x0000; $unknown07 = 0x1087; $unknown08 = 0x8005; $header = pack("vv", $record, $length); $data = pack("v", $grbit); $data .= pack("C", $chKey); $data .= pack("C", $cch); $data .= pack("v", $cce); $data .= pack("v", $ixals); $data .= pack("v", $itab); $data .= pack("C", $cchCustMenu); $data .= pack("C", $cchDescription); $data .= pack("C", $cchHelptopic); $data .= pack("C", $cchStatustext); $data .= pack("C", $rgch); $data .= pack("C", $unknown03); $data .= pack("v", $unknown04); $data .= pack("v", $unknown05); $data .= pack("v", $unknown06); $data .= pack("v", $unknown07); $data .= pack("v", $unknown08); $data .= pack("v", $index); $data .= pack("v", $index); $data .= pack("v", $rowmin); $data .= pack("v", $rowmax); $data .= pack("C", $colmin); $data .= pack("C", $colmax); $this->append($header . $data); } /** * Store the NAME record in the long format that is used for storing the repeat * rows and columns when both are specified. This shares a lot of code with * writeNameShort() but we use a separate method to keep the code clean. * Code abstraction for reuse can be carried too far, and I should know. ;-) * * @param integer $index Sheet index * @param integer $type Built-in name type * @param integer $rowmin Start row * @param integer $rowmax End row * @param integer $colmin Start colum * @param integer $colmax End column */ private function writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) { $record = 0x0018; // Record identifier $length = 0x003d; // Number of bytes to follow $grbit = 0x0020; // Option flags $chKey = 0x00; // Keyboard shortcut $cch = 0x01; // Length of text name $cce = 0x002e; // Length of text definition $ixals = $index + 1; // Sheet index $itab = $ixals; // Equal to ixals $cchCustMenu = 0x00; // Length of cust menu text $cchDescription = 0x00; // Length of description text $cchHelptopic = 0x00; // Length of help topic text $cchStatustext = 0x00; // Length of status bar text $rgch = $type; // Built-in name type $unknown01 = 0x29; $unknown02 = 0x002b; $unknown03 = 0x3b; $unknown04 = 0xffff-$index; $unknown05 = 0x0000; $unknown06 = 0x0000; $unknown07 = 0x1087; $unknown08 = 0x8008; $header = pack("vv", $record, $length); $data = pack("v", $grbit); $data .= pack("C", $chKey); $data .= pack("C", $cch); $data .= pack("v", $cce); $data .= pack("v", $ixals); $data .= pack("v", $itab); $data .= pack("C", $cchCustMenu); $data .= pack("C", $cchDescription); $data .= pack("C", $cchHelptopic); $data .= pack("C", $cchStatustext); $data .= pack("C", $rgch); $data .= pack("C", $unknown01); $data .= pack("v", $unknown02); // Column definition $data .= pack("C", $unknown03); $data .= pack("v", $unknown04); $data .= pack("v", $unknown05); $data .= pack("v", $unknown06); $data .= pack("v", $unknown07); $data .= pack("v", $unknown08); $data .= pack("v", $index); $data .= pack("v", $index); $data .= pack("v", 0x0000); $data .= pack("v", 0x3fff); $data .= pack("C", $colmin); $data .= pack("C", $colmax); // Row definition $data .= pack("C", $unknown03); $data .= pack("v", $unknown04); $data .= pack("v", $unknown05); $data .= pack("v", $unknown06); $data .= pack("v", $unknown07); $data .= pack("v", $unknown08); $data .= pack("v", $index); $data .= pack("v", $index); $data .= pack("v", $rowmin); $data .= pack("v", $rowmax); $data .= pack("C", 0x00); $data .= pack("C", 0xff); // End of data $data .= pack("C", 0x10); $this->append($header . $data); } /** * Stores the COUNTRY record for localization * * @return string */ private function writeCountry() { $record = 0x008C; // Record identifier $length = 4; // Number of bytes to follow $header = pack('vv', $record, $length); /* using the same country code always for simplicity */ $data = pack('vv', $this->countryCode, $this->countryCode); //$this->append($header . $data); return $this->writeData($header . $data); } /** * Write the RECALCID record * * @return string */ private function writeRecalcId() { $record = 0x01C1; // Record identifier $length = 8; // Number of bytes to follow $header = pack('vv', $record, $length); // by inspection of real Excel files, MS Office Excel 2007 writes this $data = pack('VV', 0x000001C1, 0x00001E667); return $this->writeData($header . $data); } /** * Stores the PALETTE biff record. */ private function writePalette() { $aref = $this->palette; $record = 0x0092; // Record identifier $length = 2 + 4 * count($aref); // Number of bytes to follow $ccv = count($aref); // Number of RGB values to follow $data = ''; // The RGB data // Pack the RGB data foreach ($aref as $color) { foreach ($color as $byte) { $data .= pack("C", $byte); } } $header = pack("vvv", $record, $length, $ccv); $this->append($header . $data); } /** * Handling of the SST continue blocks is complicated by the need to include an * additional continuation byte depending on whether the string is split between * blocks or whether it starts at the beginning of the block. (There are also * additional complications that will arise later when/if Rich Strings are * supported). * * The Excel documentation says that the SST record should be followed by an * EXTSST record. The EXTSST record is a hash table that is used to optimise * access to SST. However, despite the documentation it doesn't seem to be * required so we will ignore it. * * @return string Binary data */ private function writeSharedStringsTable() { // maximum size of record data (excluding record header) $continue_limit = 8224; // initialize array of record data blocks $recordDatas = array(); // start SST record data block with total number of strings, total number of unique strings $recordData = pack("VV", $this->stringTotal, $this->stringUnique); // loop through all (unique) strings in shared strings table foreach (array_keys($this->stringTable) as $string) { // here $string is a BIFF8 encoded string // length = character count $headerinfo = unpack("vlength/Cencoding", $string); // currently, this is always 1 = uncompressed $encoding = $headerinfo["encoding"]; // initialize finished writing current $string $finished = false; while ($finished === false) { // normally, there will be only one cycle, but if string cannot immediately be written as is // there will be need for more than one cylcle, if string longer than one record data block, there // may be need for even more cycles if (strlen($recordData) + strlen($string) <= $continue_limit) { // then we can write the string (or remainder of string) without any problems $recordData .= $string; if (strlen($recordData) + strlen($string) == $continue_limit) { // we close the record data block, and initialize a new one $recordDatas[] = $recordData; $recordData = ''; } // we are finished writing this string $finished = true; } else { // special treatment writing the string (or remainder of the string) // If the string is very long it may need to be written in more than one CONTINUE record. // check how many bytes more there is room for in the current record $space_remaining = $continue_limit - strlen($recordData); // minimum space needed // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character // compressed: 2 byte string length length field + 1 byte option flags + 1 byte character $min_space_needed = ($encoding == 1) ? 5 : 4; // We have two cases // 1. space remaining is less than minimum space needed // here we must waste the space remaining and move to next record data block // 2. space remaining is greater than or equal to minimum space needed // here we write as much as we can in the current block, then move to next record data block // 1. space remaining is less than minimum space needed if ($space_remaining < $min_space_needed) { // we close the block, store the block data $recordDatas[] = $recordData; // and start new record data block where we start writing the string $recordData = ''; // 2. space remaining is greater than or equal to minimum space needed } else { // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below $effective_space_remaining = $space_remaining; // for uncompressed strings, sometimes effective space remaining is reduced by 1 if ($encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1) { --$effective_space_remaining; } // one block fininshed, store the block data $recordData .= substr($string, 0, $effective_space_remaining); $string = substr($string, $effective_space_remaining); // for next cycle in while loop $recordDatas[] = $recordData; // start new record data block with the repeated option flags $recordData = pack('C', $encoding); } } } } // Store the last record data block unless it is empty // if there was no need for any continue records, this will be the for SST record data block itself if (strlen($recordData) > 0) { $recordDatas[] = $recordData; } // combine into one chunk with all the blocks SST, CONTINUE,... $chunk = ''; foreach ($recordDatas as $i => $recordData) { // first block should have the SST record header, remaing should have CONTINUE header $record = ($i == 0) ? 0x00FC : 0x003C; $header = pack("vv", $record, strlen($recordData)); $data = $header . $recordData; $chunk .= $this->writeData($data); } return $chunk; } /** * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records. */ private function writeMsoDrawingGroup() { // write the Escher stream if necessary if (isset($this->escher)) { $writer = new PHPExcel_Writer_Excel5_Escher($this->escher); $data = $writer->close(); $record = 0x00EB; $length = strlen($data); $header = pack("vv", $record, $length); return $this->writeData($header . $data); } else { return ''; } } /** * Get Escher object * * @return PHPExcel_Shared_Escher */ public function getEscher() { return $this->escher; } /** * Set Escher object * * @param PHPExcel_Shared_Escher $pValue */ public function setEscher(PHPExcel_Shared_Escher $pValue = null) { $this->escher = $pValue; } } PK!-Excel5/Parser.phpnu[=,;#()"{} const REGEX_SHEET_TITLE_UNQUOTED = '[^\*\:\/\\\\\?\[\]\+\-\% \\\'\^\&\<\>\=\,\;\#\(\)\"\{\}]+'; // Sheet title in quoted form (without surrounding quotes) // Invalid sheet title characters cannot occur in the sheet title: // *:/\?[] (usual invalid sheet title characters) // Single quote is represented as a pair '' const REGEX_SHEET_TITLE_QUOTED = '(([^\*\:\/\\\\\?\[\]\\\'])+|(\\\'\\\')+)+'; /** * The index of the character we are currently looking at * @var integer */ public $currentCharacter; /** * The token we are working on. * @var string */ public $currentToken; /** * The formula to parse * @var string */ private $formula; /** * The character ahead of the current char * @var string */ public $lookAhead; /** * The parse tree to be generated * @var string */ private $parseTree; /** * Array of external sheets * @var array */ private $externalSheets; /** * Array of sheet references in the form of REF structures * @var array */ public $references; /** * The class constructor * */ public function __construct() { $this->currentCharacter = 0; $this->currentToken = ''; // The token we are working on. $this->formula = ''; // The formula to parse. $this->lookAhead = ''; // The character ahead of the current char. $this->parseTree = ''; // The parse tree to be generated. $this->initializeHashes(); // Initialize the hashes: ptg's and function's ptg's $this->externalSheets = array(); $this->references = array(); } /** * Initialize the ptg and function hashes. * * @access private */ private function initializeHashes() { // The Excel ptg indices $this->ptg = array( 'ptgExp' => 0x01, 'ptgTbl' => 0x02, 'ptgAdd' => 0x03, 'ptgSub' => 0x04, 'ptgMul' => 0x05, 'ptgDiv' => 0x06, 'ptgPower' => 0x07, 'ptgConcat' => 0x08, 'ptgLT' => 0x09, 'ptgLE' => 0x0A, 'ptgEQ' => 0x0B, 'ptgGE' => 0x0C, 'ptgGT' => 0x0D, 'ptgNE' => 0x0E, 'ptgIsect' => 0x0F, 'ptgUnion' => 0x10, 'ptgRange' => 0x11, 'ptgUplus' => 0x12, 'ptgUminus' => 0x13, 'ptgPercent' => 0x14, 'ptgParen' => 0x15, 'ptgMissArg' => 0x16, 'ptgStr' => 0x17, 'ptgAttr' => 0x19, 'ptgSheet' => 0x1A, 'ptgEndSheet' => 0x1B, 'ptgErr' => 0x1C, 'ptgBool' => 0x1D, 'ptgInt' => 0x1E, 'ptgNum' => 0x1F, 'ptgArray' => 0x20, 'ptgFunc' => 0x21, 'ptgFuncVar' => 0x22, 'ptgName' => 0x23, 'ptgRef' => 0x24, 'ptgArea' => 0x25, 'ptgMemArea' => 0x26, 'ptgMemErr' => 0x27, 'ptgMemNoMem' => 0x28, 'ptgMemFunc' => 0x29, 'ptgRefErr' => 0x2A, 'ptgAreaErr' => 0x2B, 'ptgRefN' => 0x2C, 'ptgAreaN' => 0x2D, 'ptgMemAreaN' => 0x2E, 'ptgMemNoMemN' => 0x2F, 'ptgNameX' => 0x39, 'ptgRef3d' => 0x3A, 'ptgArea3d' => 0x3B, 'ptgRefErr3d' => 0x3C, 'ptgAreaErr3d' => 0x3D, 'ptgArrayV' => 0x40, 'ptgFuncV' => 0x41, 'ptgFuncVarV' => 0x42, 'ptgNameV' => 0x43, 'ptgRefV' => 0x44, 'ptgAreaV' => 0x45, 'ptgMemAreaV' => 0x46, 'ptgMemErrV' => 0x47, 'ptgMemNoMemV' => 0x48, 'ptgMemFuncV' => 0x49, 'ptgRefErrV' => 0x4A, 'ptgAreaErrV' => 0x4B, 'ptgRefNV' => 0x4C, 'ptgAreaNV' => 0x4D, 'ptgMemAreaNV' => 0x4E, 'ptgMemNoMemN' => 0x4F, 'ptgFuncCEV' => 0x58, 'ptgNameXV' => 0x59, 'ptgRef3dV' => 0x5A, 'ptgArea3dV' => 0x5B, 'ptgRefErr3dV' => 0x5C, 'ptgAreaErr3d' => 0x5D, 'ptgArrayA' => 0x60, 'ptgFuncA' => 0x61, 'ptgFuncVarA' => 0x62, 'ptgNameA' => 0x63, 'ptgRefA' => 0x64, 'ptgAreaA' => 0x65, 'ptgMemAreaA' => 0x66, 'ptgMemErrA' => 0x67, 'ptgMemNoMemA' => 0x68, 'ptgMemFuncA' => 0x69, 'ptgRefErrA' => 0x6A, 'ptgAreaErrA' => 0x6B, 'ptgRefNA' => 0x6C, 'ptgAreaNA' => 0x6D, 'ptgMemAreaNA' => 0x6E, 'ptgMemNoMemN' => 0x6F, 'ptgFuncCEA' => 0x78, 'ptgNameXA' => 0x79, 'ptgRef3dA' => 0x7A, 'ptgArea3dA' => 0x7B, 'ptgRefErr3dA' => 0x7C, 'ptgAreaErr3d' => 0x7D ); // Thanks to Michael Meeks and Gnumeric for the initial arg values. // // The following hash was generated by "function_locale.pl" in the distro. // Refer to function_locale.pl for non-English function names. // // The array elements are as follow: // ptg: The Excel function ptg code. // args: The number of arguments that the function takes: // >=0 is a fixed number of arguments. // -1 is a variable number of arguments. // class: The reference, value or array class of the function args. // vol: The function is volatile. // $this->functions = array( // function ptg args class vol 'COUNT' => array( 0, -1, 0, 0 ), 'IF' => array( 1, -1, 1, 0 ), 'ISNA' => array( 2, 1, 1, 0 ), 'ISERROR' => array( 3, 1, 1, 0 ), 'SUM' => array( 4, -1, 0, 0 ), 'AVERAGE' => array( 5, -1, 0, 0 ), 'MIN' => array( 6, -1, 0, 0 ), 'MAX' => array( 7, -1, 0, 0 ), 'ROW' => array( 8, -1, 0, 0 ), 'COLUMN' => array( 9, -1, 0, 0 ), 'NA' => array( 10, 0, 0, 0 ), 'NPV' => array( 11, -1, 1, 0 ), 'STDEV' => array( 12, -1, 0, 0 ), 'DOLLAR' => array( 13, -1, 1, 0 ), 'FIXED' => array( 14, -1, 1, 0 ), 'SIN' => array( 15, 1, 1, 0 ), 'COS' => array( 16, 1, 1, 0 ), 'TAN' => array( 17, 1, 1, 0 ), 'ATAN' => array( 18, 1, 1, 0 ), 'PI' => array( 19, 0, 1, 0 ), 'SQRT' => array( 20, 1, 1, 0 ), 'EXP' => array( 21, 1, 1, 0 ), 'LN' => array( 22, 1, 1, 0 ), 'LOG10' => array( 23, 1, 1, 0 ), 'ABS' => array( 24, 1, 1, 0 ), 'INT' => array( 25, 1, 1, 0 ), 'SIGN' => array( 26, 1, 1, 0 ), 'ROUND' => array( 27, 2, 1, 0 ), 'LOOKUP' => array( 28, -1, 0, 0 ), 'INDEX' => array( 29, -1, 0, 1 ), 'REPT' => array( 30, 2, 1, 0 ), 'MID' => array( 31, 3, 1, 0 ), 'LEN' => array( 32, 1, 1, 0 ), 'VALUE' => array( 33, 1, 1, 0 ), 'TRUE' => array( 34, 0, 1, 0 ), 'FALSE' => array( 35, 0, 1, 0 ), 'AND' => array( 36, -1, 0, 0 ), 'OR' => array( 37, -1, 0, 0 ), 'NOT' => array( 38, 1, 1, 0 ), 'MOD' => array( 39, 2, 1, 0 ), 'DCOUNT' => array( 40, 3, 0, 0 ), 'DSUM' => array( 41, 3, 0, 0 ), 'DAVERAGE' => array( 42, 3, 0, 0 ), 'DMIN' => array( 43, 3, 0, 0 ), 'DMAX' => array( 44, 3, 0, 0 ), 'DSTDEV' => array( 45, 3, 0, 0 ), 'VAR' => array( 46, -1, 0, 0 ), 'DVAR' => array( 47, 3, 0, 0 ), 'TEXT' => array( 48, 2, 1, 0 ), 'LINEST' => array( 49, -1, 0, 0 ), 'TREND' => array( 50, -1, 0, 0 ), 'LOGEST' => array( 51, -1, 0, 0 ), 'GROWTH' => array( 52, -1, 0, 0 ), 'PV' => array( 56, -1, 1, 0 ), 'FV' => array( 57, -1, 1, 0 ), 'NPER' => array( 58, -1, 1, 0 ), 'PMT' => array( 59, -1, 1, 0 ), 'RATE' => array( 60, -1, 1, 0 ), 'MIRR' => array( 61, 3, 0, 0 ), 'IRR' => array( 62, -1, 0, 0 ), 'RAND' => array( 63, 0, 1, 1 ), 'MATCH' => array( 64, -1, 0, 0 ), 'DATE' => array( 65, 3, 1, 0 ), 'TIME' => array( 66, 3, 1, 0 ), 'DAY' => array( 67, 1, 1, 0 ), 'MONTH' => array( 68, 1, 1, 0 ), 'YEAR' => array( 69, 1, 1, 0 ), 'WEEKDAY' => array( 70, -1, 1, 0 ), 'HOUR' => array( 71, 1, 1, 0 ), 'MINUTE' => array( 72, 1, 1, 0 ), 'SECOND' => array( 73, 1, 1, 0 ), 'NOW' => array( 74, 0, 1, 1 ), 'AREAS' => array( 75, 1, 0, 1 ), 'ROWS' => array( 76, 1, 0, 1 ), 'COLUMNS' => array( 77, 1, 0, 1 ), 'OFFSET' => array( 78, -1, 0, 1 ), 'SEARCH' => array( 82, -1, 1, 0 ), 'TRANSPOSE' => array( 83, 1, 1, 0 ), 'TYPE' => array( 86, 1, 1, 0 ), 'ATAN2' => array( 97, 2, 1, 0 ), 'ASIN' => array( 98, 1, 1, 0 ), 'ACOS' => array( 99, 1, 1, 0 ), 'CHOOSE' => array( 100, -1, 1, 0 ), 'HLOOKUP' => array( 101, -1, 0, 0 ), 'VLOOKUP' => array( 102, -1, 0, 0 ), 'ISREF' => array( 105, 1, 0, 0 ), 'LOG' => array( 109, -1, 1, 0 ), 'CHAR' => array( 111, 1, 1, 0 ), 'LOWER' => array( 112, 1, 1, 0 ), 'UPPER' => array( 113, 1, 1, 0 ), 'PROPER' => array( 114, 1, 1, 0 ), 'LEFT' => array( 115, -1, 1, 0 ), 'RIGHT' => array( 116, -1, 1, 0 ), 'EXACT' => array( 117, 2, 1, 0 ), 'TRIM' => array( 118, 1, 1, 0 ), 'REPLACE' => array( 119, 4, 1, 0 ), 'SUBSTITUTE' => array( 120, -1, 1, 0 ), 'CODE' => array( 121, 1, 1, 0 ), 'FIND' => array( 124, -1, 1, 0 ), 'CELL' => array( 125, -1, 0, 1 ), 'ISERR' => array( 126, 1, 1, 0 ), 'ISTEXT' => array( 127, 1, 1, 0 ), 'ISNUMBER' => array( 128, 1, 1, 0 ), 'ISBLANK' => array( 129, 1, 1, 0 ), 'T' => array( 130, 1, 0, 0 ), 'N' => array( 131, 1, 0, 0 ), 'DATEVALUE' => array( 140, 1, 1, 0 ), 'TIMEVALUE' => array( 141, 1, 1, 0 ), 'SLN' => array( 142, 3, 1, 0 ), 'SYD' => array( 143, 4, 1, 0 ), 'DDB' => array( 144, -1, 1, 0 ), 'INDIRECT' => array( 148, -1, 1, 1 ), 'CALL' => array( 150, -1, 1, 0 ), 'CLEAN' => array( 162, 1, 1, 0 ), 'MDETERM' => array( 163, 1, 2, 0 ), 'MINVERSE' => array( 164, 1, 2, 0 ), 'MMULT' => array( 165, 2, 2, 0 ), 'IPMT' => array( 167, -1, 1, 0 ), 'PPMT' => array( 168, -1, 1, 0 ), 'COUNTA' => array( 169, -1, 0, 0 ), 'PRODUCT' => array( 183, -1, 0, 0 ), 'FACT' => array( 184, 1, 1, 0 ), 'DPRODUCT' => array( 189, 3, 0, 0 ), 'ISNONTEXT' => array( 190, 1, 1, 0 ), 'STDEVP' => array( 193, -1, 0, 0 ), 'VARP' => array( 194, -1, 0, 0 ), 'DSTDEVP' => array( 195, 3, 0, 0 ), 'DVARP' => array( 196, 3, 0, 0 ), 'TRUNC' => array( 197, -1, 1, 0 ), 'ISLOGICAL' => array( 198, 1, 1, 0 ), 'DCOUNTA' => array( 199, 3, 0, 0 ), 'USDOLLAR' => array( 204, -1, 1, 0 ), 'FINDB' => array( 205, -1, 1, 0 ), 'SEARCHB' => array( 206, -1, 1, 0 ), 'REPLACEB' => array( 207, 4, 1, 0 ), 'LEFTB' => array( 208, -1, 1, 0 ), 'RIGHTB' => array( 209, -1, 1, 0 ), 'MIDB' => array( 210, 3, 1, 0 ), 'LENB' => array( 211, 1, 1, 0 ), 'ROUNDUP' => array( 212, 2, 1, 0 ), 'ROUNDDOWN' => array( 213, 2, 1, 0 ), 'ASC' => array( 214, 1, 1, 0 ), 'DBCS' => array( 215, 1, 1, 0 ), 'RANK' => array( 216, -1, 0, 0 ), 'ADDRESS' => array( 219, -1, 1, 0 ), 'DAYS360' => array( 220, -1, 1, 0 ), 'TODAY' => array( 221, 0, 1, 1 ), 'VDB' => array( 222, -1, 1, 0 ), 'MEDIAN' => array( 227, -1, 0, 0 ), 'SUMPRODUCT' => array( 228, -1, 2, 0 ), 'SINH' => array( 229, 1, 1, 0 ), 'COSH' => array( 230, 1, 1, 0 ), 'TANH' => array( 231, 1, 1, 0 ), 'ASINH' => array( 232, 1, 1, 0 ), 'ACOSH' => array( 233, 1, 1, 0 ), 'ATANH' => array( 234, 1, 1, 0 ), 'DGET' => array( 235, 3, 0, 0 ), 'INFO' => array( 244, 1, 1, 1 ), 'DB' => array( 247, -1, 1, 0 ), 'FREQUENCY' => array( 252, 2, 0, 0 ), 'ERROR.TYPE' => array( 261, 1, 1, 0 ), 'REGISTER.ID' => array( 267, -1, 1, 0 ), 'AVEDEV' => array( 269, -1, 0, 0 ), 'BETADIST' => array( 270, -1, 1, 0 ), 'GAMMALN' => array( 271, 1, 1, 0 ), 'BETAINV' => array( 272, -1, 1, 0 ), 'BINOMDIST' => array( 273, 4, 1, 0 ), 'CHIDIST' => array( 274, 2, 1, 0 ), 'CHIINV' => array( 275, 2, 1, 0 ), 'COMBIN' => array( 276, 2, 1, 0 ), 'CONFIDENCE' => array( 277, 3, 1, 0 ), 'CRITBINOM' => array( 278, 3, 1, 0 ), 'EVEN' => array( 279, 1, 1, 0 ), 'EXPONDIST' => array( 280, 3, 1, 0 ), 'FDIST' => array( 281, 3, 1, 0 ), 'FINV' => array( 282, 3, 1, 0 ), 'FISHER' => array( 283, 1, 1, 0 ), 'FISHERINV' => array( 284, 1, 1, 0 ), 'FLOOR' => array( 285, 2, 1, 0 ), 'GAMMADIST' => array( 286, 4, 1, 0 ), 'GAMMAINV' => array( 287, 3, 1, 0 ), 'CEILING' => array( 288, 2, 1, 0 ), 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), 'LOGNORMDIST' => array( 290, 3, 1, 0 ), 'LOGINV' => array( 291, 3, 1, 0 ), 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), 'NORMDIST' => array( 293, 4, 1, 0 ), 'NORMSDIST' => array( 294, 1, 1, 0 ), 'NORMINV' => array( 295, 3, 1, 0 ), 'NORMSINV' => array( 296, 1, 1, 0 ), 'STANDARDIZE' => array( 297, 3, 1, 0 ), 'ODD' => array( 298, 1, 1, 0 ), 'PERMUT' => array( 299, 2, 1, 0 ), 'POISSON' => array( 300, 3, 1, 0 ), 'TDIST' => array( 301, 3, 1, 0 ), 'WEIBULL' => array( 302, 4, 1, 0 ), 'SUMXMY2' => array( 303, 2, 2, 0 ), 'SUMX2MY2' => array( 304, 2, 2, 0 ), 'SUMX2PY2' => array( 305, 2, 2, 0 ), 'CHITEST' => array( 306, 2, 2, 0 ), 'CORREL' => array( 307, 2, 2, 0 ), 'COVAR' => array( 308, 2, 2, 0 ), 'FORECAST' => array( 309, 3, 2, 0 ), 'FTEST' => array( 310, 2, 2, 0 ), 'INTERCEPT' => array( 311, 2, 2, 0 ), 'PEARSON' => array( 312, 2, 2, 0 ), 'RSQ' => array( 313, 2, 2, 0 ), 'STEYX' => array( 314, 2, 2, 0 ), 'SLOPE' => array( 315, 2, 2, 0 ), 'TTEST' => array( 316, 4, 2, 0 ), 'PROB' => array( 317, -1, 2, 0 ), 'DEVSQ' => array( 318, -1, 0, 0 ), 'GEOMEAN' => array( 319, -1, 0, 0 ), 'HARMEAN' => array( 320, -1, 0, 0 ), 'SUMSQ' => array( 321, -1, 0, 0 ), 'KURT' => array( 322, -1, 0, 0 ), 'SKEW' => array( 323, -1, 0, 0 ), 'ZTEST' => array( 324, -1, 0, 0 ), 'LARGE' => array( 325, 2, 0, 0 ), 'SMALL' => array( 326, 2, 0, 0 ), 'QUARTILE' => array( 327, 2, 0, 0 ), 'PERCENTILE' => array( 328, 2, 0, 0 ), 'PERCENTRANK' => array( 329, -1, 0, 0 ), 'MODE' => array( 330, -1, 2, 0 ), 'TRIMMEAN' => array( 331, 2, 0, 0 ), 'TINV' => array( 332, 2, 1, 0 ), 'CONCATENATE' => array( 336, -1, 1, 0 ), 'POWER' => array( 337, 2, 1, 0 ), 'RADIANS' => array( 342, 1, 1, 0 ), 'DEGREES' => array( 343, 1, 1, 0 ), 'SUBTOTAL' => array( 344, -1, 0, 0 ), 'SUMIF' => array( 345, -1, 0, 0 ), 'COUNTIF' => array( 346, 2, 0, 0 ), 'COUNTBLANK' => array( 347, 1, 0, 0 ), 'ISPMT' => array( 350, 4, 1, 0 ), 'DATEDIF' => array( 351, 3, 1, 0 ), 'DATESTRING' => array( 352, 1, 1, 0 ), 'NUMBERSTRING' => array( 353, 2, 1, 0 ), 'ROMAN' => array( 354, -1, 1, 0 ), 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), 'HYPERLINK' => array( 359, -1, 1, 0 ), 'PHONETIC' => array( 360, 1, 0, 0 ), 'AVERAGEA' => array( 361, -1, 0, 0 ), 'MAXA' => array( 362, -1, 0, 0 ), 'MINA' => array( 363, -1, 0, 0 ), 'STDEVPA' => array( 364, -1, 0, 0 ), 'VARPA' => array( 365, -1, 0, 0 ), 'STDEVA' => array( 366, -1, 0, 0 ), 'VARA' => array( 367, -1, 0, 0 ), 'BAHTTEXT' => array( 368, 1, 0, 0 ), ); } /** * Convert a token to the proper ptg value. * * @access private * @param mixed $token The token to convert. * @return mixed the converted token on success */ private function convert($token) { if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { return $this->convertString($token); } elseif (is_numeric($token)) { return $this->convertNumber($token); // match references like A1 or $A$1 } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/', $token)) { return $this->convertRef2d($token); // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u", $token)) { return $this->convertRef3d($token); // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u", $token)) { return $this->convertRef3d($token); // match ranges like A1:B2 or $A$1:$B$2 } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) { return $this->convertRange2d($token); // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u", $token)) { return $this->convertRange3d($token); // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u", $token)) { return $this->convertRange3d($token); // operators (including parentheses) } elseif (isset($this->ptg[$token])) { return pack("C", $this->ptg[$token]); // match error codes } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { return $this->convertError($token); // commented so argument number can be processed correctly. See toReversePolish(). /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token)) { return($this->convertFunction($token, $this->_func_args)); }*/ // if it's an argument, ignore the token (the argument remains) } elseif ($token == 'arg') { return ''; } // TODO: use real error codes throw new PHPExcel_Writer_Exception("Unknown token $token"); } /** * Convert a number token to ptgInt or ptgNum * * @access private * @param mixed $num an integer or double for conversion to its ptg value */ private function convertNumber($num) { // Integer in the range 0..2**16-1 if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { return pack("Cv", $this->ptg['ptgInt'], $num); } else { // A float if (PHPExcel_Writer_Excel5_BIFFwriter::getByteOrder()) { // if it's Big Endian $num = strrev($num); } return pack("Cd", $this->ptg['ptgNum'], $num); } } /** * Convert a string token to ptgStr * * @access private * @param string $string A string for conversion to its ptg value. * @return mixed the converted token on success */ private function convertString($string) { // chop away beggining and ending quotes $string = substr($string, 1, strlen($string) - 2); if (strlen($string) > 255) { throw new PHPExcel_Writer_Exception("String is too long"); } return pack('C', $this->ptg['ptgStr']) . PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($string); } /** * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of * args that it takes. * * @access private * @param string $token The name of the function for convertion to ptg value. * @param integer $num_args The number of arguments the function receives. * @return string The packed ptg for the function */ private function convertFunction($token, $num_args) { $args = $this->functions[$token][1]; // $volatile = $this->functions[$token][3]; // Fixed number of args eg. TIME($i, $j, $k). if ($args >= 0) { return pack("Cv", $this->ptg['ptgFuncV'], $this->functions[$token][0]); } // Variable number of args eg. SUM($i, $j, $k, ..). if ($args == -1) { return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]); } } /** * Convert an Excel range such as A1:D4 to a ptgRefV. * * @access private * @param string $range An Excel range in the A1:A2 * @param int $class */ private function convertRange2d($range, $class = 0) { // TODO: possible class value 0,1,2 check Formula.pm // Split the range into 2 cell refs if (preg_match('/^(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)\:(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)$/', $range)) { list($cell1, $cell2) = explode(':', $range); } else { // TODO: use real error codes throw new PHPExcel_Writer_Exception("Unknown range separator"); } // Convert the cell references list($row1, $col1) = $this->cellToPackedRowcol($cell1); list($row2, $col2) = $this->cellToPackedRowcol($cell2); // The ptg value depends on the class of the ptg. if ($class == 0) { $ptgArea = pack("C", $this->ptg['ptgArea']); } elseif ($class == 1) { $ptgArea = pack("C", $this->ptg['ptgAreaV']); } elseif ($class == 2) { $ptgArea = pack("C", $this->ptg['ptgAreaA']); } else { // TODO: use real error codes throw new PHPExcel_Writer_Exception("Unknown class $class"); } return $ptgArea . $row1 . $row2 . $col1. $col2; } /** * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to * a ptgArea3d. * * @access private * @param string $token An Excel range in the Sheet1!A1:A2 format. * @return mixed The packed ptgArea3d token on success. */ private function convertRange3d($token) { // $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) // Split the ref at the ! symbol list($ext_ref, $range) = explode('!', $token); // Convert the external reference part (different for BIFF8) $ext_ref = $this->getRefIndex($ext_ref); // Split the range into 2 cell refs list($cell1, $cell2) = explode(':', $range); // Convert the cell references if (preg_match("/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\d+)$/", $cell1)) { list($row1, $col1) = $this->cellToPackedRowcol($cell1); list($row2, $col2) = $this->cellToPackedRowcol($cell2); } else { // It's a rows range (like 26:27) list($row1, $col1, $row2, $col2) = $this->rangeToPackedRange($cell1.':'.$cell2); } // The ptg value depends on the class of the ptg. // if ($class == 0) { $ptgArea = pack("C", $this->ptg['ptgArea3d']); // } elseif ($class == 1) { // $ptgArea = pack("C", $this->ptg['ptgArea3dV']); // } elseif ($class == 2) { // $ptgArea = pack("C", $this->ptg['ptgArea3dA']); // } else { // throw new PHPExcel_Writer_Exception("Unknown class $class"); // } return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; } /** * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. * * @access private * @param string $cell An Excel cell reference * @return string The cell in packed() format with the corresponding ptg */ private function convertRef2d($cell) { // $class = 2; // as far as I know, this is magick. // Convert the cell reference $cell_array = $this->cellToPackedRowcol($cell); list($row, $col) = $cell_array; // The ptg value depends on the class of the ptg. // if ($class == 0) { // $ptgRef = pack("C", $this->ptg['ptgRef']); // } elseif ($class == 1) { // $ptgRef = pack("C", $this->ptg['ptgRefV']); // } elseif ($class == 2) { $ptgRef = pack("C", $this->ptg['ptgRefA']); // } else { // // TODO: use real error codes // throw new PHPExcel_Writer_Exception("Unknown class $class"); // } return $ptgRef.$row.$col; } /** * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a * ptgRef3d. * * @access private * @param string $cell An Excel cell reference * @return mixed The packed ptgRef3d token on success. */ private function convertRef3d($cell) { // $class = 2; // as far as I know, this is magick. // Split the ref at the ! symbol list($ext_ref, $cell) = explode('!', $cell); // Convert the external reference part (different for BIFF8) $ext_ref = $this->getRefIndex($ext_ref); // Convert the cell reference part list($row, $col) = $this->cellToPackedRowcol($cell); // The ptg value depends on the class of the ptg. // if ($class == 0) { // $ptgRef = pack("C", $this->ptg['ptgRef3d']); // } elseif ($class == 1) { // $ptgRef = pack("C", $this->ptg['ptgRef3dV']); // } elseif ($class == 2) { $ptgRef = pack("C", $this->ptg['ptgRef3dA']); // } else { // throw new PHPExcel_Writer_Exception("Unknown class $class"); // } return $ptgRef . $ext_ref. $row . $col; } /** * Convert an error code to a ptgErr * * @access private * @param string $errorCode The error code for conversion to its ptg value * @return string The error code ptgErr */ private function convertError($errorCode) { switch ($errorCode) { case '#NULL!': return pack("C", 0x00); case '#DIV/0!': return pack("C", 0x07); case '#VALUE!': return pack("C", 0x0F); case '#REF!': return pack("C", 0x17); case '#NAME?': return pack("C", 0x1D); case '#NUM!': return pack("C", 0x24); case '#N/A': return pack("C", 0x2A); } return pack("C", 0xFF); } /** * Convert the sheet name part of an external reference, for example "Sheet1" or * "Sheet1:Sheet2", to a packed structure. * * @access private * @param string $ext_ref The name of the external reference * @return string The reference index in packed() format */ private function packExtRef($ext_ref) { $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. // Check if there is a sheet range eg., Sheet1:Sheet2. if (preg_match("/:/", $ext_ref)) { list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); $sheet1 = $this->getSheetIndex($sheet_name1); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); } $sheet2 = $this->getSheetIndex($sheet_name2); if ($sheet2 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); } // Reverse max and min sheet numbers if necessary if ($sheet1 > $sheet2) { list($sheet1, $sheet2) = array($sheet2, $sheet1); } } else { // Single sheet name only. $sheet1 = $this->getSheetIndex($ext_ref); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); } $sheet2 = $sheet1; } // References are stored relative to 0xFFFF. $offset = -1 - $sheet1; return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); } /** * Look up the REF index that corresponds to an external sheet name * (or range). If it doesn't exist yet add it to the workbook's references * array. It assumes all sheet names given must exist. * * @access private * @param string $ext_ref The name of the external reference * @return mixed The reference index in packed() format on success */ private function getRefIndex($ext_ref) { $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. $ext_ref = str_replace('\'\'', '\'', $ext_ref); // Replace escaped '' with ' // Check if there is a sheet range eg., Sheet1:Sheet2. if (preg_match("/:/", $ext_ref)) { list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); $sheet1 = $this->getSheetIndex($sheet_name1); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); } $sheet2 = $this->getSheetIndex($sheet_name2); if ($sheet2 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); } // Reverse max and min sheet numbers if necessary if ($sheet1 > $sheet2) { list($sheet1, $sheet2) = array($sheet2, $sheet1); } } else { // Single sheet name only. $sheet1 = $this->getSheetIndex($ext_ref); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); } $sheet2 = $sheet1; } // assume all references belong to this document $supbook_index = 0x00; $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); $totalreferences = count($this->references); $index = -1; for ($i = 0; $i < $totalreferences; ++$i) { if ($ref == $this->references[$i]) { $index = $i; break; } } // if REF was not found add it to references array if ($index == -1) { $this->references[$totalreferences] = $ref; $index = $totalreferences; } return pack('v', $index); } /** * Look up the index that corresponds to an external sheet name. The hash of * sheet names is updated by the addworksheet() method of the * PHPExcel_Writer_Excel5_Workbook class. * * @access private * @param string $sheet_name Sheet name * @return integer The sheet index, -1 if the sheet was not found */ private function getSheetIndex($sheet_name) { if (!isset($this->externalSheets[$sheet_name])) { return -1; } else { return $this->externalSheets[$sheet_name]; } } /** * This method is used to update the array of sheet names. It is * called by the addWorksheet() method of the * PHPExcel_Writer_Excel5_Workbook class. * * @access public * @see PHPExcel_Writer_Excel5_Workbook::addWorksheet() * @param string $name The name of the worksheet being added * @param integer $index The index of the worksheet being added */ public function setExtSheet($name, $index) { $this->externalSheets[$name] = $index; } /** * pack() row and column into the required 3 or 4 byte format. * * @access private * @param string $cell The Excel cell reference to be packed * @return array Array containing the row and column in packed() format */ private function cellToPackedRowcol($cell) { $cell = strtoupper($cell); list($row, $col, $row_rel, $col_rel) = $this->cellToRowcol($cell); if ($col >= 256) { throw new PHPExcel_Writer_Exception("Column in: $cell greater than 255"); } if ($row >= 65536) { throw new PHPExcel_Writer_Exception("Row in: $cell greater than 65536 "); } // Set the high bits to indicate if row or col are relative. $col |= $col_rel << 14; $col |= $row_rel << 15; $col = pack('v', $col); $row = pack('v', $row); return array($row, $col); } /** * pack() row range into the required 3 or 4 byte format. * Just using maximum col/rows, which is probably not the correct solution * * @access private * @param string $range The Excel range to be packed * @return array Array containing (row1,col1,row2,col2) in packed() format */ private function rangeToPackedRange($range) { preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); // return absolute rows if there is a $ in the ref $row1_rel = empty($match[1]) ? 1 : 0; $row1 = $match[2]; $row2_rel = empty($match[3]) ? 1 : 0; $row2 = $match[4]; // Convert 1-index to zero-index --$row1; --$row2; // Trick poor inocent Excel $col1 = 0; $col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!) // FIXME: this changes for BIFF8 if (($row1 >= 65536) or ($row2 >= 65536)) { throw new PHPExcel_Writer_Exception("Row in: $range greater than 65536 "); } // Set the high bits to indicate if rows are relative. $col1 |= $row1_rel << 15; $col2 |= $row2_rel << 15; $col1 = pack('v', $col1); $col2 = pack('v', $col2); $row1 = pack('v', $row1); $row2 = pack('v', $row2); return array($row1, $col1, $row2, $col2); } /** * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero * indexed row and column number. Also returns two (0,1) values to indicate * whether the row or column are relative references. * * @access private * @param string $cell The Excel cell reference in A1 format. * @return array */ private function cellToRowcol($cell) { preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match); // return absolute column if there is a $ in the ref $col_rel = empty($match[1]) ? 1 : 0; $col_ref = $match[2]; $row_rel = empty($match[3]) ? 1 : 0; $row = $match[4]; // Convert base26 column string to a number. $expn = strlen($col_ref) - 1; $col = 0; $col_ref_length = strlen($col_ref); for ($i = 0; $i < $col_ref_length; ++$i) { $col += (ord($col_ref{$i}) - 64) * pow(26, $expn); --$expn; } // Convert 1-index to zero-index --$row; --$col; return array($row, $col, $row_rel, $col_rel); } /** * Advance to the next valid token. * * @access private */ private function advance() { $i = $this->currentCharacter; $formula_length = strlen($this->formula); // eat up white spaces if ($i < $formula_length) { while ($this->formula{$i} == " ") { ++$i; } if ($i < ($formula_length - 1)) { $this->lookAhead = $this->formula{$i+1}; } $token = ''; } while ($i < $formula_length) { $token .= $this->formula{$i}; if ($i < ($formula_length - 1)) { $this->lookAhead = $this->formula{$i+1}; } else { $this->lookAhead = ''; } if ($this->match($token) != '') { //if ($i < strlen($this->formula) - 1) { // $this->lookAhead = $this->formula{$i+1}; //} $this->currentCharacter = $i + 1; $this->currentToken = $token; return 1; } if ($i < ($formula_length - 2)) { $this->lookAhead = $this->formula{$i+2}; } else { // if we run out of characters lookAhead becomes empty $this->lookAhead = ''; } ++$i; } //die("Lexical error ".$this->currentCharacter); } /** * Checks if it's a valid token. * * @access private * @param mixed $token The token to check. * @return mixed The checked token or false on failure */ private function match($token) { switch ($token) { case "+": case "-": case "*": case "/": case "(": case ")": case ",": case ";": case ">=": case "<=": case "=": case "<>": case "^": case "&": case "%": return $token; break; case ">": if ($this->lookAhead == '=') { // it's a GE token break; } return $token; break; case "<": // it's a LE or a NE token if (($this->lookAhead == '=') or ($this->lookAhead == '>')) { break; } return $token; break; default: // if it's a reference A1 or $A$1 or $A1 or A$1 if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $token) and !preg_match("/[0-9]/", $this->lookAhead) and ($this->lookAhead != ':') and ($this->lookAhead != '.') and ($this->lookAhead != '!')) { return $token; } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead) and ($this->lookAhead != ':') and ($this->lookAhead != '.')) { // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) return $token; } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead) and ($this->lookAhead != ':') and ($this->lookAhead != '.')) { // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) return $token; } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) && !preg_match("/[0-9]/", $this->lookAhead)) { // if it's a range A1:A2 or $A$1:$A$2 return $token; } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead)) { // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 return $token; } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead)) { // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 return $token; } elseif (is_numeric($token) and (!is_numeric($token.$this->lookAhead) or ($this->lookAhead == '')) and ($this->lookAhead != '!') and ($this->lookAhead != ':')) { // If it's a number (check that it's not a sheet name or range) return $token; } elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token) and $this->lookAhead != '"' and (substr_count($token, '"')%2 == 0)) { // If it's a string (of maximum 255 characters) return $token; } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { // If it's an error code return $token; } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $token) and ($this->lookAhead == "(")) { // if it's a function call return $token; } elseif (substr($token, -1) == ')') { // It's an argument of some description (e.g. a named range), // precise nature yet to be determined return $token; } return ''; } } /** * The parsing method. It parses a formula. * * @access public * @param string $formula The formula to parse, without the initial equal * sign (=). * @return mixed true on success */ public function parse($formula) { $this->currentCharacter = 0; $this->formula = $formula; $this->lookAhead = isset($formula{1}) ? $formula{1} : ''; $this->advance(); $this->parseTree = $this->condition(); return true; } /** * It parses a condition. It assumes the following rule: * Cond -> Expr [(">" | "<") Expr] * * @access private * @return mixed The parsed ptg'd tree on success */ private function condition() { $result = $this->expression(); if ($this->currentToken == "<") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgLT', $result, $result2); } elseif ($this->currentToken == ">") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgGT', $result, $result2); } elseif ($this->currentToken == "<=") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgLE', $result, $result2); } elseif ($this->currentToken == ">=") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgGE', $result, $result2); } elseif ($this->currentToken == "=") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgEQ', $result, $result2); } elseif ($this->currentToken == "<>") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgNE', $result, $result2); } elseif ($this->currentToken == "&") { $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgConcat', $result, $result2); } return $result; } /** * It parses a expression. It assumes the following rule: * Expr -> Term [("+" | "-") Term] * -> "string" * -> "-" Term : Negative value * -> "+" Term : Positive value * -> Error code * * @access private * @return mixed The parsed ptg'd tree on success */ private function expression() { // If it's a string return a string node if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->currentToken)) { $tmp = str_replace('""', '"', $this->currentToken); if (($tmp == '"') || ($tmp == '')) { // Trap for "" that has been used for an empty string $tmp = '""'; } $result = $this->createTree($tmp, '', ''); $this->advance(); return $result; // If it's an error code } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->currentToken) or $this->currentToken == '#N/A') { $result = $this->createTree($this->currentToken, 'ptgErr', ''); $this->advance(); return $result; // If it's a negative value } elseif ($this->currentToken == "-") { // catch "-" Term $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgUminus', $result2, ''); return $result; // If it's a positive value } elseif ($this->currentToken == "+") { // catch "+" Term $this->advance(); $result2 = $this->expression(); $result = $this->createTree('ptgUplus', $result2, ''); return $result; } $result = $this->term(); while (($this->currentToken == "+") or ($this->currentToken == "-") or ($this->currentToken == "^")) { /**/ if ($this->currentToken == "+") { $this->advance(); $result2 = $this->term(); $result = $this->createTree('ptgAdd', $result, $result2); } elseif ($this->currentToken == "-") { $this->advance(); $result2 = $this->term(); $result = $this->createTree('ptgSub', $result, $result2); } else { $this->advance(); $result2 = $this->term(); $result = $this->createTree('ptgPower', $result, $result2); } } return $result; } /** * This function just introduces a ptgParen element in the tree, so that Excel * doesn't get confused when working with a parenthesized formula afterwards. * * @access private * @see fact() * @return array The parsed ptg'd tree */ private function parenthesizedExpression() { $result = $this->createTree('ptgParen', $this->expression(), ''); return $result; } /** * It parses a term. It assumes the following rule: * Term -> Fact [("*" | "/") Fact] * * @access private * @return mixed The parsed ptg'd tree on success */ private function term() { $result = $this->fact(); while (($this->currentToken == "*") or ($this->currentToken == "/")) { /**/ if ($this->currentToken == "*") { $this->advance(); $result2 = $this->fact(); $result = $this->createTree('ptgMul', $result, $result2); } else { $this->advance(); $result2 = $this->fact(); $result = $this->createTree('ptgDiv', $result, $result2); } } return $result; } /** * It parses a factor. It assumes the following rule: * Fact -> ( Expr ) * | CellRef * | CellRange * | Number * | Function * * @access private * @return mixed The parsed ptg'd tree on success */ private function fact() { if ($this->currentToken == "(") { $this->advance(); // eat the "(" $result = $this->parenthesizedExpression(); if ($this->currentToken != ")") { throw new PHPExcel_Writer_Exception("')' token expected."); } $this->advance(); // eat the ")" return $result; } // if it's a reference if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $this->currentToken)) { $result = $this->createTree($this->currentToken, '', ''); $this->advance(); return $result; } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) $result = $this->createTree($this->currentToken, '', ''); $this->advance(); return $result; } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) $result = $this->createTree($this->currentToken, '', ''); $this->advance(); return $result; } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->currentToken) or preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->currentToken)) { // if it's a range A1:B2 or $A$1:$B$2 // must be an error? $result = $this->createTree($this->currentToken, '', ''); $this->advance(); return $result; } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) // must be an error? //$result = $this->currentToken; $result = $this->createTree($this->currentToken, '', ''); $this->advance(); return $result; } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) // must be an error? //$result = $this->currentToken; $result = $this->createTree($this->currentToken, '', ''); $this->advance(); return $result; } elseif (is_numeric($this->currentToken)) { // If it's a number or a percent if ($this->lookAhead == '%') { $result = $this->createTree('ptgPercent', $this->currentToken, ''); $this->advance(); // Skip the percentage operator once we've pre-built that tree } else { $result = $this->createTree($this->currentToken, '', ''); } $this->advance(); return $result; } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->currentToken)) { // if it's a function call $result = $this->func(); return $result; } throw new PHPExcel_Writer_Exception("Syntax error: ".$this->currentToken.", lookahead: ".$this->lookAhead.", current char: ".$this->currentCharacter); } /** * It parses a function call. It assumes the following rule: * Func -> ( Expr [,Expr]* ) * * @access private * @return mixed The parsed ptg'd tree on success */ private function func() { $num_args = 0; // number of arguments received $function = strtoupper($this->currentToken); $result = ''; // initialize result $this->advance(); $this->advance(); // eat the "(" while ($this->currentToken != ')') { /**/ if ($num_args > 0) { if ($this->currentToken == "," || $this->currentToken == ";") { $this->advance(); // eat the "," or ";" } else { throw new PHPExcel_Writer_Exception("Syntax error: comma expected in function $function, arg #{$num_args}"); } $result2 = $this->condition(); $result = $this->createTree('arg', $result, $result2); } else { // first argument $result2 = $this->condition(); $result = $this->createTree('arg', '', $result2); } ++$num_args; } if (!isset($this->functions[$function])) { throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); } $args = $this->functions[$function][1]; // If fixed number of args eg. TIME($i, $j, $k). Check that the number of args is valid. if (($args >= 0) and ($args != $num_args)) { throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); } $result = $this->createTree($function, $result, $num_args); $this->advance(); // eat the ")" return $result; } /** * Creates a tree. In fact an array which may have one or two arrays (sub-trees) * as elements. * * @access private * @param mixed $value The value of this node. * @param mixed $left The left array (sub-tree) or a final node. * @param mixed $right The right array (sub-tree) or a final node. * @return array A tree */ private function createTree($value, $left, $right) { return array('value' => $value, 'left' => $left, 'right' => $right); } /** * Builds a string containing the tree in reverse polish notation (What you * would use in a HP calculator stack). * The following tree: * * + * / \ * 2 3 * * produces: "23+" * * The following tree: * * + * / \ * 3 * * / \ * 6 A1 * * produces: "36A1*+" * * In fact all operands, functions, references, etc... are written as ptg's * * @access public * @param array $tree The optional tree to convert. * @return string The tree in reverse polish notation */ public function toReversePolish($tree = array()) { $polish = ""; // the string we are going to return if (empty($tree)) { // If it's the first call use parseTree $tree = $this->parseTree; } if (is_array($tree['left'])) { $converted_tree = $this->toReversePolish($tree['left']); $polish .= $converted_tree; } elseif ($tree['left'] != '') { // It's a final node $converted_tree = $this->convert($tree['left']); $polish .= $converted_tree; } if (is_array($tree['right'])) { $converted_tree = $this->toReversePolish($tree['right']); $polish .= $converted_tree; } elseif ($tree['right'] != '') { // It's a final node $converted_tree = $this->convert($tree['right']); $polish .= $converted_tree; } // if it's a function convert it here (so we can set it's arguments) if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/", $tree['value']) and !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/', $tree['value']) and !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/", $tree['value']) and !is_numeric($tree['value']) and !isset($this->ptg[$tree['value']])) { // left subtree for a function is always an array. if ($tree['left'] != '') { $left_tree = $this->toReversePolish($tree['left']); } else { $left_tree = ''; } // add it's left subtree and return. return $left_tree.$this->convertFunction($tree['value'], $tree['right']); } else { $converted_tree = $this->convert($tree['value']); } $polish .= $converted_tree; return $polish; } } PK!>$$CSV.phpnu[phpExcel = $phpExcel; } /** * Save PHPExcel to file * * @param string $pFilename * @throws PHPExcel_Writer_Exception */ public function save($pFilename = null) { // Fetch sheet $sheet = $this->phpExcel->getSheet($this->sheetIndex); $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog(); PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); // Open file $fileHandle = fopen($pFilename, 'wb+'); if ($fileHandle === false) { throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); } if ($this->excelCompatibility) { $this->setUseBOM(true); // Enforce UTF-8 BOM Header $this->setIncludeSeparatorLine(true); // Set separator line $this->setEnclosure('"'); // Set enclosure to " $this->setDelimiter(";"); // Set delimiter to a semi-colon $this->setLineEnding("\r\n"); } if ($this->useBOM) { // Write the UTF-8 BOM code if required fwrite($fileHandle, "\xEF\xBB\xBF"); } if ($this->includeSeparatorLine) { // Write the separator line if required fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding); } // Identify the range that we need to extract from the worksheet $maxCol = $sheet->getHighestDataColumn(); $maxRow = $sheet->getHighestDataRow(); // Write rows to file for ($row = 1; $row <= $maxRow; ++$row) { // Convert the row to an array... $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row, '', $this->preCalculateFormulas); // ... and write to the file $this->writeLine($fileHandle, $cellsArray[0]); } // Close file fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** * Get delimiter * * @return string */ public function getDelimiter() { return $this->delimiter; } /** * Set delimiter * * @param string $pValue Delimiter, defaults to , * @return PHPExcel_Writer_CSV */ public function setDelimiter($pValue = ',') { $this->delimiter = $pValue; return $this; } /** * Get enclosure * * @return string */ public function getEnclosure() { return $this->enclosure; } /** * Set enclosure * * @param string $pValue Enclosure, defaults to " * @return PHPExcel_Writer_CSV */ public function setEnclosure($pValue = '"') { if ($pValue == '') { $pValue = null; } $this->enclosure = $pValue; return $this; } /** * Get line ending * * @return string */ public function getLineEnding() { return $this->lineEnding; } /** * Set line ending * * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) * @return PHPExcel_Writer_CSV */ public function setLineEnding($pValue = PHP_EOL) { $this->lineEnding = $pValue; return $this; } /** * Get whether BOM should be used * * @return boolean */ public function getUseBOM() { return $this->useBOM; } /** * Set whether BOM should be used * * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false * @return PHPExcel_Writer_CSV */ public function setUseBOM($pValue = false) { $this->useBOM = $pValue; return $this; } /** * Get whether a separator line should be included * * @return boolean */ public function getIncludeSeparatorLine() { return $this->includeSeparatorLine; } /** * Set whether a separator line should be included as the first line of the file * * @param boolean $pValue Use separator line? Defaults to false * @return PHPExcel_Writer_CSV */ public function setIncludeSeparatorLine($pValue = false) { $this->includeSeparatorLine = $pValue; return $this; } /** * Get whether the file should be saved with full Excel Compatibility * * @return boolean */ public function getExcelCompatibility() { return $this->excelCompatibility; } /** * Set whether the file should be saved with full Excel Compatibility * * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file * Note that this overrides other settings such as useBOM, enclosure and delimiter * @return PHPExcel_Writer_CSV */ public function setExcelCompatibility($pValue = false) { $this->excelCompatibility = $pValue; return $this; } /** * Get sheet index * * @return int */ public function getSheetIndex() { return $this->sheetIndex; } /** * Set sheet index * * @param int $pValue Sheet index * @return PHPExcel_Writer_CSV */ public function setSheetIndex($pValue = 0) { $this->sheetIndex = $pValue; return $this; } /** * Write line to CSV file * * @param mixed $pFileHandle PHP filehandle * @param array $pValues Array containing values in a row * @throws PHPExcel_Writer_Exception */ private function writeLine($pFileHandle = null, $pValues = null) { if (is_array($pValues)) { // No leading delimiter $writeDelimiter = false; // Build the line $line = ''; foreach ($pValues as $element) { // Escape enclosures $element = str_replace($this->enclosure, $this->enclosure . $this->enclosure, $element); // Add delimiter if ($writeDelimiter) { $line .= $this->delimiter; } else { $writeDelimiter = true; } // Add enclosed string $line .= $this->enclosure . $element . $this->enclosure; } // Add line ending $line .= $this->lineEnding; // Write to file fwrite($pFileHandle, $line); } else { throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); } } } PK!OpenDocument.phpnu[setPHPExcel($pPHPExcel); $writerPartsArray = array( 'content' => 'PHPExcel_Writer_OpenDocument_Content', 'meta' => 'PHPExcel_Writer_OpenDocument_Meta', 'meta_inf' => 'PHPExcel_Writer_OpenDocument_MetaInf', 'mimetype' => 'PHPExcel_Writer_OpenDocument_Mimetype', 'settings' => 'PHPExcel_Writer_OpenDocument_Settings', 'styles' => 'PHPExcel_Writer_OpenDocument_Styles', 'thumbnails' => 'PHPExcel_Writer_OpenDocument_Thumbnails' ); foreach ($writerPartsArray as $writer => $class) { $this->writerParts[$writer] = new $class($this); } } /** * Get writer part * * @param string $pPartName Writer part name * @return PHPExcel_Writer_Excel2007_WriterPart */ public function getWriterPart($pPartName = '') { if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { return $this->writerParts[strtolower($pPartName)]; } else { return null; } } /** * Save PHPExcel to file * * @param string $pFilename * @throws PHPExcel_Writer_Exception */ public function save($pFilename = null) { if (!$this->spreadSheet) { throw new PHPExcel_Writer_Exception('PHPExcel object unassigned.'); } // garbage collect $this->spreadSheet->garbageCollect(); // If $pFilename is php://output or php://stdout, make it a temporary file... $originalFilename = $pFilename; if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); if ($pFilename == '') { $pFilename = $originalFilename; } } $objZip = $this->createZip($pFilename); $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest()); $objZip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail()); $objZip->addFromString('content.xml', $this->getWriterPart('content')->write()); $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->write()); $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->write()); $objZip->addFromString('settings.xml', $this->getWriterPart('settings')->write()); $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->write()); // Close file if ($objZip->close() === false) { throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); } // If a temporary file was used, copy it to the correct file stream if ($originalFilename != $pFilename) { if (copy($pFilename, $originalFilename) === false) { throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); } @unlink($pFilename); } } /** * Create zip object * * @param string $pFilename * @throws PHPExcel_Writer_Exception * @return ZipArchive */ private function createZip($pFilename) { // Create new ZIP file and open it for writing $zipClass = PHPExcel_Settings::getZipClass(); $objZip = new $zipClass(); // Retrieve OVERWRITE and CREATE constants from the instantiated zip class // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP $ro = new ReflectionObject($objZip); $zipOverWrite = $ro->getConstant('OVERWRITE'); $zipCreate = $ro->getConstant('CREATE'); if (file_exists($pFilename)) { unlink($pFilename); } // Try opening the ZIP file if ($objZip->open($pFilename, $zipOverWrite) !== true) { if ($objZip->open($pFilename, $zipCreate) !== true) { throw new PHPExcel_Writer_Exception("Could not open $pFilename for writing."); } } return $objZip; } /** * Get PHPExcel object * * @return PHPExcel * @throws PHPExcel_Writer_Exception */ public function getPHPExcel() { if ($this->spreadSheet !== null) { return $this->spreadSheet; } else { throw new PHPExcel_Writer_Exception('No PHPExcel assigned.'); } } /** * Set PHPExcel object * * @param PHPExcel $pPHPExcel PHPExcel object * @throws PHPExcel_Writer_Exception * @return PHPExcel_Writer_Excel2007 */ public function setPHPExcel(PHPExcel $pPHPExcel = null) { $this->spreadSheet = $pPHPExcel; return $this; } } PK!9 Abstract.phpnu[includeCharts; } /** * Set write charts in workbook * Set to true, to advise the Writer to include any charts that exist in the PHPExcel object. * Set to false (the default) to ignore charts. * * @param boolean $pValue * @return PHPExcel_Writer_IWriter */ public function setIncludeCharts($pValue = false) { $this->includeCharts = (boolean) $pValue; return $this; } /** * Get Pre-Calculate Formulas flag * If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, * so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet * viewer when opening the file * If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower * when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself * * @return boolean */ public function getPreCalculateFormulas() { return $this->preCalculateFormulas; } /** * Set Pre-Calculate Formulas * Set to true (the default) to advise the Writer to calculate all formulae on save * Set to false to prevent precalculation of formulae on save. * * @param boolean $pValue Pre-Calculate Formulas? * @return PHPExcel_Writer_IWriter */ public function setPreCalculateFormulas($pValue = true) { $this->preCalculateFormulas = (boolean) $pValue; return $this; } /** * Get use disk caching where possible? * * @return boolean */ public function getUseDiskCaching() { return $this->_useDiskCaching; } /** * Set use disk caching where possible? * * @param boolean $pValue * @param string $pDirectory Disk caching directory * @throws PHPExcel_Writer_Exception when directory does not exist * @return PHPExcel_Writer_Excel2007 */ public function setUseDiskCaching($pValue = false, $pDirectory = null) { $this->_useDiskCaching = $pValue; if ($pDirectory !== null) { if (is_dir($pDirectory)) { $this->_diskCachingDirectory = $pDirectory; } else { throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory"); } } return $this; } /** * Get disk caching directory * * @return string */ public function getDiskCachingDirectory() { return $this->_diskCachingDirectory; } } PK!b۴Rterminate-i.yamlnu[PK!ieB-cdesc-Writer.yamlnu[PK!j= new-c.yamlnu[PK! j"" create-c.yamlnu[PK!`Č;; %3c%3c-i.yamlnu[PK!ãuadd_row-i.yamlnu[PK!uu generate-c.yamlnu[PK!ֳ Q close-i.yamlnu[PK!q#{YP'P'6 Excel2007/Comments.phpnu[PK!yZ]]3Excel2007/Theme.phpnu[PK!O+Q\&\&lExcel2007/DocProps.phpnu[PK!CExcel2007/Worksheet.phpnu[PK!&!Excel2007/Chart.phpnu[PK!3h,,Excel2007/ContentTypes.phpnu[PK!򬵂>>Excel2007/Rels.phpnu[PK!q &Excel2007/RelsRibbon.phpnu[PK!]{E{E1Excel2007/Workbook.phpnu[PK!11wExcel2007/StringTable.phpnu[PK!}ƂZZExcel2007/Drawing.phpnu[PK!/ aΛmmExcel2007/Style.phpnu[PK!,vp]^rExcel2007/WriterPart.phpnu[PK!@: {Excel2007/RelsVBA.phpnu[PK! PDF.phpnu[PK! ==HTML.phpnu[PK! {PDF/mPDF.phpnu[PK!S / @PDF/tcPDF.phpnu[PK!  `PDF/DomPDF.phpnu[PK!cS6S6 PDF/Core.phpnu[PK!3CbDD :IWriter.phpnu[PK!@&ee Excel5.phpnu[PK!w   XException.phpnu[PK!?jUU Excel2007.phpnu[PK!#OpenDocument/Mimetype.phpnu[PK!z( OpenDocument/Settings.phpnu[PK!|F22HOpenDocument/Content.phpnu[PK!X/OpenDocument/MetaInf.phpnu[PK!F?T?OpenDocument/Thumbnails.phpnu[PK!a4TEOpenDocument/Meta.phpnu[PK!.m= bVOpenDocument/Cell/Comment.phpnu[PK!ʕ aOpenDocument/WriterPart.phpnu[PK!rBAAfOpenDocument/Styles.phpnu[PK!؃cII?{Excel5/Escher.phpnu[PK!31c Excel5/BIFFwriter.phpnu[PK!w:rr}Excel5/Worksheet.phpnu[PK!hhVX Excel5/Font.phpnu[PK!̿{$I$I i Excel5/Xf.phpnu[PK!ck^ Excel5/Workbook.phpnu[PK!- Excel5/Parser.phpnu[PK!>$$ CSV.phpnu[PK! OpenDocument.phpnu[PK!9 v Abstract.phpnu[PK33N
element because TCPDF // does not recognize e.g.
element because TCPDF // does not recognize e.g.