miércoles, 22 de octubre de 2014

Libreria FPDF y ajustar campos al texto

FPDF es una clase escrita en PHP que permite generar documentos PDF directamente desde PHP, es decir, sin usar la biblioteca PDFlib. La F de FPDF significa Free (gratis y libre): puede usted usarla para cualquier propósito y modificarla a su gusto para satisfacer sus necesidades.

Ahora bien, ¿qué pasa si en la cabecera, un título tiene más caracteres o uno de nuestros datos y por lo tanto no quepan en el ancho de celda que escogimos? pasa esto:


Para solucionar esto, colocaremos en nuestra clase de PDF.php una serie de métodos que ajustan el texto a la celda. Este código es proporcionado por la propia comunidad de fpdf.org en la opción de su página principal llamada “Scripts”.
Al final de los métodos que ya tenemos, colocaremos este código. El método que usaremos se llama CellFitSpace( ) el cual sustituirá a Cell( ). El código de PDF.php es el siguiente:
<?php
require('fpdf/fpdf.php');
class PDF extends FPDF
{
    function cabeceraHorizontal($cabecera)
    {
        $this->SetXY(10, 10);
        $this->SetFont('Arial','B',10);
        $this->SetFillColor(2,157,116);//Fondo verde de celda
        $this->SetTextColor(240, 255, 240); //Letra color blanco
        foreach($cabecera as $fila)
        {
            $this->CellFitSpace(30,7, utf8_decode($fila),1, 0 , 'L', true);
        }
    }
    function datosHorizontal($datos)
    {
        $this->SetXY(10,17);
        $this->SetFont('Arial','',10);
        $this->SetFillColor(229, 229, 229); //Gris tenue de cada fila
        $this->SetTextColor(3, 3, 3); //Color del texto: Negro
        $bandera = false; //Para alternar el relleno
        foreach($datos as $fila)
        {
            //Usaremos CellFitSpace en lugar de Cell
            $this->CellFitSpace(30,7, utf8_decode($fila['nombre']),1, 0 , 'L', $bandera );
            $this->CellFitSpace(30,7, utf8_decode($fila['apellido']),1, 0 , 'L', $bandera );
            $this->CellFitSpace(30,7, utf8_decode($fila['matricula']),1, 0 , 'L', $bandera );
            $this->Ln();//Salto de línea para generar otra fila
            $bandera = !$bandera;//Alterna el valor de la bandera
        }
    }
    function tablaHorizontal($cabeceraHorizontal, $datosHorizontal)
    {
        $this->cabeceraHorizontal($cabeceraHorizontal);
        $this->datosHorizontal($datosHorizontal);
    }
    //***** Aquí comienza código para ajustar texto *************
    //***********************************************************
    function CellFit($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $scale=false, $force=true)
    {
        //Get string width
        $str_width=$this->GetStringWidth($txt);
        //Calculate ratio to fit cell
        if($w==0)
            $w = $this->w-$this->rMargin-$this->x;
        $ratio = ($w-$this->cMargin*2)/$str_width;
        $fit = ($ratio < 1 || ($ratio > 1 && $force));
        if ($fit)
        {
            if ($scale)
            {
                //Calculate horizontal scaling
                $horiz_scale=$ratio*100.0;
                //Set horizontal scaling
                $this->_out(sprintf('BT %.2F Tz ET',$horiz_scale));
            }
            else
            {
                //Calculate character spacing in points
                $char_space=($w-$this->cMargin*2-$str_width)/max($this->MBGetStringLength($txt)-1,1)*$this->k;
                //Set character spacing
                $this->_out(sprintf('BT %.2F Tc ET',$char_space));
            }
            //Override user alignment (since text will fill up cell)
            $align='';
        }
        //Pass on to Cell method
        $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link);
        //Reset character spacing/horizontal scaling
        if ($fit)
            $this->_out('BT '.($scale ? '100 Tz' : '0 Tc').' ET');
    }
    function CellFitSpace($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='')
    {
        $this->CellFit($w,$h,$txt,$border,$ln,$align,$fill,$link,false,false);
    }
    //Patch to also work with CJK double-byte text
    function MBGetStringLength($s)
    {
        if($this->CurrentFont['type']=='Type0')
        {
            $len = 0;
            $nbbytes = strlen($s);
            for ($i = 0; $i < $nbbytes; $i++)
            {
                if (ord($s[$i])<128)
                    $len++;
                else
                {
                    $len++;
                    $i++;
                }
            }
            return $len;
        }
        else
            return strlen($s);
    }
//************** Fin del código para ajustar texto *****************
//******************************************************************
} // FIN Class PDF
?>

index.php


<?php
include_once('PDF.php');
$pdf = new PDF();
$pdf->AddPage();
$miCabecera = array('Nombre de campo', 'Apellido', 'Matrícula campo');
$misDatos = array(
            array('nombre' => 'Esperbeneplatoledo', 'apellido' => 'Martínez', 'matricula' => '20420423'),
            array('nombre' => 'Araceli', 'apellido' => 'Morales', 'matricula' =>  '204909'),
            array('nombre' => 'Georginadavabulus', 'apellido' => 'Galindo', 'matricula' =>  '2043442'),
            array('nombre' => 'Luis', 'apellido' => 'Dolores', 'matricula' => '20411122'),
            array('nombre' => 'Mario', 'apellido' => 'Linares', 'matricula' => '2049990'),
            array('nombre' => 'Viridianapaliragama', 'apellido' => 'Badillo', 'matricula' => '20418855'),
            array('nombre' => 'Yadiramentoladosor', 'apellido' => 'García', 'matricula' => '20443335')
            );
$pdf->tablaHorizontal($miCabecera, $misDatos);
$pdf->Output(); //Salida al navegador
?>

Y acá la salida:


Cualquier cosa dejen un comentario a mi me funciono sin problema.

7 comentarios:

  1. Disculpa, sabras como hacerle para que cuando el texto sobrepasa la celda se corte, es decir que no quede todo junto como en tu ejemplo y que se vean dos lineas?

    ResponderEliminar
  2. Disculpa, sabras como hacerle para que cuando el texto sobrepasa la celda se corte, es decir que no quede todo junto como en tu ejemplo y que se vean dos lineas?

    ResponderEliminar
    Respuestas
    1. tengo la misma duda ya puediste resulverla?

      Eliminar
    2. Utiliza el multicell(0,0,$variable,1,'J'); el cual te ayuda a realizar lo que usted requiere...

      Eliminar
  3. Te copiaste mi tuto! :D Genial!!
    Por lo menos por el link a mi blog :D

    SALUDOS!!

    ResponderEliminar
  4. Saludos estoy usando este código para crear un reporte. Necesito Ajustar los campos a los item. ¿Como puedo hacerlo?

    ResponderEliminar