* .estilo_1 {color:red;}
*
*
*
* | 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;
}
}
?>