* .estilo_1 {color:red;} * * * * *
Titulo
* th1 * *
* * Si bien es un poco pesada la inclusión de thead y tbody, lo que hago para cumplir con la especificación * Son opcionales STYLE, THEAD y CAPTION. El sistema sólo reconoce clases, y todas las declaraciones * deben terminar con ';'. * Se puede determinar el ancho de las columnas utilizando style='width:x%' en los th, puediendo utilizar em, * px y %. * También se permite el uso de colspan, a discreción ;) * * Requiere: PEAR Spreadsheet_Excel, PEAR XML_Parser * @link http://pear.php.net * * Uso: * * $sXhtml="
"; * $sFile="nuevo.xls"; * $XHTML2Xls = &XHTML2Xls::get($sXhtml, $sFile); * $XHTML2Xls->create(); // Crea el archivo *
* @author Claudio Bustos * @copyrigth Prodem S.A., 2003 * @version 0.1 * @package XML * @subpackage XHTML2Xls * @see XHTML2Xls Implementación Dom del algoritmo, más clara pero menos eficiente. * @CVS $Id: XHTML2Xls_Expat.class.php,v 2.8 2004/10/27 19:16:17 Administrador Exp $ */ class XHTML2Xls_Expat extends XML_Parser { var $sData; var $x; var $y; var $sXhtml; var $oXls; var $sTag; var $iTablaId = 0; var $sTablaId = ""; var $aXlsFormats = array(); var $oHoja; var $aAttribs = array(); var $sFormatoFila = ""; var $aAnchosMaximos = array(); // function XHTML2Xls_Expat() { parent::XML_Parser(null, 'func'); } /** * Entrega un objeto XHTML2Xls_Expat * @param string código XHTML * @param string nombre del archivo .xls a grabar * @return XHTML2Xls_Expat */ function &get($sXhtml, $sFilename) { $XHTML2Xls = &new XHTML2Xls_Expat(); $XHTML2Xls->oXls = &new Spreadsheet_Excel_Writer($sFilename); $XHTML2Xls->sXhtml = $sXhtml; return $XHTML2Xls; } /** * Central parsing function. * Corrección: Debe utilizarse xml_set_object y xml_parser_free en la MISMA FUNCION. * * @throws XML_Parser_Error * @return boolean true on success * @see parseString() * @access public */ function create() { $this->setInputString($this->sXhtml); if (PEAR::isError($err = $this->parse())) { $sMensaje = $err->getMessage(); // Verifico si es un error'well-formed' if (strpos($sMensaje, 'not well-formed') !== FALSE) { preg_match("/line (\d.*)/", $sMensaje, $match); $iLinea = $match[1]-5; if ($iLinea<0) { $iLinea = 0; } $aXhtml = explode("\n", $this->sXhtml); $sTrozo = implode("
", array_slice($aXhtml, $iLinea, 10)); } else { $sTrozo = ""; } return PEAR::raiseError($sMensaje."
".htmlentities($sTrozo, ENT_NOQUOTES, 'UTF-8')); } else { $this->oXls->close(); return true; } } function xmltag_table($resource, $tag, $attribs) { $this->sTag = $tag; $this->x = 0; $this->y = 0; $this->iTablaId++; $sId = ((!empty($attribs["ID"])) ? $attribs["ID"] : "Tabla_".($this->iTablaId++)); $this->oHoja = &$this->oXls->addworksheet($sId); $this->aAnchosMaximos = array(); } function xmltag_table_($resource, $tag) { foreach($this->aAnchosMaximos as $iCol=>$iAncho) { if ($iAncho>50) { $iAncho = 50; } $this->oHoja->setColumn($iCol, $iCol, $iAncho); } } function xmltag_style($resource, $tag, $attribs) { $this->sData = ""; } function xmltag_style_($resource, $tag) { $sStyle = $this->sData; $aRules = $this->parseStyle($sStyle); foreach($aRules as $sSelector=>$aDeclarations) { if (!preg_match("/\.([A-Za-z0-9_]*)/", $sSelector, $sSelectorName)) { continue; } $sSelectorName = $sSelectorName[1]; $this->aXlsFormats[$sSelectorName] = &$this->oXls->addFormat(); $oTrans = new Css2XlsFormat(); // MAGIA NEGRA. Ja. $oTrans->process($this->aXlsFormats[$sSelectorName], $aDeclarations); } $this->sData = ""; } function xmltag_caption($resource, $tag, $attribs) { $this->sTag = $tag; $this->sData = ""; $this->aAttribs[$tag] = $attribs; } function xmltag_caption_($resource, $tag) { $sTitulo = trim($this->sData); $sClase = @$this->aAttribs["CAPTION"]["CLASS"]; $this->oHoja->write($this->x++, $this->y, $sTitulo, $this->getClase($sClase)); } function xmltag_th($resource, $tag, $attribs) { $this->sTag = $tag; $this->aAttribs[$tag] = $attribs; $this->sData = ""; } function xmltag_th_($resource, $tag) { $sTexto = trim($this->sData); $sClase = @$this->aAttribs["TH"]["CLASS"]; if ($aStyle = $this->parseDeclarations(@$this->aAttribs["TH"]["STYLE"])) { if ($iWidth = $this->getWidth($aStyle)) { $this->oHoja->setColumn($this->y, $this->y, $iWidth); } } $this->oHoja->write($this->x, $this->y++, $sTexto, $this->getClase($sClase)); } function cDataHandler($resource, $data) { $this->sData.= $data; } function xmltag_thead_($resource, $tag) { $this->x++; } function xmltag_tr($resource, $tag, $attribs) { $this->sTag = $tag; $this->aAttribs[$tag] = $attribs; $this->sData = ""; $this->sFormatoFila = @$attribs["CLASS"]; $this->y = 0; } function xmltag_tr_($resource, $tag) { $this->x++; } function xmltag_td($resource, $tag, $attribs) { $this->sTag = $tag; $this->aAttribs[$tag] = $attribs; $this->sData = ""; } function xmltag_td_($resource, $tag) { $sTexto = trim($this->sData); if (!array_key_exists($this->y, $this->aAnchosMaximos)) { $this->aAnchosMaximos[$this->y] = 0; } if ($this->aAnchosMaximos[$this->y]aAnchosMaximos[$this->y] = strlen($sTexto); } $sFormatoCol = @$this->aAttribs["TD"]["CLASS"]; $iColspan = @$this->aAttribs["TD"]["COLSPAN"]; if (!$iColspan) { $iColspan = 1; } if (!$sFormatoCol) { $sFormatoCol = $this->sFormatoFila; } $this->oHoja->write($this->x, $this->y, $sTexto, $this->getClase($sFormatoCol)); if ($iColspan>1) { $this->oHoja->mergeCells($this->x, $this->y, $this->x, $this->y+$iColspan-1); } $this->y+= $iColspan; } function getWidth($aStyle) { if ($aStyle["width"]) { preg_match("/(\d*)(%|em|px)/", $aStyle["width"], $aMatch); switch ($aMatch[2]) { case '%': $iWidth = (int)(100*($aMatch[1]/XLS_ANCHO_ESTANDAR)); break; case 'em': $iWidth = $aMatch[1]; break; case 'px': $iWidth = (int)($aMatch[1]/7); break; } return $iWidth; } else { return false; } } function &getClase($sClase) { if (isset($this->aXlsFormats[$sClase])) { return $this->aXlsFormats[$sClase]; } else { return false; } } function parseStyle($sStyle) { if (!$sStyle) { return false; } $aOut = array(); preg_match_all("/\s*?(.*?)\s*?\{(.*?)\}/smi", $sStyle, $aRules, PREG_SET_ORDER); foreach($aRules as $aRule) { $sSelector = trim($aRule[1]); $sDeclarations = trim($aRule[2]); $aOut[$sSelector] = $this->parseDeclarations($sDeclarations); } return $aOut; } function parseDeclarations($sDeclarations) { if (substr(trim($sDeclarations) , -1) != ";") { $sDeclarations = trim($sDeclarations) .";"; } preg_match_all("/\s*(.*?)\s*:\s*(.*?)\s*;/", $sDeclarations, $aDeclarations, PREG_SET_ORDER); $aOut = array(); foreach($aDeclarations as $aDeclaration) { $sDeclarationName = $aDeclaration[1]; $sDeclarationValue = $aDeclaration[2]; $aOut[$sDeclarationName] = $sDeclarationValue; } return $aOut; } } ?>