]> git.llucax.com Git - mecon/meconlib.git/blob - lib/MECON/PDF/Tabla.php
- Correccion de bugs
[mecon/meconlib.git] / lib / MECON / PDF / Tabla.php
1 <?php /* vim: set binary expandtab tabstop=4 shiftwidth=4 textwidth=80:
2 -------------------------------------------------------------------------------
3                              Ministerio de Economía
4                                     meconlib
5 -------------------------------------------------------------------------------
6 This file is part of meconlib.
7
8 meconlib is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your option)
11 any later version.
12
13 meconlib is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16  
17 You should have received a copy of the GNU General Public License; if not,
18 write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 Boston, MA  02111-1307  USA
20 -------------------------------------------------------------------------------
21 Creado: Fri Oct 24 16:34:11 2003
22 Autor:  Martin Marrese <mmarre@mecon.gov.ar>
23 -------------------------------------------------------------------------------
24 $Id$
25 -----------------------------------------------------------------------------*/
26
27 require_once 'MECON/PDF/Contenido.php';
28
29 /**
30  * Libreria que permite agregar una tabla a un pdf.
31  */
32 class MECON_PDF_Tabla extends MECON_PDF_Contenido {
33     
34     /**
35      * Configuracion
36      * @var array $config
37      * @access protected
38      */
39     var $_config;
40     
41     /**
42      * Objeto MECON_HTML_Tabla.
43      * @var &Object $tabla MECON_HTML_Tabla
44      * @access protected
45      */
46     var $_tabla;
47     
48     /**
49      * Objeto MECON_PDF_Marco
50      * @var &Object $marco
51      * @access protected
52      */
53     var $_marco;
54
55     /**
56      * Orientacion de las nuevas paginas
57      * @var string $orientacion
58      * @access protected
59      */
60     var $_orientacion;
61     
62     /**
63      * Indica si el encabezado debe ir en la nuevas paginas.
64      * @var bool $encabezado
65      * @access protected;
66      */
67     var $_encabezado;
68     
69     /**
70      * Class Constructor
71      *
72      * @param &Object $TABLA MECON_HTML_Tabla
73      * @param string $orientacion Orientacion que deben tener las nuevas paginas
74      * que genere la tabla.
75      *
76      * @return void
77      * @access public
78      */
79     function MECON_PDF_Tabla($TABLA, $orientacion = null, $encabezado = true) {
80         $this->_tabla = $TABLA;
81         $this->_orientacion = $orientacion;
82         $this->_config = include 'MECON/PDF/Tabla/medidas.php';
83         $this->_encabezado = $encabezado;
84     }
85     
86     /**
87      * Funcion que agrega el contenido de la tabla que se este utilizando al
88      * PDF.
89      *
90      * @param &Object $MARCO MECON_PDF_Marco
91      *
92      * @return void
93      * @access public
94      */
95     function toPDF(&$MARCO) {
96         $this->_marco =& $MARCO;
97         $this->_agregarContenido();
98     }
99
100     /**
101      * Funcion que devuelve la posicion X en donde se debe escribir un texto
102      * segun su ubicacion en la celda
103      *
104      * @param int $row Indicador de la fila
105      * @param int $col Indicador de la columna
106      * @param string $texto Texto a escribir
107      * @param array $attr Atributos internos de la celda
108      * @param array $estilo Estilo del texto
109      *
110      * @return int
111      * @access protected
112      */
113     function _obtenerAlineacionTexto($row, $col, $texto, $attr, $estilo) {
114         
115         $at = $this->_tabla->getCellAttributes($row, $col);
116
117         if (@$at['colspan']) {
118             $offset = $at['colspan'];
119         }
120         else {
121             $offset = 1;
122         }
123         
124         if (@$at['align'] == 'center') {
125             $tam = $this->_marco->strlen($texto, $estilo);
126             $init = $attr[$col] + ($attr[$col+$offset] - $attr[$col] - $tam) / 2;
127         }
128         elseif (@$at['align'] == 'right') {
129             $tam = $this->_marco->strlen($texto, $estilo);
130             $init = $attr[$col+$offset] - $tam + 1;
131         }
132         else {
133             $init = $attr[$col];
134         }
135         return $init + 1;
136     }
137
138     /**
139      * Funcion que devuelve el estilo de la celda segun la configuracion.  
140      *
141      * @param int $row Indicador de la fila
142      * @param int $col Indicador de la columna
143      *
144      * @return array
145      * @access protected
146      */
147     function _obtenerEstiloCelda($row, $col) {
148         $clase = $this->_tabla->getCellAttributes($row, $col);
149         if (@$clase['cabecera']) {
150             $estilo = $this->_config['celda_cabecera'];
151         }
152         elseif (@$clase['titulo']) {
153             $estilo = $this->_config['celda_titulo'];
154         }
155         elseif (@$clase['oscura']) {
156             $tmp = $this->_config['celda_comun'];
157             $tmp['fillcolor'] = $this->_config['celda_cabecera']['fillcolor'];
158             $tmp['fill'] = $this->_config['celda_cabecera']['fill'];
159             $estilo = $tmp;
160         }
161         elseif (@$clase['clara']) {
162             $tmp = $this->_config['celda_comun'];
163             $tmp['fillcolor'] = $this->_config['celda_titulo']['fillcolor'];
164             $tmp['fill'] = $this->_config['celda_titulo']['fill'];
165             $estilo = $tmp;
166         }
167         else {
168             $estilo = $this->_config['celda_comun'];
169         }
170         if (@$clase['colspan']) {
171             $estilo['colspan'] = $clase['colspan'];
172         }
173         return $estilo;
174     }
175
176     /**
177      * Funcion que calcula el ancho de las columnas de la tabla.  
178      *
179      * @return array
180      * @access protected
181      */
182     function _obtenerAnchoColumnas() {
183         $ancho_pagina = $this->_marco->getWidth($this->_marco->refPage(),
184                 $this->_marco->getOrientation());
185         for ($row = 0; $row<$this->_tabla->getRowCount(); $row++) {
186             for ($i=0; $i<$this->_tabla->getColCount(); $i++ ) {
187                 $tmp = $this->_tabla->getCellAttributes($row,$i);
188                 if(@intval($tmp['width']) != 0)
189                     $attr[$i] = intval($tmp['width']);
190                 if(@count($attr) == $this->_tabla->getColCount())
191                   break 2;
192             }
193         }
194         
195         if (!isset($attr))
196             trigger_error ('Todas las columnas tienen que tener un ancho asignado', E_USER_ERROR);
197         
198         $tmp = array_sum($attr);
199         
200         $attr2[0] = 0;
201         for ($i=1; $i<count($attr); $i++) {
202             $attr2[$i] = intval(($ancho_pagina * $attr[$i-1] / $tmp) +
203                     $attr2[$i-1]);
204         }
205         $attr2[$i] = $ancho_pagina;
206         return $attr2;
207     }
208     /**
209      * Funcion que se encarga de crear las nuevas paginas.
210      *
211      * @return void
212      * @access protected
213      */
214     function _newPage() {
215         $tmp = ($this->_orientacion) ? $this->_orientacion :
216             $this->_marco->getOrientation();
217         $this->_marco->newPage($this->_marco->tamanio, $tmp, $this->_encabezado);               
218     }
219
220     /**
221      * Funcion que agrega las filas y columnas a la pagina.                  
222      *
223      * @return void
224      * @access protected
225      */
226     function _agregarContenido() {
227         $alto = $this->_marco->espacioDisponible;
228         $orientacion = $this->_marco->getOrientation();
229         if ($alto <= 0 || ($this->_orientacion && $this->_orientacion !=
230                     $orientacion) ) {
231             $this->_newPage();               
232             $orientacion = $this->_marco->getOrientation();
233             $alto = $this->_marco->espacioDisponible;
234         }
235         $attr2 = $this->_obtenerAnchoColumnas();
236         for ($i = 0; $i < $this->_tabla->getRowCount(); $i++) {
237             $max = 0;
238             for ($j = 0; $j < $this->_tabla->getColCount(); $j++) {
239                 $estilo = $this->_obtenerEstiloCelda($i, $j);
240
241                 //Actuo por el colspan
242                 if (@$estilo['colspan']) {
243                     if ($estilo['colspan'] > $this->_tabla->getColCount()) {
244                         $estilo['colspan'] = 
245                             $this->_tabla->getColCount() - $j;
246                     }
247                     $ancho_columna = $attr2[$j+$estilo['colspan']] - 
248                         $attr2[$j];
249                 }
250                 else {
251                    $ancho_columna = $attr2[$j+1] - $attr2[$j];
252                 }
253                 if (@$this->_tabla->getCellContents($i,$j)) {
254                     $txt = $this->_marco->wordWrap(
255                             @$this->_tabla->getCellContents($i,$j), $ancho_columna, 
256                             $estilo
257                             );
258                 }
259                 else {
260                     $txt = array (' ');
261                 }
262                 
263                 $txtt[$j] = $txt; //Esto es para no hacer el wordWrap siempre
264                 $max = max($estilo['alto_linea'] * count($txt), $max);
265                 
266                 $rep = array ();
267                 $rep = $this->_tabla->getCellAttributes($i, $j);
268                 if (@$rep['cabecera'] || @$rep['titulo']) {
269                     $repetir[$i][$j] = $txt;
270                     $repetir[$i]['max'] = $max;
271                 }
272             }
273             if ($alto <= 0) 
274             {
275                 $this->_newPage();               
276                 $alto = $this->_marco->espacioDisponible;
277                 
278                 foreach ($repetir as $ii => $value) {
279                     $alto -= $repetir[$ii]['max'];
280                     for ($jj = 0; $jj < $this->_tabla->getColCount(); $jj++) {
281                         $estilo = $this->_obtenerEstiloCelda($ii, $jj);
282
283                         //Actuo por el colspan
284                         if (@$estilo['colspan']) {
285                             if ($estilo['colspan'] > $this->_tabla->getColCount()) {
286                                 $estilo['colspan'] =
287                                     $this->_tabla->getColCount() - $jj;
288                             }
289                             $der = $attr2[$jj+$estilo['colspan']];
290                             $izq = $attr2[$jj];
291                         }
292                         else {
293                            $der = $attr2[$jj+1];
294                            $izq = $attr2[$jj];
295                         }
296
297                         
298                         $this->_marco->addRectangle($izq, $alto, $der, 
299                                 $alto+$repetir[$ii]['max'], @$estilo['fill'], 
300                                 null, $orientacion);
301                         $alto1 = $alto + $repetir[$ii]['max'];
302                         foreach ($repetir[$ii][$jj] as $t) {
303                             $alto1 -= $estilo['alto_linea'];
304
305                             //Ubico el texto segun su alineacion
306                             $init = $this->_obtenerAlineacionTexto($ii, $jj, $t, $attr2,
307                                     $estilo);
308                             
309                             $this->_marco->addText($init, $alto1 + 2,
310                                     $t, $estilo, null, $orientacion);
311                         }
312
313                         if (@$estilo['colspan']) {
314                             $jj += $estilo['colspan'] -1;
315                         }
316                         
317                     }
318                 }
319                 
320             }
321             
322             $alto -= $max;
323             for ($j = 0; $j < $this->_tabla->getColCount(); $j++) {
324                 
325                 $estilo = $this->_obtenerEstiloCelda($i, $j);
326                  
327                 //Actuo por el colspan
328                 if (@$estilo['colspan']) {
329                     if ($estilo['colspan'] > $this->_tabla->getColCount()) {
330                         $estilo['colspan'] = $this->_tabla->getColCount()  - 1;
331                     }
332                     $der = $attr2[$j+$estilo['colspan']];
333                     $izq = $attr2[$j];
334                 }
335                 else {
336                    $der = $attr2[$j+1];
337                    $izq = $attr2[$j];
338                 }
339
340                 
341                 $this->_marco->addRectangle($izq, $alto, $der, $alto+$max, 
342                         @$estilo['fill'], null, $orientacion);
343                 
344                 $alto1 = $alto + $max;
345                 if (@$txtt[$j]) {
346                     foreach ($txtt[$j] as $t) {
347                         $alto1 -= $estilo['alto_linea'];
348
349                         //Ubico el texto segun su alineacion
350                         $init = $this->_obtenerAlineacionTexto($i, $j, $t, $attr2,
351                                 $estilo);
352                         
353                         $this->_marco->addText($init, $alto1 + 2,
354                                 $t, $estilo, null, $orientacion);
355                     }
356                 }
357                 if (@$estilo['colspan']) {
358                     $j += $estilo['colspan']-1;
359                 }
360
361             }
362         }
363         $this->_marco->espacioDisponible = $alto;
364     }
365 }
366 ?>