FAQ

1. ¿Cuál es exactamente el tipo de licencia de FPDF? ¿Existen restricciones de uso?
2. Cuando intento crear un PDF, aparecen un montón de caracteres raros. ¿Por qué?
3. Intento generar un PDF y IE muestra una página en blanco. ¿Qué pasa?
4. Mando parámetros mediante el método POST y los valores no aparecen en el PDF.
5. Cuando uso una sesión PHP, IE no me muestra el PDF, pero me pregunta si deseo descargarlo.
6. Cuando estoy en SSL, IE no puede abrir el PDF.
7. Cuando ejecuto un script me da un error "FPDF error: Don't alter the locale before including class file".
8. Intento insertar un PNG y Acrobat dice "There was an error processing a page. A drawing error occurred".
9. Encuentro el siguiente error cuando intento generar un PDF: Warning: Cannot add header information - headers already sent by (output started at script.php:X)
10. Intento mostrar una variable en el método Header pero no se imprime nada.
11. He definido los métodos Header y Footer en mi clase PDF, pero no se muestra nada.
12. No consigo que los saltos de línea funcionen. Pongo \n en la cadena para MultiCell, pero no funciona.
13. Intento incluir el símbolo del euro, pero no funciona.
14. Dibujo un marco con dimensiones muy precisas pero, cuando lo imprimo, noto algunas diferencias.
15. Me gustaría usar toda la superficie de la página, pero cuando imprimo siempre aparecen márgenes. ¿Cómo puedo deshacerme de ellos?
16. ¿Cuál es el límite de tamaño de los ficheros que puedo generar con FPDF?
17. ¿Puedo modificar un PDF con FPDF?
18. Me gustaría hacer un motor de búsqueda en PHP e indexar ficheros PDF. ¿Puedo hacerlo con FPDF?
19. ¿Puedo convertir una página HTML en PDF con FPDF?
20. ¿Puedo concatenar ficheros PDF con FPDF?


1. ¿Cuál es exactamente el tipo de licencia de FPDF? ¿Existen restricciones de uso?

FPDF es freeware (tal y como se afirma al principio del fichero fuente). No hay limitaciones de uso. Puede usarlo libre y gratuitamente en su aplicación (comercial o no), con o sin modificaciones.

2. Cuando intento crear un PDF, aparecen un montón de caracteres raros. ¿Por qué?

Esos caracteres "raros" constituyen de hecho el contenido del PDF. Este comportamiento es un fallo de Internet Explorer (IE). Cuando recibe una página en HTML y después un PDF de la misma URL, lo muestra directamente sin lanzar Acrobat. Esto ocurre con frecuencia durante la fase de desarrollo: al menor fallo en el script, se envía una página HTML y, después de corregirlo, se envía el PDF.
Para resolver el problema, simplemente reinicie IE. También puede irse a otra URL y volver.
Para evitar estas molestias durante el desarrollo, puede generar el PDF directamente a un fichero y abrirlo mediante el navegador.

3. Intento generar un PDF y IE muestra una página en blanco. ¿Qué pasa?

Antes de nada, compruebe que no envía nada al navegador después del PDF (ni siquiera un espacio o un salto de línea). Puede incluir una instrucción exist justo después de llamar al método Output() para asegurarse.
Si esto no funciona, significa que es usted víctima del "síndrome de la página en blanco". IE usado con la extensión de Acrobat tiene numerosos fallos, en todas las versiones. Debería probar su aplicación con tantas versiones de IE como le sea posible (al menos si está usted en Internet). El problema ocurre sobre todo con el método POST, así que se aconseja encarecidamente que lo evite (a no ser que cause otros problemas, véase la siguiente pregunta). El método GET funciona mejor, pero puede fallar si la URL es demasiado larga: no use una cadena de petición de más de 45 caracteres. Sin embargo, existe un truco para exceder este límite: haga terminar la URL con .pdf, lo que engaña a IE. Si usa un formulario, puede añadir un campo oculto en el último lugar:

<INPUT TYPE="HIDDEN" NAME="ext" VALUE=".pdf">

El uso de sesiones de PHP también causa problemas con frecuencia (evite usar cabeceras HTTP que eviten el caché). Véase la cuestión 5 para un atajo.

Para evitar todos estos problemas de manera fiable, existen dos técnicas fundamentalmente:

- Deshabilite la extensión y use Acrobat como una aplicación auxiliar. Para esto, abra Acrobat; en el menú Archivo, Preferencias, General, desmarque la casilla "Integración con el navegador" (para Acrobat 5: Edición, Preferencias, Opciones, "Mostrar PDF en el navegador"). La próxima vez que cargue un PDF en IE, se le mostrará un mensaje "Abrir" o "Guardar en disco". Desmarque la casilla "Preguntar siempre antes de abrir este tipo de archivo" y escoja Abrir. A partir de ahora, los ficheros PDF se abrirán automáticamente en una ventana externa de Acrobat.
La pega de este método es que necesita alterar la configuración del cliente, que es algo viable en una intranet, pero imposible para Internet.

- Use una técnica de redirección. Consiste en generar el PDF en un fichero temporal en el servidor y redireccionar al cliente al fichero (usando JavaScript, no la cabecera HTTP Location, ya que también da problemas). Por ejemplo, al final del script, puede añadir lo siguiente:

//Determinar un nombre temporal de fichero en el directorio actual
$file=basename(tempnam(getcwd(),'tmp'));
//Guardar el PDF en el fichero
$pdf->Output($file);
//Redirección por JavaScript
echo "<HTML><SCRIPT>document.location='getpdf.php?f=$file';</SCRIPT></HTML>";

Después, cree el fichero getpdf.php con esto:

<?php
$f=$HTTP_GET_VARS['f'];
//Comprobar el fichero (¡no lo pase por alto!)
if(substr($f,0,3)!='tmp' or strpos($f,'/') or strpos($f,'\\'))
die('Nombre incorrecto de fichero');
if(!file_exists($f))
    die('El fichero no existe');
//Gestionar peticiones especiales de IE si es necesario
if($HTTP_ENV_VARS['USER_AGENT']=='contype')
{
    Header('Content-Type: application/pdf');
    exit;
}
//Devolver el PDF
Header('Content-Type: application/pdf');
Header('Content-Length: '.filesize($f));
readfile($f);
//Eliminar el fichero
unlink($f);
exit;
?>

Este método funciona en la mayoría de los casos, pero IE6 puede todavía causar problemas. El método "definitivo" consiste en redireccionar directamente al fichero temporal. Por tanto, el nombre de fichero debe terminar con .pdf:

//Determinar un nombre temporal de fichero en el directorio actual
$file=basename(tempnam(getcwd(),'tmp'));
rename($file,$file.'.pdf');
$file.='.pdf';
//Guardar el PDF en un fichero
$pdf->Output($file);
//Redirección con JavaScript
echo "<HTML><SCRIPT>document.location='$file';</SCRIPT></HTML>";

Este método convierte el PDF dinámico en estático y evita todos los problemas. Pero debe hacer limpieza de los ficheros temporales. Por ejemplo:

function CleanFiles($dir)
{
    //Borrar los ficheros temporales
    $t=time();
    $h=opendir($dir);
    while($file=readdir($h))
    {
        if(substr($file,0,3)=='tmp' and substr($file,-4)=='.pdf')
        {
            $path=$dir.'/'.$file;
            if($t-filemtime($path)>3600)
                @unlink($path);
        }
    }
    closedir($h);
}

Esta función borra todos los ficheros de la forma tmp*.pdf más antiguos de una hora en el directorio especificado. Puede ser llamada donde usted quiera como, por ejemplo, en el script que genera el PDF.

Nota: es necesario abrir el PDF en una ventana nueva, ya que no podrá ir hacia atrás debido a la redirección.

4. Mando parámetros mediante el método POST y los valores no aparecen en el PDF.

Es un problema que afecta a algunas versiones de IE (especialmente a los primeros 5.5). Véase la pregunta anterior para algunas soluciones.

5. Cuando uso una sesión PHP, IE no me muestra el PDF, pero me pregunta si deseo descargarlo.

Se trata de un problema con algunas versiones de IE. Para solucionarlo, añada la siguiente línea antes de session_start();

session_cache_limiter('private');

o haga una redirección como se explicó en la pregunta 3.

6. Cuando estoy en SSL, IE no puede abrir el PDF.

El problema puede solucionarse añadiendo esta línea:

Header('Pragma: public');

7. Cuando ejecuto un script me da un error "FPDF error: Don't alter the locale before including class file".

Cuando el separador de decimales se configura para que se una coma antes de incluir un fichero, existe un fallo en PHP, y los números decimales se truncan. Por tanto, no debería hacer ninguna llamada a setlocale() antes de incluir la clase. En Unix, no debería tampoco establecer la variable de entorno LC_ALL, ya que es equivalente a una llamada a setlocale().

8. Intento insertar un PNG y Acrobat dice "There was an error processing a page. A drawing error occurred".

Acrobat 5 tiene un fallo y no puede mostrar imágenes monocromas transparentes (1 bit por píxel). Elimine la transparencia o guarde su imagen en 16 colores (4 bits por píxel) o más.

9. Encuentro el siguiente error cuando intento generar un PDF: Warning: Cannot add header information - headers already sent by (output started at script.php:X)

No puede enviar nada al navegador excepto el PDF mismo: ni HTML, ni espacios, ni saltos de línea, ni antes ni después. El script está enviando algo en la línea X.

10. Intento mostrar una variable en el método Header pero no se imprime nada.

Debe usar la directiva global, por ejemplo:

function Header()
{
    global $title;

    $this->SetFont('Arial','B',15);
    $this->Cell(0,10,$title,1,1,'C');
}

11. He definido los métodos Header y Footer en mi clase PDF, pero no se muestra nada.

Tiene que crear un objeto de la clase PDF, no de la FPDF:

$pdf=new PDF();

12. No consigo que los saltos de línea funcionen. Pongo \n en la cadena para MultiCell, pero no funciona.

Debe usted utilizar comillas dobles ("), no simples ('), para la cadena.

13. Intento incluir el símbolo del euro, pero no funciona.

Las fuentes estándares tiene el carácter euro en la posición 128. Puede definir una constante como esta para su comodidad:

define('EURO',chr(128));

14. Dibujo un marco con dimensiones muy precisas pero, cuando lo imprimo, noto algunas diferencias.

Para que se respeten las dimensiones, debe desmarcan la casilla "Ajustar a página" en la ventana de impresión de Acrobat.

15. Me gustaría usar toda la superficie de la página, pero cuando imprimo siempre aparecen márgenes. ¿Cómo puedo deshacerme de ellos?

Todas las impresoras tienen márgenes físicos (dependiendo del modelo). Por tanto, es imposible quitarlos e imprimir en la totalidad del papel.

16. ¿Cuál es el límite de tamaño de los ficheros que puedo generar con FPDF?

No hay ningún límte en particular. Sin embargo, hay ciertas limitaciones:

- El máximo de memoria reservada para los scripts en PHP es, por defecto, de 8 MB. Para documentos muy extensos, especialmente si contienen imágenes, este límite puede alcanzarse (ya que el fichero se construye en memoria). El límite se define en el fichero php.ini.

- El tiempo máximo de ejecución es por defecto de 30 segundos. Este límite puede ser fácilmente sobrepasado. Se define en php.ini y puede ser modificado dinámicamente mediante set_time_limit().

- Los navegadores tienen por lo general un límite de 5 minutos de inactividad. Si envía directamente el PDF al navegador y sobrepasa el límite, se perderá el documento. Por tanto, en el caso de documentos muy grandes, se aconseja generarlos en un fichero y enviar información al navegador de tanto en tanto (por ejemplo, la página 1, la 2... con flush(), que fuerza la salida). Cuando el documento esté terminado, puede redireccionar a él con JavaScript o crear un enlace.
Nota: incluso si el navegador agota su tiempo, el script puede continuar ejecutándose en el servidor.

17. ¿Puedo modificar un PDF con FPDF?

No.

18. Me gustaría hacer un motor de búsqueda en PHP e indexar ficheros PDF. ¿Puedo hacerlo con FPDF?

No. Pero existe una utilidad GPL escrita en C, pdftotext, que es capaz de extraer el texto de un PDF. Viene con el paquete Xpdf:

http://www.foolabs.com/xpdf/

19. ¿Puedo convertir una página HTML en PDF con FPDF?

No. Pero existe una utilidad GPL escrita en C. htmldoc, que le permite hacerlo y da buen resultado:

http://www.easysw.com/htmldoc/

20. ¿Puedo concatenar ficheros PDF con FPDF?

No. Pero existe un programa gratuito escrito en C para hacerlo:

http://thierry.schmit.free.fr/dev/mbtPdfAsm/enMbtPdfAsm2.html