Skip to content

FPDF, necesitas usar una multicelda sin que salte línea

mayo 25, 2011

Si estas utilizando la librería FPDF y  a la hora de generar un pdf al vuelo con php, necesitas escribir varias líneas sabes que cuentas con el método MultiCell, pero esto tiene un salto de línea, si tu no quieres que salte de línea, entonces no te pierdas ese artículo.

Aquí aprenderás como lograr el siguiente resultado:

Hola esto lo puedes hacer gracias al método Multicell, pero el cuadro que sigue estaría abajo. Pero para lograr que esta celda se quede aquí y no abajo te diré como le puedes hacer. E inclusive no solo sirve para dos celdas sirve para más celdas.

Pues bien te explico: Yo actualmente estoy trabajando en un proyecto que he llamado SICET (Sistema Integral de Control Escolar y Tutorías), y en él me topé con la necesidad de imprimir las boletas de calificaciones en pdf, donde la primer columna lleva el nombre de la materia y tienen nombres larguísimos en alguna de ellas, asi que necesitaba escribir varias líneas en una celda (esto lo hice con multicell), pero ahora necesito que escriba en la misma línea y no debajo, pues buscando y buscando, me tope con esta excelente extensión de la clase FPDF,  se llama PDF_MC_Table.

Con este ejemplo veras que sencillo es utilizar esta extensión de la clase.

Primero el código en cuestión es este:

<?php

class PDF_MC_Table extends FPDF

{

var $widths;

var $aligns;

function SetWidths($w)

{

//Set the array of column widths

$this->widths=$w;

}

function SetAligns($a)

{

//Set the array of column alignments

$this->aligns=$a;

}

function fill($f)

{

//juego de arreglos de relleno

$this->fill=$f;

}

function Row($data)

{

//Calculate the height of the row

$nb=0;

for($i=0;$i<count($data);$i++)

$nb=max($nb,$this->NbLines($this->widths[$i],$data[$i]));

$h=5*$nb;

//Issue a page break first if needed

$this->CheckPageBreak($h);

//Draw the cells of the row

for($i=0;$i<count($data);$i++)

{

$w=$this->widths[$i];

$a=isset($this->aligns[$i]) ? $this->aligns[$i] : ‘L’;

//Save the current position

$x=$this->GetX();

$y=$this->GetY();

//Draw the border

$this->Rect($x,$y,$w,$h,$style);

//Print the text

$this->MultiCell($w,5,$data[$i],’LTR’,$a,$fill);

//Put the position to the right of the cell

$this->SetXY($x+$w,$y);

}

//Go to the next line

$this->Ln($h);

}

function CheckPageBreak($h)

{

//If the height h would cause an overflow, add a new page immediately

if($this->GetY()+$h>$this->PageBreakTrigger)

$this->AddPage($this->CurOrientation);

}

function NbLines($w,$txt)

{

//Computes the number of lines a MultiCell of width w will take

$cw=&$this->CurrentFont[‘cw’];

if($w==0)

$w=$this->w-$this->rMargin-$this->x;

$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;

$s=str_replace(“\r”,”,$txt);

$nb=strlen($s);

if($nb>0 and $s[$nb-1]==”\n”)

$nb–;

$sep=-1;

$i=0;

$j=0;

$l=0;

$nl=1;

while($i<$nb)

{

$c=$s[$i];

if($c==”\n”)

{

$i++;

$sep=-1;

$j=$i;

$l=0;

$nl++;

continue;

}

if($c==’ ‘)

$sep=$i;

$l+=$cw[$c];

if($l>$wmax)

{

if($sep==-1)

{

if($i==$j)

$i++;

}

else

$i=$sep+1;

$sep=-1;

$j=$i;

$l=0;

$nl++;

}

else

$i++;

}

return $nl;

}

}

?>

Ahora con el siguiente código se produce un documento pdf con la misma información que se encuentra en la tabla anterior. El código esta comentado para su mejor entendimiento.

<?php

include(“mc_table.php”);

define(‘FPDF_FONTPATH’, ‘font/’);

// Encabezado del pdf

$pdf = new PDF_Mc_Table();

$pdf->AddPage();

$pdf->SetFont(‘Helvetica’,’B’, 12);

//un arreglo con su medida  a lo ancho

$pdf->SetWidths(array(80,80,30));

//un arreglo con alineacion de cada celda

$pdf->SetAligns(array(‘C’,’L’,’R’));

//OTro arreglo pero con el contenido

//utf8_decode es para que escriba bien

//los acentos.

$pdf->Row(array(utf8_decode(“Hola esto lo puedes hacer gracias al método Multicell, pero el cuadro que sigue estaría abajo.”),utf8_decode(“Pero para lograr que esta celda se quede aquí y no abajo te diré como le puedes hacer.”),utf8_decode(“E inclusive no solo sirve para dos celdas sirve para más celdas.”)));

// fin y entrega del pdf

$pdf->Output(“ejemplo.pdf”,”F”);

echo “<script language=’javascript’>window.open(‘ejemplo.pdf’,’_self’,”);</script>”;

exit;

?>

Bueno eso es todo por este artículo, si deseas obtener el código dale click aquí, y recuerda jugar un poco con el código para que veas como funciona eso te ayuda en 80% a aprender.

Espero te sea utilidad esta información tanto como a mi me sirven tus comentarios, asi que no dudes en comentar y nos vemos en el siguiente artículo.

Atte, tu amigo

Salvador López

From → Avanzado, inicial

16 comentarios
  1. Nataly permalink

    Hola, muchas gracias por la explicacion fue d mucha ayuda, ahora tngo un pequeño detalle q no se como solucionar. es como puedo saber q ya llegue al final de la hoja para resetear la posicion x y y para empezar en otra hoja al principio?

  2. kike permalink

    excelente aportacion, gracias por ello!!!

  3. Julio permalink

    Muy bien tu codigo, me ayudo bastante, ya me habia desesperado de que no podia hacer esto. Gracias 😀

  4. Joan permalink

    “Una solución más simple es usando GetX(), GetY() y SetXY().”
    Lo malo de usar las coordenadas es cuando cambia a otra pagina.Como se haria en ese caso.Tengo algunos problemas al capturar el inicio de la celda y fin cuando el contenido es extenso y se pasa a una siguiente hoja,alquerer imprimir la siguiente columna inicia en la pagina siguiente.

  5. correo gai permalink

    Buen aporte gracias!!! 😀

  6. Una solución más simple es usando GetX(), GetY() y SetXY().

    Obteniendo las coordenadas antes y después del multicell, puedes averiguar el tamaño y posición de la celda y utilizarlo para el resto de celdas de la misma fila.

    Aquí va un ejemplo:

    // Primero me guardo las coordenadas donde comienza la celda multilinea.
    $y1 = $pdf->GetY();
    $x1 = $pdf->GetX();

    // Pinto la celda multilinea.
    $pdf->MultiCell(65,3,’Texto de ejemplo que va a ocupar más de una línea dentro de la misma celda’,1,’L’,true);

    // Obtengo la posición vertical donde termina la celda y así saco el tamaño de alto de celda para aplicarlo al resto de las celdas de la misma fila.
    $y2 = $pdf->GetY();
    $alto_de_fila = $y2 – $y1 ;

    // Aquí obtengo la coordenada X donde quiero comenzar la siguiente columna, que no es otra cosa que la posición original más el ancho de la primera celda, en el caso del ejemplo es 65.
    $posicionX = $x1 + 65;

    // Por último, me sitúo en las coordenadas correspondientes a la misma fila y siguiente columna.
    $pdf->SetXY($posicionX,$y1);

    // Y ahora a pintar el resto de celdas con el mismo tamaño de alto para toda la fila.
    $pdf->Cell(20,$alto_de_fila,’Celda 2′,1,0,’C’,true);
    $pdf->Cell(20,$alto_de_fila,’Celda 3′,1,0,’C’,true);
    $pdf->Cell(20,$alto_de_fila,’Celda 4′,1,0,’C’,true);

    Espero haberme explicado bien.
    Un saludo.

  7. Juan Diego Ari permalink

    Wow!! me sirvio de mucho, gracias por subir este codigo.

  8. gracias por compartir la información… un tweet para este artículo 😉

  9. Daniel permalink

    Muy buieno pero solo hay unos pequeños detalles como el $style debes agregarla o quitarla ya que no esta ni entrando o declarandose por algun lado, pregunta por que ya no funciona la salida normal a browser antes hacia $PDF->OutPut() y funcionaba ahora me toca ponerle el nombre del archivo y solo funciona con F nisiquiera con I 😦

  10. david permalink

    lo he probado, ha sido perfecto para mi! mil gracias!

  11. Andres permalink

    Gracias por el codigo.
    Disculpa tengo un problema para posicionar la tabla donde yo quiero, alguna idea de donde puede estar el error??.

  12. ubuntu_flafla permalink

    GRACIAS,ESTOY PASANDO TRABAJO CON ALGO PARECIDO

  13. fer permalink

    todo eso solo para k no salte, muy complicado voy a buscar una solucion mas simple

  14. josue rivera permalink

    Muchas gracias por el codigo.

  15. Alex permalink

    Chevere, Gracias!!! 🙂 No había logrado resolver este problema. Y al fin lo he logrado.

  16. Dert permalink

    Probando, a ver que tal funca.

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: