styles = array(); $this->fonts = array(); $this->sheets = array(); $this->currentRow = 0; $this->currentSheet = 0; $this->currentCell = 0; $this->repeat = 0; } function parse($data) { $xml_parser = xml_parser_create(); xml_set_object ( $xml_parser, $this ); xml_set_element_handler($xml_parser, "startElement", "endElement"); xml_set_character_data_handler($xml_parser, "characterData"); xml_parse($xml_parser, $data, strlen($data)); xml_parser_free($xml_parser); } function array2ods() { $fontArray = $this->fonts; $styleArray = $this->styles; $sheetArray = $this->sheets; // Header $string = ''; // ToDo: scripts $string .= ''; // Fonts $string .= ''; foreach ($fontArray as $fontName => $fontAttribs) { $string .= ' $attrValue) { $string .= strtolower($attrName) . '="' . $attrValue . '" '; } $string .= '/>'; } $string .= ''; // Styles $string .= ''; foreach ($styleArray as $styleName => $styleAttribs) { $string .= ' $attrValue) { $string .= strtolower($attrName) . '="' . $attrValue . '" '; } $string .= '>'; // Subnodes foreach ($styleAttribs['styles'] as $nodeName => $nodeTree) { $string .= '<' . $nodeName . ' '; foreach ($nodeTree as $attrName => $attrValue) { $string .= strtolower($attrName) . '="' . $attrValue . '" '; } $string .= '/>'; } $string .= ''; } $string .= ''; // Body $string .= ''; $string .= ''; foreach ($sheetArray as $tableIndex => $tableContent) { $string .= ''; //$string .= ''; foreach ($tableContent['rows'] as $rowIndex => $rowContent) { $string .= ''; foreach($rowContent as $cellIndex => $cellContent) { $string .= ' $attrValue) { $string .= strtolower($attrName) . '="' . $attrValue . '" '; } $string .= '>'; if (isset($cellContent['value'])) { $string .= '' . $cellContent['value'] . ''; } $string .= ''; } $string .= ''; } $string .= ''; } $string .= ''; $string .= ''; // Footer $string .= ''; return $string; } function startElement($parser, $tagName, $attrs) { $cTagName = strtolower($tagName); if($cTagName == 'style:font-face') { $this->fonts[$attrs['STYLE:NAME']] = $attrs; } elseif($cTagName == 'style:style') { $this->lastElement = $attrs['STYLE:NAME']; $this->styles[$this->lastElement]['attrs'] = $attrs; } elseif($cTagName == 'style:table-column-properties' || $cTagName == 'style:table-row-properties' || $cTagName == 'style:table-properties' || $cTagName == 'style:text-properties') { $this->styles[$this->lastElement]['styles'][$cTagName] = $attrs; } elseif($cTagName == 'table:table-cell') { $this->lastElement = $cTagName; $this->sheets[$this->currentSheet]['rows'][$this->currentRow][$this->currentCell]['attrs'] = $attrs; if(isset($attrs['TABLE:NUMBER-COLUMNS-REPEATED'])) { $times = intval($attrs['TABLE:NUMBER-COLUMNS-REPEATED']); $times--; for($i=1;$i<=$times;$i++) { $cnum = $this->currentCell+$i; $this->sheets[$this->currentSheet]['rows'][$this->currentRow][$cnum]['attrs'] = $attrs; } $this->currentCell += $times; $this->repeat = $times; } if(isset($this->lastRowAtt['TABLE:NUMBER-ROWS-REPEATED'])) { $times = intval($this->lastRowAtt['TABLE:NUMBER-ROWS-REPEATED']); $times--; for($i=1;$i<=$times;$i++) { $cnum = $this->currentRow+$i; $this->sheets[$this->currentSheet]['rows'][$cnum][$i-1]['attrs'] = $attrs; } $this->currentRow += $times; } } elseif($cTagName == 'table:table-row') { $this->lastRowAtt = $attrs; } } function endElement($parser, $tagName) { $cTagName = strtolower($tagName); if($cTagName == 'table:table') { $this->currentSheet++; $this->currentRow = 0; } elseif($cTagName == 'table:table-row') { $this->currentRow++; $this->currentCell = 0; } elseif($cTagName == 'table:table-cell') { $this->currentCell++; $this->repeat = 0; } } function characterData($parser, $data) { if($this->lastElement == 'table:table-cell') { $this->sheets[$this->currentSheet]['rows'][$this->currentRow][$this->currentCell]['value'] = $data; if($this->repeat > 0) { for($i=0;$i<$this->repeat;$i++) { $cnum = $this->currentCell - ($i+1); $this->sheets[$this->currentSheet]['rows'][$this->currentRow][$cnum]['value'] = $data; } } } } function getMeta($lang) { $myDate = date('Y-m-j\TH:i:s'); $meta = ' ods-php '.$myDate.' '.$myDate.' '.$lang.' 2 PT15S '; return $meta; } function getStyle() { return ' - ???Página 1??? (???)18/02/2008, 00:17:06Página 1 / 99'; } function getSettings() { return ' 002258903View101000020000Hoja1270010060falsetruetruetrue12632256truetruetruetruefalsefalse100010001 1truetruetruetrue12632256true3truetruetruefalsefalse1000100011truetrueGeneric PrinterWAH+/0dlbmVyaWMgUHJpbnRlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU0dFTlBSVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAMAngAAAAAAAAAFAFZUAAAkbQAASm9iRGF0YSAxCnByaW50ZXI9R2VuZXJpYyBQcmludGVyCm9yaWVudGF0aW9uPVBvcnRyYWl0CmNvcGllcz0xCm1hcmdpbmRhanVzdG1lbnQ9MCwwLDAsMApjb2xvcmRlcHRoPTI0CnBzbGV2ZWw9MApjb2xvcmRldmljZT0wClBQRENvbnRleERhdGEKUGFnZVNpemU6TGV0dGVyAAA=true0falsefalsefalsetruefalse'; } function getManifest() { return ' '; } function addCell($sheet,$row,$cell,$value,$type) { $this->sheets[$sheet]['rows'][$row][$cell]['attrs'] = array('OFFICE:VALUE-TYPE'=>$type,'OFFICE:VALUE'=>$value); $this->sheets[$sheet]['rows'][$row][$cell]['value'] = $value; } function editCell($sheet,$row,$cell,$value) { $this->sheets[$sheet]['rows'][$row][$cell]['attrs']['OFFICE:VALUE'] = $value; $this->sheets[$sheet]['rows'][$row][$cell]['value'] = $value; } function output() { $name = 'doc.ods'; $tmp = get_tmp_dir(); $uid = uniqid(); mkdir($tmp.'/'.$uid); $path = $tmp.'/'.$uid.'/'.basename('temp.ods'); saveOds($this, $path); if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) { header('Content-Type: application/force-download'); } else { header('Content-Type: application/octet-stream'); } $buffer = file_get_contents($path); header('Content-Length: '.strlen($buffer)); header('Content-disposition: attachment; filename="'.$name.'"'); echo $buffer; unlink($path); rmdir($tmp.'/'.$uid); } } function parseOds($file) { $tmp = get_tmp_dir(); copy($file,$tmp.'/'.basename($file)); $path = $tmp.'/'.basename($file); $uid = uniqid(); mkdir($tmp.'/'.$uid); #shell_exec('unzip '.escapeshellarg($path).' -d '.escapeshellarg($tmp.'/'.$uid)); unzip(escapeshellarg($path), escapeshellarg($tmp.'/'.$uid)); $obj = new ods(); $obj->parse(file_get_contents($tmp.'/'.$uid.'/content.xml')); return $obj; } function unzip($fln, $path) { $zip = zip_open($fln); if ($zip) { while ($zip_entry = zip_read($zip)) { if (zip_entry_filesize($zip_entry) > 0) { // str_replace must be used under windows to convert "/" into "\" $complete_path = $path.str_replace('/','\\',dirname(zip_entry_name($zip_entry))); $complete_name = $path.str_replace ('/','\\',zip_entry_name($zip_entry)); if(!file_exists($complete_path)) { $tmp = ''; foreach(explode('\\',$complete_path) AS $k) { $tmp .= $k.'\\'; if(!file_exists($tmp)) { mkdir($tmp, 0777); } } } if (zip_entry_open($zip, $zip_entry, "r")) { $fd = fopen($complete_name, 'w'); fwrite($fd, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry))); fclose($fd); zip_entry_close($zip_entry); } } } zip_close($zip); } } function remove_directory($dir) { if ($handle = opendir("$dir")) { while (false !== ($item = readdir($handle))) { if ($item != "." && $item != "..") { if (is_dir("$dir/$item")) { remove_directory("$dir/$item"); } else { unlink("$dir/$item"); } } } closedir($handle); rmdir($dir); } } function saveOds($obj,$file) { $charset = ini_get('default_charset'); ini_set('default_charset', 'UTF-8'); $tmp = get_tmp_dir(); $uid = uniqid(); mkdir($tmp.'/'.$uid); file_put_contents($tmp.'/'.$uid.'/content.xml',$obj->array2ods()); file_put_contents($tmp.'/'.$uid.'/mimetype','application/vnd.oasis.opendocument.spreadsheet'); file_put_contents($tmp.'/'.$uid.'/meta.xml',$obj->getMeta('pt-BR')); file_put_contents($tmp.'/'.$uid.'/styles.xml',$obj->getStyle()); file_put_contents($tmp.'/'.$uid.'/settings.xml',$obj->getSettings()); mkdir($tmp.'/'.$uid.'/META-INF/'); mkdir($tmp.'/'.$uid.'/Configurations2/'); mkdir($tmp.'/'.$uid.'/Configurations2/acceleator/'); mkdir($tmp.'/'.$uid.'/Configurations2/images/'); mkdir($tmp.'/'.$uid.'/Configurations2/popupmenu/'); mkdir($tmp.'/'.$uid.'/Configurations2/statusbar/'); mkdir($tmp.'/'.$uid.'/Configurations2/floater/'); mkdir($tmp.'/'.$uid.'/Configurations2/menubar/'); mkdir($tmp.'/'.$uid.'/Configurations2/progressbar/'); mkdir($tmp.'/'.$uid.'/Configurations2/toolbar/'); file_put_contents($tmp.'/'.$uid.'/META-INF/manifest.xml',$obj->getManifest()); $ziper = new zipfile(); $ziper->addFiles($tmp.'/'.$uid, array('META-INF', 'Configurations2', 'content.xml', 'meta.xml', 'mimetype', 'settings.xml', 'styles.xml')); $ziper->output($file); remove_directory($tmp.'/'.$uid); ini_set('default_charset',$charset); } function newOds() { $content = ' '; $obj = new ods(); $obj->parse($content); return $obj; } function get_tmp_dir() { $path = ''; if(!function_exists('sys_get_temp_dir')){ $path = try_get_temp_dir(); }else{ $path = sys_get_temp_dir(); if(is_dir($path)){ return $path; }else{ $path = try_get_temp_dir(); } } return $path; } function try_get_temp_dir() { // Try to get from environment variable if(!empty($_ENV['TMP'])){ $path = realpath($_ENV['TMP']); }else if(!empty($_ENV['TMPDIR'])){ $path = realpath( $_ENV['TMPDIR'] ); }else if(!empty($_ENV['TEMP'])){ $path = realpath($_ENV['TEMP']); } // Detect by creating a temporary file else{ // Try to use system's temporary directory // as random name shouldn't exist $temp_file = tempnam(md5(uniqid(rand(),TRUE)),''); if ($temp_file){ $temp_dir = realpath(dirname($temp_file)); unlink($temp_file); $path = $temp_dir; }else{ return "/tmp"; } } return $path; } ?>