]> git.llucax.com Git - mecon/meconlib.git/blob - lib/MECON/PDF/Tabla.php
Habia problemas si se agregaban parrafos vacios (sin espacios). Ahora se pueden pasar...
[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                 $txt = $this->_marco->wordWrap(
254                         @$this->_tabla->getCellContents($i,$j), $ancho_columna, 
255                         $estilo);
256                 
257                 $txtt[$j] = $txt; //Esto es para no hacer el wordWrap siempre
258                 $max = max($estilo['alto_linea'] * count($txt), $max);
259                 
260                 $rep = array ();
261                 $rep = $this->_tabla->getCellAttributes($i, $j);
262                 if (@$rep['cabecera'] || @$rep['titulo']) {
263                     $repetir[$i][$j] = $txt;
264                     $repetir[$i]['max'] = $max;
265                 }
266             }
267             if ($alto <= 0) 
268             {
269                 $this->_newPage();               
270                 $alto = $this->_marco->espacioDisponible;
271                 
272                 foreach ($repetir as $ii => $value) {
273                     $alto -= $repetir[$ii]['max'];
274                     for ($jj = 0; $jj < $this->_tabla->getColCount(); $jj++) {
275                         $estilo = $this->_obtenerEstiloCelda($ii, $jj);
276
277                         //Actuo por el colspan
278                         if (@$estilo['colspan']) {
279                             if ($estilo['colspan'] > $this->_tabla->getColCount()) {
280                                 $estilo['colspan'] =
281                                     $this->_tabla->getColCount() - $jj;
282                             }
283                             $der = $attr2[$jj+$estilo['colspan']];
284                             $izq = $attr2[$jj];
285                         }
286                         else {
287                            $der = $attr2[$jj+1];
288                            $izq = $attr2[$jj];
289                         }
290
291                         
292                         $this->_marco->addRectangle($izq, $alto, $der, 
293                                 $alto+$repetir[$ii]['max'], @$estilo['fill'], 
294                                 null, $orientacion);
295                         $alto1 = $alto + $repetir[$ii]['max'];
296                         foreach ($repetir[$ii][$jj] as $t) {
297                             $alto1 -= $estilo['alto_linea'];
298
299                             //Ubico el texto segun su alineacion
300                             $init = $this->_obtenerAlineacionTexto($ii, $jj, $t, $attr2,
301                                     $estilo);
302                             
303                             $this->_marco->addText($init, $alto1 + 2,
304                                     $t, $estilo, null, $orientacion);
305                         }
306
307                         if (@$estilo['colspan']) {
308                             $jj += $estilo['colspan'] -1;
309                         }
310                         
311                     }
312                 }
313                 
314             }
315             
316             $alto -= $max;
317             for ($j = 0; $j < $this->_tabla->getColCount(); $j++) {
318                 
319                 $estilo = $this->_obtenerEstiloCelda($i, $j);
320                  
321                 //Actuo por el colspan
322                 if (@$estilo['colspan']) {
323                     if ($estilo['colspan'] > $this->_tabla->getColCount()) {
324                         $estilo['colspan'] = $this->_tabla->getColCount()  - 1;
325                     }
326                     $der = $attr2[$j+$estilo['colspan']];
327                     $izq = $attr2[$j];
328                 }
329                 else {
330                    $der = $attr2[$j+1];
331                    $izq = $attr2[$j];
332                 }
333
334                 
335                 $this->_marco->addRectangle($izq, $alto, $der, $alto+$max, 
336                         @$estilo['fill'], null, $orientacion);
337                 
338                 $alto1 = $alto + $max;
339                 if (@$txtt[$j]) {
340                     foreach ($txtt[$j] as $t) {
341                         $alto1 -= $estilo['alto_linea'];
342
343                         //Ubico el texto segun su alineacion
344                         $init = $this->_obtenerAlineacionTexto($i, $j, $t, $attr2,
345                                 $estilo);
346                         
347                         $this->_marco->addText($init, $alto1 + 2,
348                                 $t, $estilo, null, $orientacion);
349                     }
350                 }
351                 if (@$estilo['colspan']) {
352                     $j += $estilo['colspan']-1;
353                 }
354
355             }
356         }
357         $this->_marco->espacioDisponible = $alto;
358     }
359 }
360 ?>