Recursos y Contenidos para Webmaster y Freelances del Diseño
Categoría: Programación
Como Crear Ficheros PDF con PHP
  1. Los tipos de letra
    Dentro de directorio en el que has instalado PHP hay un subdirectorio que se llama pdf-related y dentro de ese directorio hay un fichero copyright.txt que te leas con lo cual advertid@ quedas de los aspectos legales de asunto.

  2. Además de ese, hay otro fichero muy importante que es el pdflib.upr donde aparece una lista como esta:
     
    FontAFM

  3.      Courier=Courier.afm
         Courier-Bold=Courier-Bold.afm
         Courier-BoldOblique=Courier-BoldOblique.afm
         Courier-Oblique=Courier-Oblique.afm
         Helvetica=Helvetica.afm
         Helvetica-Bold=Helvetica-Bold.afm
         Helvetica-BoldOblique=Helvetica-BoldOblique.afm
         Helvetica-Oblique=Helvetica-Oblique.afm
         Symbol=Symbol.afm
         Times-Bold=Times-Bold.afm
         Times-BoldItalic=Times-BoldItalic.afm
         Times-Italic=Times-Italic.afm
         Times-Roman=Times-Roman.afm
         ZapfDingbats=ZapfDingbats.afm
     

  4. Te anticipo que es posible utilizar también fuentes TrueType, etc. etc. pero como parece que no funcionan con todas la versiones de la librería PDF será mejor que de momento te conformes con estas...
     
      Un fichero pdf en blanco
    Aquí tienes el código fuente para crear el fichero pdf más sencillo... un fichero en blanco que contiene tres páginas distintas con distintos tamaños.

  5. Fíjate que antes de crear la nueva página cerramos la anterior con un pdf_end_page.
     
    <?
    $hb=rand(1,99);
    $f = fopen("ejemplo".$hb."pdf.pdf", "w");
    $g = pdf_open($f);
    #dimensionamos la página con formato A-4
    pdf_begin_page($g, 595, 842);
    pdf_end_page($g);
    #dimensionamos la segunda página con formato A-5
    pdf_begin_page($g, 421, 595);
    pdf_end_page($g);
    #dimensionamos la tercera página con formato A-6
    pdf_begin_page($g, 297, 421);
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo<?php echo $hb;?>pdf.pdf">Ver el pdf creado</a>
     
     
      Un simple línea de texto
    Aquí tienes un ejemplo en el que creamos un documento pdf en el que aparecerá una línea de texto, pero... fíjate donde aparece... ¿no la encuentras? pues mira bien... mira al final de la página en la esquina inferior izquierda... ¿por qué? bueno... pues parece que la razón es que pdf_show empieza a colocar el texto a partir de la coordenada (0,0) y ya sabes que aquí las coordenadas son puramente cartesianas.
     
    <?
    $f = fopen("ejemplo2pdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    pdf_set_font($g, "Times-Roman", 30,"host", 0 );
    pdf_show($g,"Este es el texto");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo2pdf.pdf">Ver el pdf creado</a>
     
     
      Cambiando el origen de coordenadas
    PHP dispone de una función que permite desplazar el origen de coordenadas. Su utilización es muy sencilla, basta escribir -despues de crear la nueva página- está función:

  6.       pdf_translate($g, x, y)

  7. en la que $g es -como siempre- el famoso identificador de recurso y x e y son las coordenadas (horizontal y vertical) del nuevo origen de coordenadas.

  8. Si observas el ejemplo que te pongo aquí debajo, he transladado el origen a la ordenada 750 (como siempre en pixels) y quizá te preguntes... ¿por qué no la cambió a 842 si 842 es la altura de la página?...

  9. La respuesta es sencilla, si hubiera puesto el nuevo origen en 842 -de hecho lo hice y me llevé un buen susto- lo que ocurre es que empieza a escribir a partir de ese punto, pero hacia arriba y claro, como ese es el extremo superior de la página escribe fuera de ella y... no se ve nada.
    Por esa razón dejé el origen un poquito más abajo... para que cupiera en la página...

  10. Te recuerdo que las coordenadas en los documentos pdf son coordenadas cartesianas... ;-) ¡¡avisad@ quedas..!!


  11. <?
    $f = fopen("ejemplo2bpdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    pdf_translate($g, 20, 750);
    pdf_set_font($g, "Times-Roman", 30,"host", 0 );
    pdf_show($g,"Este es el texto");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo2bpdf.pdf">Ver el pdf creado</a>
     
     
      Saltos de línea y posicionamiento por coordenadas
    En este ejemplo puedes observar los resultado de aplicar las funciones pdf_show, pdf_continue_text y pdf_show_xy.

  12. Observa como pdf_show va colocando un texto a continuación de otro -siempre en la misma línea- sin tener en consideración si desborda o no el margen del documento.
     
    <?
    $f = fopen("ejemplo2cpdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    pdf_translate($g, 20, 750);
    pdf_set_font($g, "Times-Roman", 60,"host", 0 );
    pdf_show($g,"Este es el texto");
    pdf_show($g,"Mas texto");
    pdf_continue_text($g,"Una nueva línea");
    pdf_show_xy($g,"Esto sale en (40,-300)",40,-400);
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo2cpdf.pdf">Ver el pdf creado</a>
     
     
      Los diferentes tipos tipos de letra
    Cuando te comentaba -al margen- la función pdf_set_font no fuí demasiado explícito al comentarte los tipos de codificación. Aquí tienes un poco más de información al respecto.

  13.      • winansi es la codificación de Windows con codepage 1252

  14.      • macroman es la codificación Mac Roman que utilizan por defecto los sistemas Macintosh

  15.      • ebcdic es la codificación EBCDIC que utilizan algunos sistemas I.B.M. de las series AS400 y S/390

  16.      • host Utiliza macroman en sistemas Macintosh, ebcdic en sistemas basados en EBCDIC y winansi en todos los demás casos.

  17.      • builtin Utiliza una codificación específica aplicable al caso de fuentes de símbolos o a otras fuentes que no pertenecen al alfabeto latino.

  18. Como podrás observar lo práctico y lo cómodo es utilizar la codificación host que sirve para todo con las excepciones de las fuentes Symbol y ZapfDingbats que por su peculiaridades -alfabeto griego en un caso y símbolos en el otro- deben utilizar la codificación builtin.

  19. Y por si acaso desconfías de mi que dicho sea de paso sería una opción muy prudente por tu parte, aquí tienes la prueba de que no te engaño.... ;-).
     
    <?
    $f = fopen("ejemplo3pdf.pdf", "w+");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    pdf_translate($g, 20, 842);
    pdf_set_font($g, "Courier", 20,"host", 0 );
    pdf_show_xy($g, "Courier", 0, -40);
    pdf_set_font($g, "Courier-Bold", 20,"host", 0 );
    pdf_continue_text($g,"Courier-Bold");
    pdf_set_font($g, "Courier-BoldOblique", 20,"host", 0 );
    pdf_continue_text($g,"Courier-BoldOblique");
    pdf_set_font($g, "Courier-Oblique", 20,"host", 0 );
    pdf_continue_text($g,"Courier-Oblique");
    pdf_set_font($g, "Helvetica", 20,"host", 0 );
    pdf_continue_text($g,"Helvetica");
    pdf_set_font($g, "Helvetica-Bold", 20,"host", 0 );
    pdf_continue_text($g,"Helvetica-Bold");
    pdf_set_font($g, "Helvetica-BoldOblique", 20,"host", 0 );
    pdf_continue_text($g,"Helvetica-BoldOblique");
    pdf_set_font($g, "Helvetica-Oblique", 20,"host", 0 );
    pdf_continue_text($g,"Helvetica-Oblique");
    pdf_set_font($g, "Times-Bold", 20,"host", 0 );
    pdf_continue_text($g,"Times-Bold");
    pdf_set_font($g, "Times-BoldItalic", 20,"host", 0 );
    pdf_continue_text($g,"Times-BoldItalic");
    pdf_set_font($g, "Times-Italic", 20,"host", 0 );
    pdf_continue_text($g,"Times-Italic");
    pdf_set_font($g, "Times-Roman", 20,"host", 0 );
    pdf_continue_text($g,"Times-Roman");
    #cuidado con la definición de fuentes Zapfdingbats
    pdf_set_font($g, "ZapfDingbats", 20,"builtin", 0 );
    pdf_continue_text($g,"ZapfDingbats");
    #cuidado con la definición de fuentes Symbol
    pdf_set_font($g, "Symbol", 20,"builtin", 0 );
    pdf_continue_text($g,"Symbol");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo3pdf.pdf">Ver el pdf creado</a>
     
     
      Manejando cajas de texto
    Aquí tienes un ejemplo que crea cajas de textos con unas dimensiones determinadas y realiza diferentes tipos de a alineación horizontal.
     
    <?
    $f = fopen("ejemplo4pdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    #recogemos en una variable una cadena de texto
    $cadena="Este el texto que vamos a insertar dentro de una caja\\n";
    $cadena .="Añadimos una nueva línea y hemos puesto el ";
    $cadena.="caracter especial 'barra invertida n'";
    $cadena .=" para señalar el punto y aparte\\n";
    #recogemos comentarios sobre diferentes alineaciones
    $izquierda="Este texto se alineará a la izquierda";
    $centro="Esta caja de texto aparecerá centrada";
    $derecha="En esta caja aparecerá el texto alineado a la derecha";
    $justificado="Esta caja de texto aparecerá justificada";
    #establecemos la tipografia
    pdf_set_font($g, "Courier", 12,"host", 0 );
    #establecemos el color de la letra usando colores RGB
    pdf_setcolor($g,"fill","rgb", 1.0, 0, 0);
    #imprimimos la caja en la posicion deseada
    pdf_show_boxed($g, $cadena.$justificado , 50, 600, 200, 150, "justify");
    #cambiamos el tipo de letra
    pdf_set_font($g, "Helvetica", 10,"host", 0 );
    #establecemos el nuevo color de la letra usando colores CMYK
    pdf_setcolor($g,"fill","cmyk", 1.0, 0, 0, 0);
    pdf_show_boxed($g, $cadena.$centro , 300, 600, 200, 150, "center");
    pdf_show_boxed($g, $cadena.$derecha , 50, 400, 200, 150, "right");
    pdf_set_font($g, "Times-Italic", 10,"host", 0 );
    pdf_show_boxed($g, $cadena.$izquierda , 300, 400, 200, 150, "left");
    #aumentamos el tamaño de letra y observaremos
    #como el texto aparece incompleto porque no cabe en la caja de texto
    pdf_set_font($g, "Times-Italic", 20,"host", 0 );
    pdf_show_boxed($g, $cadena.$izquierda , 150, 250, 200, 150, "left");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo4pdf.pdf">Ver el pdf creado</a>
     

  20. Si este código no te funciona y te aparece un error es posible que se deba a que la versión de PHP que estás utilizando sea una versión antigua.

  21. En ese caso, prueba con este otro código en el que he modificado la funciones de color de relleno sustituyéndolas por su versión más antigua tal como te comento al margen.
     
    <?
    $f = fopen("ejemplo4bpdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    #recogemos en una variable una cadena de texto
    $cadena="Este el texto que vamos a insertar dentro de una caja\\n";
    $cadena .="Añadimos una nueva línea y hemos puesto ";
    $cadena .="el caracter especial 'barra invertida n'";
    $cadena .=" para señalar el punto y aparte\\n";
    #recogemos comentarios sobre diferentes alineaciones
    $izquierda="Este texto se alineará a la izquierda";
    $centro="Esta caja de texto aparecerá centrada";
    $derecha="En esta caja aparecerá el texto alineado a la derecha";
    $justificado="Esta caja de texto aparecerá justificada";
    #establecemos la tipografia
    pdf_set_font($g, "Courier", 12,"host", 0 );
    #establecemos el color de la letra usando colores RGB
    pdf_setrgbcolor_fill($g, 1.0,0,0);
    pdf_show_boxed($g, $cadena.$justificado , 50, 600, 200, 150, "justify");
    pdf_set_font($g, "Helvetica", 10,"host", 0 );
    #establecemos el nuevo color de la letra
    pdf_setrgbcolor_fill($g,0,1,1);
    pdf_show_boxed($g, $cadena.$centro , 300, 600, 200, 150, "center");
    pdf_show_boxed($g, $cadena.$derecha , 50, 400, 200, 150, "right");
    pdf_set_font($g, "Times-Italic", 10,"host", 0 );
    pdf_show_boxed($g, $cadena.$izquierda , 300, 400, 200, 150, "left");
    #aumentamos el tamaño de letra y observaremos
    #como el texto aparece incompleto porque no cabe en la caja de texto
    pdf_set_font($g, "Times-Italic", 20,"host", 0 );
    pdf_show_boxed($g, $cadena.$izquierda , 150, 250, 200, 150, "left");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo4bpdf.pdf">Ver el pdf creado</a>
     
     
      Dimensionando cajas de texto
    El manejo de cajas de texto puede presentar un problema. Si dimensionamos de forma estimativa la altura de caja es posible que nos quedemos cortos en cuyo caso el texto aparecerá cortado o que nos pasemos con lo cual el texto se situará en la parte superior de la caja y quizá nos provoque un efecto no deseado.

  22. PHP dispone de una función que permite calcular la altura exacta de la caja de texto una vez especificados: el tipo y tamaño de letra que pretendemos utilizar y el texto que debe contener la caja mencionada.

  23. Utilizando el viejo truco de hacer un bucle... podemos partir de una altura de caja igual a una línea e irla incrementando hasta que la función pdf_show_boxed nos devuelva cero como número de carácteres que no caben en la caja.

  24. ¡¡Cuidado...!! En versiones antiguas el valor mínimo que devuelve la función pdf_show_boxed es UNO con lo cual, si en esa situación no midificas el bucle para que se acabe en uno y no en cero puedes tener un serio problema ya que ...como no llegaría nunca a cero entraría en un bucle infinito. ¡¡Avisad@ quedas... y además -para que no te falte de nada- aquí debajo tienes los ejemplos para ambas situaciones. ... de nada... ;-)
     
    <?
    $f = fopen("ejemplo5pdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    $cadena="Este el texto que vamos a insertar dentro de una caja\\n";
    $cadena .="Añadimos una nueva línea y escribimos un par de bobadas más\\n";
    $cadena .="Se trata de probar que somos capaces de determinar la altura";
    $cadena .=" de una caja de texto\\n";
    pdf_set_font($g, "Courier", 12,"host", 0 );
    #fijamos en interlineado a voluntad
    pdf_set_value($g,"leading",20);
    #recogemos en la variable interlinea el valor del interlineado
    $interlinea = pdf_get_value($g, "leading");
    #iniciamos dos variables, alto y sumador con el valor de la interlinea
    $alto = $sumador = $interlinea;
    #con este bucle vamos modificando la altura de la caja de texto
    #hasta que el valor devuelto por pdf_show_boxed sea CERO

  25. while(pdf_show_boxed($g, $cadena, 0, 0, 150, $alto, "center",'blind')!=0){
    $alto+=$sumador;
    }
    # aquí hay una "chapucilla" para que imprima la caja de texto a partir
    # del borde superior de la página ya que siendo la altura de esta 842
    # al poner la esquina inferior izquierda en 842-$alto el borde superior se
    # situaría en cero

  26. pdf_show_boxed($g, $cadena , 50, 842-$alto, 200, $alto, "center");
    #cambiamos el tipo de letra y la alineación horizontal
    pdf_set_font($g, "Times-Roman", 18,"host", 0 );
    # determinamos las nuevas medidas del interlineado
    # en este caso tomamos el interlineado por defecto que extraemos
    # con la funcion pdf_get_value... etc.
    $interlinea = pdf_get_value($g, "leading");
    # restauramos las variables, alto y sumador
    # con el valor de la nueva interlinea
    $alto = $sumador = $interlinea;
    #recalculamos la altura con un bucle similar al anterior
    while(pdf_show_boxed($g, $cadena, 0, 0, 250, $alto, "justify",'blind')!=0){
    $alto+=$sumador;
    }

  27. pdf_show_boxed($g, $cadena , 300, 842-$alto, 250, $alto, "justify");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo5pdf.pdf">Ver el pdf creado</a>
     

  28. En este otro ejemplo tienes el mismo proceso pero adaptado a las peculiaridades de las versiones antiguas.

  29. Fíjate que el bucle while acaba ahora en uno, pero además tiene un par de peculiaridades más.

  30. Además de utilizar una función distinta -tal como te comento al margen- para establecer la interlinea, he tenido que asignar manualmente los valores de la variable $interlinea porque la función pdf_get_value($g, "leading") parece que no funciona con estas versiones antiguas y claro... a falta de función... pico y pala...

  31. ¡¡Ah...!! se me olvidaba... Quizá te preguntes que pinta el parámetro 'blind' que aparece añadido a la función pdf_show_boxed

  32. Al añadir ese parámetro adicional evitamos que el texto se vaya reescribiendo una y otra vez a medida que se repite el bucle. El parámetro adicional 'blind' impide que se escriba el texto... es por eso que después de salir del bucle repetimos la función pdf_show_boxed para que ahora si lo imprima.
     
    <?
    $f = fopen("ejemplo5bpdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    $cadena="Este el texto que vamos a insertar dentro de una caja\\n";
    $cadena .="Añadimos una nueva línea y escribimos un par de bobadas más\\n";
    $cadena .="Se trata de probar que somos capaces de determinar la altura";
    $cadena .="de una caja de texto\\n";
    pdf_set_font($g, "Courier", 12,"host", 0 );
    # fijamos en interlineado con la función antigua
    pdf_set_leading($g,20);
    #establecemos en la variable interlinea el parámeto anterior
    #en esta versión tenemos que incluirlo expresamente
    $interlinea=20;
    #iniciamos dos variables, alto y sumador con el valor de la interlinea
    $alto = $sumador = $interlinea;
    #con este bucle vamos modificando la altura de la caja de texto
    #hasta que el valor devuelto por pdf_show_boxed sea UNO
    while(pdf_show_boxed($g, $cadena,0,0,150,$alto,"center",'blind')!=1){
    $alto+=$sumador;
    }
    pdf_show_boxed($g, $cadena , 50, 842-$alto, 200, $alto, "center");
    #cambiamos el tipo de letra y la alineación horizontal
    pdf_set_font($g, "Times-Roman", 18,"host", 0 );
    # establecemos manualmente el valor de la variable interlinea
    # el interlineado por defecto es el tamaño de la letra
    $interlinea=18;
    #restauramos las variables, alto y sumador
    #con el valor de la nueva interlinea
    $alto = $sumador = $interlinea;
    #recalculamos la altura con un bucle similar al anterior
    while(pdf_show_boxed($g,$cadena,0,0,250,$alto,"justify",'blind')!=1){
    $alto+=$sumador;
    }
    pdf_show_boxed($g,$cadena,300,842-$alto, 250, $alto, "justify");
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo5bpdf.pdf">Ver el pdf creado</a>
     
     
      Centrando textos y modificando escalas
    Aquí tienes un ejemplo en el que intento mostrarte como jugar con las escalas, centrar textos, invertirlos, etc. etc. Una monada... pero... como no hay santo sin octava tengo que comentarte algunas cosillas... no vayas a decir luego que te he engañado... ;-)

  33. Mira... las escalas, aparte de lo que te comento al margen... tienen su cosa... porque una vez aplicadas se mantienen en el resto del documento salvo que... cuando quieras volver a la escala normal utilices nuevamente la función escala con los valores inversos.

  34. Y como eso de andar haciendo cuentas no es nada cómodo, y como el mando lo tiene todo previsto (cada día me sorprende más lo que cuidan el detalles l@s desarrollador@s de PHP) existen dos funciones tremendamente útiles -al menos a mi me lo parecen- que son save($p) y restore($p) y que sirven para lo siguiente.

  35. Cuando pones save($g) es como si dijeras... aquí empieza un trozo de código excepcional y si detrás de esa función pones un color nuevo, un tipo de letra distinto del que tenías, cambias el origen de coordenadas de sitio, añades un factor de escala, etc. etc. esas nuevas especificaciones se aplicarán hasta el momento en que pongas restore($g) y en cuanto pongas esto... se acabará la excepcionalidad con lo que a partir de esa línea todo volverá a las condiciones anteriores a la inserción de save($g).

  36. No me digas que no molan mogollón estas funcioncillas... ;-)

  37. Aquí en el ejemplo has he utilizado... verás que chachi...
     
    <?
    $f = fopen("ejemplo6pdf.pdf", "w");
    $g = pdf_open($f);
    pdf_begin_page($g, 595, 842);
    $cadena="Rincón Astur";
    $cadena1="Memorias de un aprendiz";
    $cadena2="Asturias si yo pudiera...";

  38. pdf_set_font($g, "Helvetica-Bold", 18,"host", 0 );
    $ancho=pdf_stringwidth($g, $cadena);
    #aquí (595-$ancho)/2 es el cálculo de la abscisa
    # para que el texto quede centrado en la página de 595 pixesl de ancho
    pdf_show_xy($g,$cadena,(595-$ancho)/2,800);
    #quiero empezar un "trozo" excepcional, pongo pdf_save
    pdf_save($g);
    #pongo una escala horizontal del 70% y vertical de 140%
    pdf_scale($g, 0.7, 1.4);
    $ancho=pdf_stringwidth($g, $cadena1);
    # quiero que aparezca centrado por eso divido 595/0.7
    # así me adapto a las nuevas unidades de ancho introducidas
    # por el factor de escala... lo mismo hago en la escala vertical
    pdf_show_xy($g,$cadena1,(595/0.7-$ancho)/2,750/1.4);
    pdf_restore($g);
    # he puesto pdf_restore con lo cual he desactivado la escala
    # ya he vuelto a la situación inicial y ahora pongo un unevo pdf_save
    # para utilizar en el "trozo siguiente" una escala distinta
    pdf_save($g);
    pdf_scale($g, 0.75, 1.3);
    pdf_set_font($g, "Times-Bold", 50,"host", 0 );
    $ancho=pdf_stringwidth($g, $cadena2);
    pdf_show_xy($g,$cadena2,(595/0.75-$ancho)/2,650/1.3);
    pdf_restore($g);
    # acabo una excepción y empiezo otra... ahora con escala negativa
    pdf_save($g);
    pdf_setrgbcolor_fill($g, 0.7,0.7,0.7);
    pdf_scale($g, 0.75, -1.3);
    pdf_set_font($g, "Times-Bold", 50,"host", 0 );
    $ancho=pdf_stringwidth($g, $cadena2);
    # fijate que ahora pongo la posición vertical negativa
    # el hecho de que el factor de escala sea negativo me obliga a hacerlo
    # por aquello de "menos por menos más..."
    pdf_show_xy($g,$cadena2,(595/0.75-$ancho)/2,-620/1.3);
    pdf_restore($g);
    # con este pdf_restore acabo la "ultima excepcionalidad"
    pdf_end_page($g);
    pdf_close($g);
    ?>
    <A Href="ejemplo6pdf.pdf">Ver el pdf creado</a>
     
     
     



Redactor: Leimnud Sistemas
Sitio Web: Leimnud Sistemas
Versión Imprimible: Ver/Imprimir
Comentarios: Hay 0 opiniones


Tu Comentario!