tfeserver: Blog de tfe

html, scripts et tout un tas de trucs...

Download

Contenu du fichier de /php-excel-xml/class.php-excel-xml.php (télécharger class.php-excel-xml.php)
<?php

/* 
	==========================================================================
	 Clase para generar fichero XML Excel
	==========================================================================

 */


/**
 * Generate excel/openoffice xml files
 * @package php-excel-xml
 */
class Excel
{
	private $_lines= Array();
	private $_maxcols= 255;
	private $_globalMargin= 1;
	private $_csv= false;
	private $_pagetitle= "Page";
	private $_container_abierto = false;

	/* Constructor */
	public function __construct($p_cols)
	{
		$this->_maxcols=$p_cols;
	}
	
	/* Set title page of the doc */
	public function set_title_pagina($p_title)
	{
		$this->_pagetitle= $p_title;
	}

	/* If you want a csv file instead xml file */
	public function setCsv()
	{
		$this->_csv=true;
	}

	/* Add row to document */
	public function add_lines($p_datos, $p_opciones)
	{
		$v_datos_linea  = $p_opciones;
		$v_datos_linea["DATOS"] = Array();

		/* Margin-top: Empty lines */
		if(isset($p_opciones["MARGIN-TOP"]))
		{
			$v_estilo = $this->_container_abierto ? "celdavaciacontainer" : "celdavacia";
			for($i=0; $i<$p_opciones["MARGIN-TOP"];$i++)
			{
				$this->_lines[] = Array("STYLE" => $v_estilo, "MERGE" => true, "DATOS" => Array(Array("DATA"=> "", "STYLE" => $v_estilo)));
			}
		}
		$v_current_left = 0;
		/* Margin-left: celdas vacias antes de empezar las líneas */
		if(isset($p_opciones["MARGIN-LEFT"]))
		{
			$v_current_left= $p_opciones["MARGIN-LEFT"];
			$v_estilo = $this->_container_abierto ? "celdaizquierda" : "";
			$v_datos_linea["DATOS"][] = Array("DATA" => "", "STYLE" => $v_estilo);
			for($i=1; $i<$p_opciones["MARGIN-LEFT"];$i++)
			{
				$v_datos_linea["DATOS"][] = Array("DATA" => "", "STYLE" => "Generico");
			}
		}
		$v_add_full_cols = !isset($p_opciones["MERGE"]) || !$p_opciones["MERGE"];

		foreach($p_datos as $dato)
		{
			$v_current_left++;
			$v_datos_linea["DATOS"][] = Array("DATA" => $dato, "STYLE" => $p_opciones["STYLE"]);
		}
		if($v_add_full_cols)
		{
			$v_estilo = $this->_container_abierto ? "container" : "Generico";
			for($i=$v_current_left; $i<$this->_maxcols;$i++)
			{
				$v_datos_linea["DATOS"][] = Array("DATA" => "", "STYLE" => $v_estilo);
			}

			$v_estilo = $this->_container_abierto ? "celdaderecha" : "";
			$v_datos_linea["DATOS"][] = Array("DATA" => "", "STYLE" => $v_estilo);
		}

		$this->_lines[] = $v_datos_linea;

		/* Margin-right: empty cells after data */
		if(isset($p_opciones["MARGIN-BOTTOM"]))
		{
			for($i=0; $i<$p_opciones["MARGIN-BOTTOM"];$i++)
			{
				$this->_lines[] = Array("STYLE" => "Generico", "DATOS" => Array(Array("DATA"=> "")));
			}
		}
		return true;
	}

	/* add an empty line */
	public function add_line_row($p_line)
	{
		$this->_lines[] =$p_line;
	}

	/* Add a title line */
	public function add_title($p_title)
	{
		return $this->add_lines(Array($p_title), Array("STYLE" => "title", "MERGE" => true, "MARGIN-BOTTOM" => 2));
	}

	/* Add a subtitle line */
	public function add_subtitle($p_subtitle)
	{
		return $this->add_lines(Array($p_subtitle), Array("STYLE" => "subtitle", "MERGE" => true, "MARGIN-TOP" => 1));
	}

	/* Add a text line */
	public function add_texto($p_texto)
	{
		return $this->add_lines(Array($p_texto), Array("STYLE" => "texto", "MERGE" => true, "MARGIN-TOP" => 2));
	}

	/* add a header line */
	public function add_header($p_celdas)
	{
		return $this->add_lines($p_celdas, Array("STYLE" => "cabecera", "MARGIN-TOP" => 1, "MARGIN-LEFT" => 1));
	}

	/* Add a cell */
	public function add_line($p_celdas)
	{
		return $this->add_lines($p_celdas, Array("STYLE" => "celda",  "MARGIN-LEFT" => 1));
	}

	/* Open container */
	public function open_container($p_subtitle)
	{
		$this->_container_abierto = true;
		return $this->add_lines(Array($p_subtitle), Array("STYLE" => "startcontainer", "MERGE" => true, "MARGIN-TOP" => 0));
	}

	/* Close container */
	public function close_container()
	{
		if($this->_container_abierto)
		{
			$this->_container_abierto = false;
			return $this->add_lines(Array(""), Array( "MERGE" => true,"STYLE" => "endcontainer", "MARGIN-BOTTOM" => 1));
		}
		return false;
	}

	/* Protect csv data */
	public function protect_csv($p_string)
	{
		return '"'.str_replace('"','""',utf8_decode($p_string)).'"';
	}

	/* Display document */
	public function output()
	{
		header("Cache-Control: public");
		header("Content-Description: File Transfer");
		header("Content-Transfer-Encoding: binary");

		return $this->_csv ? $this->csv() : $this->xml();
	}

	/* Display as CSV */
	public function csv()
	{
		header('Content-disposition: attachment; filename=file.csv');
		header("Content-Type:  application/vnd.ms-excel; charset=utf-8");

		$v_csv= Array();
		foreach($this->_lines as $v_line)
		{
			if(count($v_line["DATOS"])>0)
			{
				$v_temp_array = Array();
				if(isset($v_line["MARGIN-LEFT"]))
				{
					for($i=0;$i<$v_line["MARGIN-LEFT"]; $i++)
					{
						$v_temp_array[] = "";
					}
				}
				foreach($v_line["DATOS"] as $v_dato)
				{
					$v_temp_array[] = $this->protect_csv($v_dato["DATA"]);
				}
				$v_csv[]=  join(";",$v_temp_array);
			}
		}
		echo join("\n",$v_csv);
		return true;
	}

	/* Display as XML */
	public function xml()
	{
		header('Content-disposition: attachment; filename=file.xml');
		header("Content-Type:  text/xml");

		$v_header= <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">


EOF;

		$v_num_lines = count($this->_lines);
		$v_maxcols = $this->_maxcols+1+ $this->_globalMargin;
		$v_title = htmlspecialchars($this->_pagetitle);
		$v_default_bg = "#ffffff";
		$v_bg_container = "#eeeeee";

		$v_estilos = <<<EOF
		<Styles>
		<Style ss:ID="Default" ss:Name="Default">
			<Interior ss:Color="#ffffff" ss:Pattern="Solid"/>
		</Style>

		<Style ss:ID="Generico" ss:Name="Generico">
			<Interior ss:Color="$v_default_bg" ss:Pattern="Solid"/>
		</Style>
		<Style ss:ID="container" ss:Name="container">
			<Interior ss:Color="$v_bg_container" ss:Pattern="Solid"/>
		</Style>

		<Style ss:ID="startcontainer" ss:Name="startcontainer">
			<!--<Font ss:Bold="0" ss:Italic="0" ss:Size="12" ss:Underline="Single" ss:Color="#0099cb"/>!-->
			<Font ss:Bold="0" ss:Italic="0" ss:Size="12" ss:Color="#ffffff"/>
			<!--<Interior ss:Color="$v_bg_container" ss:Pattern="Solid"/>!-->
			<Interior ss:Color="#777777" ss:Pattern="Solid"/>
			<Borders>
				<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>

		<Style ss:ID="endcontainer" ss:Name="endcontainer">
			<Borders>
				<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
			<Interior ss:Color="$v_bg_container" ss:Pattern="Solid"/>
		</Style>


		<Style ss:ID="title">
			<Alignment ss:Horizontal="Center" ss:Vertical="Center" />
			<Font ss:Bold="1" ss:Italic="0" ss:Size="20" ss:Color="#000000"/>
			<Interior ss:Color="#ffffff" ss:Pattern="Solid"/>
			<Borders>
				<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>

		<Style ss:ID="subtitle" ss:Parent="container">
			<Font ss:Bold="0" ss:Italic="0" ss:Size="12" ss:Underline="Single" ss:Color="#000000"/>
			<Interior ss:Color="$v_bg_container" ss:Pattern="Solid"/>
			<Borders>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>

		<Style ss:ID="texto" ss:Parent="container">
  			<Alignment ss:Horizontal="Left" ss:Vertical="Center" ss:Indent="2"/>
			<Font ss:Bold="0" ss:Italic="0" ss:Size="10"/>
			<Interior  ss:Pattern="Solid"/>
			<Borders>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>

		<Style ss:ID="cabecera">
			<Font ss:Bold="1" ss:Italic="0" ss:Size="10" ss:Color="#ffffff"/>
			<Alignment ss:Horizontal="Center" ss:Vertical="Center" />
			<Borders>
				<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
			<Interior ss:Color="#303030" ss:Pattern="Solid"/>
		</Style>

		<Style ss:ID="celda">
			<Font ss:Bold="0" ss:Italic="0" ss:Size="10" ss:Color="#000000"/>
			<Borders>
				<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
			<Interior ss:Color="#ffffff" ss:Pattern="Solid"/>
		</Style>

		<Style ss:ID="celdavacia" />
		<Style ss:ID="celdavaciacontainer" ss:Parent="container">
			<Borders>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>

		<Style ss:ID="celdaizquierda" ss:Parent="container">
			<Borders>
				<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>
		<Style ss:ID="celdaderecha" ss:Parent="container">
			<Borders>
				<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#000000"/>
			</Borders>
		</Style>

	</Styles>
	<Worksheet ss:Name="{$v_title}">
	  <Names>
	   <NamedRange ss:Name="Print_Area" ss:RefersTo="='mi encuesta'!C2:C$v_maxcols"/>
	  </Names>
	 <Table ss:ExpandedColumnCount="{$v_maxcols}" ss:ExpandedRowCount="$v_num_lines" x:FullColumns="1"
		 x:FullRows="1" ss:DefaultColumnWidth="60" ss:DefaultRowHeight="15">

EOF;

		$v_xml_doc = $v_header;
		$v_xml_doc.=$v_estilos;

		/* Bucle sobre las líneas del documento */
		foreach($this->_lines as $v_line)
		{
			/* Si tienen datos */
			if(count($v_line["DATOS"])>0)
			{
				$v_merged = isset($v_line["MERGE"]) && $v_line["MERGE"];
				$v_parametro_cell = "";
				if($v_merged)
				{
					$v_parametro_cell = " ss:MergeAcross=\"".$this->_maxcols."\"";
				}
				$v_xml_doc.="\n
					";

				/* Si de de tipo título, se especifica un ancho de columna y se hace un rowspan */
				if($v_line["STYLE"]=="title")
				{
					$v_xml_doc.= '<Row ss:AutoFitHeight="0" ss:Height="30.4079">';
				}

				/* Si de de tipo subtítulo, se especifica un ancho de columna y se hace un rowspan */
				elseif($v_line["STYLE"]=="subtitle")
				{
					$v_xml_doc.= '<Row ss:AutoFitHeight="0" ss:Height="20.4079">';
				}

				/* Si de de tipo texto, se especifica un ancho de columna y se hace un rowspan */
				elseif($v_line["STYLE"]=="texto")
				{
					$v_xml_doc.= '<Row ss:AutoFitHeight="0" ss:Height="18.4079">';
				}
				/* Si de de tipo container, se especifica un ancho de columna y se hace un rowspan */
				elseif($v_line["STYLE"]=="startcontainer" || $v_line["STYLE"]=="endcontainer")
				{
					$v_xml_doc.= '<Row ss:AutoFitHeight="0" ss:Height="18.4079">';
				}

				/* Si es una celda, se especifíca el ancho */
				else
				{
					$v_xml_doc.= '<Row ss:AutoFitHeight="0" ss:Height="13.4079">';
				}
				$v_xml_doc.="\n
					";

				for($i=0;$i<$this->_globalMargin;$i++)
				{
					$v_xml_doc.="<Cell ssName=\"Print_Area\"><Data ss:Type=\"String\"></Data></Cell>\n";
				}
				/* Bucle sobre cada celda */
				foreach($v_line["DATOS"] as $v_dato)
				{
					$v_parametro_cell_addi = "";
					$v_type="String";
					/* Si es de tipo númerico, se lo decimos */
					if(ctype_digit($v_dato))
					{
						$v_type="Number";
					}
					else
					{
						$v_dato["DATA"] = htmlspecialchars($v_dato["DATA"]);
					}
					$v_style="";

					/* si no tiene estilo */
					if(empty($v_dato["STYLE"]))
					{
						$v_dato["STYLE"]="Generico";
					}
					$v_style= " ss:StyleID=\"{$v_dato["STYLE"]}\"";

					/* añadimos la celda al documento */
					$v_xml_doc.= '<Cell ssName="Print_Area"'.$v_parametro_cell.$v_parametro_cell_addi.$v_style.'><Data ss:Type="'.$v_type.'">'.$v_dato["DATA"].'</Data></Cell>'."\n";
				}
				if(!$v_merged)
				{
					/* Añadimos las celdas vacias */
					for($i=count($v_line["DATOS"]); $i<=$this->_maxcols;$i++)
					{
						$v_xml_doc.= '<Cell ssName="Print_Area" ss:StyleID="Generico"><Data ss:Type="String"></Data></Cell>'."\n";
					}
				}
				$v_xml_doc.= '
					</Row>
					';
			}
		}

		// Final del documento
		$v_xml_doc.= <<<EOF
		</Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <Unsynced/>
   <FitToPage/>
   <Print>
    <FitHeight>0</FitHeight>
    <ValidPrinterInfo/>
    <PaperSizeIndex>9</PaperSizeIndex>
    <Scale>68</Scale>
    <HorizontalResolution>600</HorizontalResolution>
    <VerticalResolution>600</VerticalResolution>
    <NumberofCopies>0</NumberofCopies>
   </Print>
</WorksheetOptions>

<x:WorksheetOptions/>
	</Worksheet>
</Workbook>
EOF;
		// Replace \r\n
		echo preg_replace("/[\r\n]+/","\n",$v_xml_doc);
	}

}