Location: PHPKode > scripts > OpenOffice Spreadsheet Generation > calc/classes/Content.class.php
<?php

require_once ('XMLDocument.abstract.php');
require_once ('Fonction.class.php');
require_once ('Table.class.php');

/**
 * OpenOfficeSpreadsheet est un ensemble de classes permettant de générer un document OpenOffice
 * Spreadsheet (feuille de calcul ou tableur). Ces classes contiennent un certain nombre de
 * fonctions permettant la mise en page et le remplissage de cellules. Euh, sinon c'est tout.
 * Mais il y a de quoi faire, notamment au niveau des classes Settings et Styles, mais ça
 * viendra (peut-être) plus tard.
 *
 * Sinon, c'est gratuit, c'est sympa, et même si ça ne sert pas à grand chose, ça sert quand
 * même à quelque chose. Donc finalement, c'est cool. Alors enjoy!
 *
 * @package		OpenOfficeGeneration
 * @version		0.1
 * @copyright	(C) 2006 Tafel. All rights reserved
 * @license		http://www.gnu.org/copyleft/lesser.html LGPL License
 * @author		Tafel <hide@address.com>
 *
 * Programme sous licence GPL. Toute reproduction, même patielle, est autorisée, avec ou sans le
 * consentement du programmeur principal (avec, c'est mieux, quand même ;) ...)
 */
class Content extends XMLDocument {
	
	/**
	 *-------------------------------------------------------------------------------
	 * Propriétés
	 *-------------------------------------------------------------------------------
	 */	
	
	/**
	 * @access 	protected
	 * @var 	array			$sheets					Les feuilles du document
	 */
	protected $sheets;
	
	
	/**
	 *-------------------------------------------------------------------------------
	 * Constructeur
	 *-------------------------------------------------------------------------------
	 */	
	
	/**
	 * Constructeur de classe
	 *
	 * @access 	public
	 * @param 	string			$path_save				Le chemin vers le dossier de sauvegarde
	 * @param 	string			$path_templates			Le chemin vers les templates
	 * @param 	boolean			$format_output			True pour un affichage joli du XML
	 * @param 	boolean			$white_space			True pour préserver les espaces blancs
	 * @return 	object									L'objet de classe
	 */
	public function __construct($path_save, $path_templates, $format_output, $white_space) {
		try {
			$fileName = 'content.xml';
			$this->load($fileName, $path_save, $path_templates, $format_output, $white_space);
			$this->root = $this->core->documentElement;
			$this->sheets = array();
		} catch (Exception $e) {
			throw $e;	
		}
	}	
	
	
	/**
	 *-------------------------------------------------------------------------------
	 * Méthodes publiques
	 *-------------------------------------------------------------------------------
	 */
	
	/**
	 * Fonction qui créé une nouvelle feuille
	 *
	 * @access 	public
	 * @param 	string			$sheet					Le nom de la feuille
	 * @return 	object									L'objet Sheet
	 */
	public function addSheet($sheet) {
		try {
			$obj = new Table($sheet, $this->core, $this->xpath);
			$this->sheets[] = $obj;
			return $obj;
		} catch (Exception $e) {
			throw $e;	
		}
	}
	
	/**
	 * Fonction qui retourne un tableau contenant les feuilles portant le nom voulu
	 *
	 * Si aucune feuille n'est trouvée, retourne un tableau vide
	 *
	 * @access 	public
	 * @param 	string			$sheet					Le nom de la feuille cherchée
	 * @param 	boolean			$solo_no_array			True pour retourner directement l'objet s'il n'y a qu'une feuille
	 * @return 	array									Le tableau d'objets Sheet
	 */
	public function getSheetsByName($name, $solo_no_array = false) {
		$tab = array();
		foreach ($this->sheets as $sheet) {
			if ($sheet->getName() == $name)
				$tab[] = $sheet;
		}
		if ($solo_no_array) {
			if (count($tab) == 1)
				return $tab[0];
		}
		return $tab;
	}
	
	/**
	 * Fonction qui retourne la feuille de l'index spécifié. La 1ère feuille a l'index 0
	 *
	 * @access 	public
	 * @param 	integer			$index					La position de la feuille
	 * @return 	object									L'objet Sheet
	 */
	public function getSheetByIndex($index) {
		return (isset($this->sheet[$index])) ? $this->sheet[$index] : false;
	}
	
	
	/**
	 *-------------------------------------------------------------------------------
	 * Redéfinition de méthodes
	 *-------------------------------------------------------------------------------
	 */
	
	/**
	 * Fonction qui est appelée juste avant de sauvegarder le fichier XML
	 *
	 * @access 	protected
	 * @return 	boolean									Doit retourner true pour faire la sauvegarde
	 */
	protected function _beforeSave() {
		$styles = array(
			'col' => array(), 'colused' => array(),
			'row' => array(), 'rowused' => array(),
			'cel' => array(), 'celused' => array(),
			'tab' => array(), 'tabused' => array()
		);
		$sheetsCols = array();
		$fonts = array();
		$maxCol = 0;
		$colDef = 'co1';
		// 1er parsage, récupération des styles, nb de lignes max et nb de colonnes max
		foreach ($this->sheets as $key => $sheet){
			$cells = $sheet->getCells();
			$cols = array();
			foreach ($cells as $row => $obj) {
				foreach ($obj as $col => $cell) {
					$used = $this->_getUsedCellStyles($cell, $styles);
					$cell->setStyleName($used);
					$fonts[] = $cell->getFontFamily();
					if (!isset($cols[$col]) || $cols[$col] == '' || ($used['col'] != $colDef))
						$cols[$col] = $used['col'];
				}
			}
			if ($maxCol < $sheet->getNbColsMax()) {
				$maxCol = $sheet->getNbColsMax();
			}
			$sheetsCols[$key] = Fonction::array_count_followed_values($cols, $colDef, $maxCol);
		}
		$this->_insertFontFamilies($fonts);
		$this->_insertStyles($styles);
		// 2e parsage, insertion des cellules
		foreach ($this->sheets as $key => $sheet){
			$cells = $sheet->getCells();
			foreach ($sheetsCols[$key] as $col) {
				$tbCol = $this->_addTableElement('table-column', null, $sheet->getXML());
				$tbCol->setAttribute('table:style-name', $col['value']);
				if ($col['nb'] > 1)
					$tbCol->setAttribute('table:number-columns-repeated', $col['nb']);
			}
			$rowCourant = 0;
			ksort($cells);
			foreach ($cells as $row => $obj) {
				ksort($obj);
				$cell = current($obj);
				$st = $cell->getStyleName();
				if ($rowCourant < $row - 1) {
					$tbRow = $this->_addTableElement('table-row', null, $sheet->getXML());
					$tbRow->setAttribute('table:number-rows-repeated', ($row - $rowCourant - 1));
					$tbCell = $this->_addTableElement('table-cell', null, $tbRow);
					$tbCell->setAttribute('table:style-name', 'ce1');
				}
				$tbRow = $this->_addTableElement('table-row', null, $sheet->getXML());
				$tbRow->setAttribute('table:style-name', $st['row']);
				$colCourant = 0;
				foreach ($obj as $col => $cell) {
					$st = $cell->getStyleName();
					// On regarde s'il y a des cellules vides entre deux
					if ($colCourant < $col - 1) {
						$tbCell = $this->_addTableElement('table-cell', null, $tbRow);
						$tbCell->setAttribute('table:number-columns-repeated', ($col - $colCourant - 1));
					}
					// On ajoute la cellule de contenu
					$tbCell = $this->_addTableElement('table-cell', null, $tbRow);
					$tbCell->setAttribute('table:style-name', $st['cel']);
					if ($cell->getFormula() != '') {
						$tbCell->setAttribute('table:formula', 'oooc:'.$cell->getFormula());
					}
					if ($cell->getSpannedRows() > 1) {
						$tbCell->setAttribute('table:number-rows-spanned', $cell->getSpannedRows());
					}
					if ($cell->getSpannedCols() > 1) {
						$tbCell->setAttribute('table:number-columns-spanned', $cell->getSpannedCols());
					}
					if ($cell->getType() == 'float') {
						$tbCell->setAttribute('office:value-type', $cell->getType());
						$tbCell->setAttribute('office:value', $cell->getContent());
					}
					if ($cell->getContent() != '') {
						$content = $this->_addTextElement('p', $cell->getContent(), $tbCell);
					}
					$colCourant = $col;
				}
				$rowCourant = $row;
			}		
		}
		return true;		
	}
		
	
	/**
	 *-------------------------------------------------------------------------------
	 * Méthodes privées
	 *-------------------------------------------------------------------------------
	 */
	
	/**
	 * Fonction qui insère les noeuds des fonts
	 *
	 * @access 	protected
	 * @param 	array			$fonts					Les divers noms des fonts voulues
	 * @return 	void
	 */
	protected function _insertFontFamilies($fonts) {
		$fontFace = $this->xpath->query('//office:font-face-decls')->item(0);
		$fonts = array_unique($fonts);
		foreach ($fonts as $font) {
			$style = $this->_addStyleElement('font-face', '', $fontFace);
			$style->setAttribute('style:name', $font);
			$style->setAttribute('svg:font-family', $font);
		}
	}
	
	/**
	 * Fonction qui insère les neuds des syles
	 *
	 * @access 	protected
	 * @param 	array			$styles					Le tableau des styles à insérer
	 * @return	void
	 */
	protected function _insertStyles($styles) {
		$automaticStyles = $this->xpath->query('//office:automatic-styles')->item(0);
		foreach ($styles['cel'] as $elem) {
			$t = null; $s = null; $p = null;
			$style = $this->_addStyleElement('style', null, $automaticStyles);
			$style->setAttribute('style:name', $elem['name']);
			$style->setAttribute('style:family', 'table-cell');
			$style->setAttribute('style:parent-style-name', 'Defaut');
			if ($elem['backgroundColor'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('fo:background-color', $elem['backgroundColor']);
			}
			if ($elem['borderTop'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('fo:border-top', $elem['borderTop']);
			}
			if ($elem['borderLeft'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('fo:border-left', $elem['borderLeft']);
			}
			if ($elem['borderBottom'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('fo:border-bottom', $elem['borderBottom']);
			}
			if ($elem['borderRight'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('fo:border-right', $elem['borderRight']);
			}
			if ($elem['fontStyle'] != '') {
				$t = (!$t) ? $this->_addStyleElement('text-properties', null, $style) : $t;
				$t->setAttribute('fo:font-style', $elem['fontStyle']);
			}
			if ($elem['fontSize'] != '') {
				$t = (!$t) ? $this->_addStyleElement('text-properties', null, $style) : $t;
				$t->setAttribute('fo:font-size', $elem['fontSize']);
			}
			if ($elem['fontFamily'] != '') {
				$t = (!$t) ? $this->_addStyleElement('text-properties', null, $style) : $t;
				$t->setAttribute('style:font-name', $elem['fontFamily']);
			}
			if ($elem['fontWeight'] != '') {
				$t = (!$t) ? $this->_addStyleElement('text-properties', null, $style) : $t;
				$t->setAttribute('fo:font-weight', $elem['fontWeight']);
			}
			if ($elem['color'] != '') {
				$t = (!$t) ? $this->_addStyleElement('text-properties', null, $style) : $t;
				$t->setAttribute('fo:color', $elem['color']);
			}
			if ($elem['textAlign'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('style:text-align-source', 'fix');
				$s->setAttribute('style:repeat-content', 'false');
				$p = (!$p) ? $this->_addStyleElement('paragraph-properties', null, $style) : $p;
				$p->setAttribute('fo:text-align', $elem['textAlign']);
			}
			if ($elem['verticalAlign'] != '') {
				$s = (!$s) ? $this->_addStyleElement('table-cell-properties', null, $style) : $s;
				$s->setAttribute('style:vertical-align', $elem['verticalAlign']);
			}
		}
		foreach ($styles['col'] as $elem) {
			$style = $this->_addStyleElement('style', null, $automaticStyles);
			$style->setAttribute('style:name', $elem['name']);
			$style->setAttribute('style:family', 'table-column');
			$tbCol = $this->_addStyleElement('table-column-properties', null, $style);
			if ($elem['width']) {
				$tbCol->setAttribute('fo:break-before', 'auto');
				$tbCol->setAttribute('style:column-width', $elem['width']);
			}
		}
		foreach ($styles['row'] as $elem) {
			$style = $this->_addStyleElement('style', null, $automaticStyles);
			$style->setAttribute('style:name', $elem['name']);
			$style->setAttribute('style:family', 'table-row');
			$tbRow = $this->_addStyleElement('table-row-properties', null, $style);
			if ($elem['height']) {
				$tbRow->setAttribute('style:row-height', $elem['height']);
				$tbRow->setAttribute('fo:break-before', 'auto');
				$tbRow->setAttribute('style:use-optimal-row-height', 'false');
			}
		}
	}
	
	/**
	 * Fonction qui check quels sont les styles à insérer
	 *
	 * @access 	protected
	 * @param 	object			$cell					L'objet TableCell
	 * @param 	array			$styles					Le tableau des styles passé en référence
	 * @return	array									Le nom des styles utilisés pour la cellule
	 */
	protected function _getUsedCellStyles($cell, &$styles) {
		// Styles relatifs aux cellules (+2 parce qu'on commence au style ce2)
		$str = '';
		$str .= ($cell->getBackgroundColor()) ? $cell->getBackgroundColor() : '';
		$str .= ($cell->getBorderBottom()) ? $cell->getBorderBottom() : '';
		$str .= ($cell->getBorderLeft()) ? $cell->getBorderLeft() : '';
		$str .= ($cell->getBorderRight()) ? $cell->getBorderRight() : '';
		$str .= ($cell->getBorderTop()) ? $cell->getBorderTop() : '';
		$str .= ($cell->getFontStyle()) ? $cell->getFontStyle() : '';
		$str .= ($cell->getFontSize()) ? $cell->getFontSize() : '';
		$str .= ($cell->getFontFamily()) ? $cell->getFontFamily() : '';
		$str .= ($cell->getFontWeight()) ? $cell->getFontWeight() : '';
		$str .= ($cell->getTextAlign()) ? $cell->getTextAlign() : '';
		$str .= ($cell->getVerticalAlign()) ? $cell->getVerticalAlign() : '';
		$str .= ($cell->getColor()) ? $cell->getColor() : '';
		if (!in_array($str, $styles['celused']) && $str != '') {
			$used['cel'] = 'ce'.(count($styles['cel']) + 2);
			$styles['celused'][] = $str;
			$styles['cel'][] = array(
				'name' => $used['cel'],
				'backgroundColor' => $cell->getBackgroundColor(),
				'borderBottom' => $cell->getBorderBottom(),
				'borderLeft' => $cell->getBorderLeft(),
				'borderRight' => $cell->getBorderRight(),
				'borderTop' => $cell->getBorderTop(),
				'color' => $cell->getColor(),
				'fontStyle' => $cell->getFontStyle(),
				'fontSize' => $cell->getFontSize(),
				'fontFamily' => $cell->getFontFamily(),
				'fontWeight' => $cell->getFontWeight(),
				'textAlign' => $cell->getTextAlign(),
				'verticalAlign' => $cell->getVerticalAlign()
			);
		} else {
			$used['cel'] = ($str != '') ? 'ce'.(array_search($str, $styles['celused']) + 2) : 'ce1';
		}
		// Styles relatifs aux lignes (+2 parce qu'on commence au style ro2)
		$str = '';
		$str .= ($cell->getHeight()) ? $cell->getHeight() :	'';
		if (!in_array($str, $styles['rowused']) && $str != '') {
			$used['row'] = 'ro'.(count($styles['row']) + 2);
			$styles['rowused'][] = $str;
			$styles['row'][] = array(
				'name' => $used['row'],
				'height' => $cell->getHeight()
			);
		} else {
			$used['row'] = ($str != '') ? 'ro'.(array_search($str, $styles['rowused']) + 2) : 'ro1';
		}
		// Styles relatifs aux colonnes (+2 parce qu'on commence au style co2)
		$str = '';
		$str .= ($cell->getWidth()) ? $cell->getWidth() : '';
		if (!in_array($str, $styles['colused']) && $str != '') {
			$used['col'] = 'co'.(count($styles['col']) + 2);
			$styles['colused'][] = $str;
			$styles['col'][] = array(
				'name' => $used['col'],
				'width' => $cell->getWidth()
			);
		} else {
			$used['col'] = ($str != '') ? 'co'.(array_search($str, $styles['colused']) + 2) : 'co1';
		}
		return $used;
	}
	
	/**
	 * Fonction qui ajoute un élément signé comme étant un élément table
	 *
	 * @access 	protected
	 * @param 	string			$element				Le nom de l'élément
	 * @param 	string			$str					La valeur de l'élément
	 * @param 	object			$parent					Le DOMElement parent de celui qu'on créé
	 * @return 	object									Le DOMElement créé
	 */
	protected function _addTableElement($element, $str = null, $parent = null) {
		try {
			return $this->_addElement('table', $element, $str, $parent);
		} catch (Exception $e) {
			throw $e;	
		}
	}
	
	/**
	 * Fonction qui ajoute un élément signé comme étant un élément style
	 *
	 * @access 	protected
	 * @param 	string			$element				Le nom de l'élément
	 * @param 	string			$str					La valeur de l'élément
	 * @param 	object			$parent					Le DOMElement parent de celui qu'on créé
	 * @return 	object									Le DOMElement créé
	 */
	protected function _addStyleElement($element, $str = null, $parent = null) {
		try {
			return $this->_addElement('style', $element, $str, $parent);
		} catch (Exception $e) {
			throw $e;	
		}
	}
	
	/**
	 * Fonction qui ajoute un élément signé comme étant un élément text
	 *
	 * @access 	protected
	 * @param 	string			$element				Le nom de l'élément
	 * @param 	string			$str					La valeur de l'élément
	 * @param 	object			$parent					Le DOMElement parent de celui qu'on créé
	 * @return 	object									Le DOMElement créé
	 */
	protected function _addTextElement($element, $str = null, $parent = null) {
		try {
			return $this->_addElement('text', $element, $str, $parent);
		} catch (Exception $e) {
			throw $e;	
		}
	}
	
	/**
	 * Fonction qui ajoute un élément signé comme étant un élément number
	 *
	 * @access 	protected
	 * @param 	string			$element				Le nom de l'élément
	 * @param 	string			$str					La valeur de l'élément
	 * @param 	object			$parent					Le DOMElement parent de celui qu'on créé
	 * @return 	object									Le DOMElement créé
	 */
	protected function _addNumberElement($element, $str = null, $parent = null) {
		try {
			return $this->_addElement('number', $element, $str, $parent);
		} catch (Exception $e) {
			throw $e;	
		}
	}

}

?>
Return current item: OpenOffice Spreadsheet Generation