• Publicidad

Guardar PDF

Todo lo relacionado con el desarrollo Web con Perl: desde CGI hasta Mojolicious

Guardar PDF

Notapor manu8c » 2011-04-02 07:27 @352

Hola de nuevo. Espero que esta sea mi última duda sobre Perl dentro de este proyecto.

He generado un PDF con el módulo PDF::Create y lo tengo guardado en el servidor: .../PROYECTO/PDF/fichero1

Los CGI están guardados en la carpeta .../PROYECTO/GGI-BIN/*.pl

Bueno, el tema es que estoy intentando que el cliente pueda descargar ese pdf y lo que yo hago es crear un botón de descarga que llama a DownloadPDF.pl.

Y en este módulo hago lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use DBI;
  2. use CGI;
  3.  
  4.  
  5.  
  6.  
  7. my $query = new CGI;
  8. my %FORM = $query->Vars;
  9.  
  10.  
  11.  
  12.  
  13.  
  14. print "Content-type: text/html\r\n\r\n";
  15.  
  16.  
  17.  
  18. print 'Content-Type:application/octet-stream; name= "../PDF/ficheroPDF"\r\n';
  19. print 'Content-Disposition: attachment; filename="../PDF/ficheroPDF1"\r\n\n';
  20.  
  21.  
  22.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Se me abre la ventana de descargar y no descarga nada.
He estado leyendo bastante sobre el tema y he visto que tengo que leer el fichero para poder escribirlo o algo así.


he probado también con cosas así, pero tampoco funciona:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print header (
  2.    -type => "pdf",
  3.    -attachment => "http://localhost/proyecto/pdf/FICH1.pdf",
  4.    -content_length => -s "http://localhost/proyecto/pdf/FICH1.pdf",
  5. );
  6.  
  7. open(OUTFILE,"<http://localhost/proyectoManu/pdf/NONONO.pdf");
  8.  
  9. binmode(OUTFILE);
  10.  
  11. while(<OUTFILE>){
  12.    print "$_";
  13. }
  14. close(OUTFILE);
  15.  
  16.  
  17.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



A ver si me podéis echar una ayuda, porque en este tema está todo bastante confuso. ¡Ah!, se me olvidaba: también he bajado el módulo http://search.cpan.org/dist/Net-Downloa ... d/Queue.pm , pero tampoco lo he podido hacer funcionar.
manu8c
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-03-31 09:45 @448

Publicidad

Re: Guardar PDF

Notapor explorer » 2011-04-02 10:59 @499

Cuando el navegador recibe las cabeceras de que se está bajando un fichero, comienza la espera de ese fichero, pero ¿quién se lo envía? El navegador no sabe bajarlo porque no sabe la URL de donde se encuentra. Si al navegador, en lugar de darle unas cabeceras, le hubieses dado esa URL, lo bajaría por sí mismo. Si no, tendrá que ser el mismo CGI el que se lo sirva, quizás abriendo el fichero y enviándoselo al navegador (que está esperando).

En Perl, cuando haces

open(OUTFILE,"<http://localhost/proyectoManu/pdf/NONONO.pdf");

le estás indicando que abra el fichero 'http://localhost/proyectoManu/pdf/NONONO.pdf' en el directorio donde se está ejecutando el programa en ese momento.

¡Ojo! Se trata del fichero 'http://localhost/proyectoManu/pdf/NONONO.pdf'. Eso quiere decir que Perl NO va a hacer una conexión HTTP para conseguir el fichero, sino que va a intentar abrir un fichero que comienza por las letras 'h', 't', 't', 'p', ':', '/', '/', etc. en el directorio local.

Lo mismo ocurre con el operador -s que usas un par de líneas más arriba: -s "http://localhost/proyecto/pdf/FICH1.pdf" siempre vale 0 porque el fichero "http://localhost/proyecto/pdf/FICH1.pdf" no existe en el directorio.

Perl NO hace conexiones HTTP de forma automática.

Si se trata de acceder a ficheros que están en tu mismo sistema informático, en tu mismo sistema de ficheros, entonces te vale con poner la ruta completa (o relativa) a esos ficheros.

Por ejemplo:
open(OUTFILE,"<../PDF/fichero1");

Otra cosa distinta es que necesites acceder a ficheros que están fuera de tu sistema informático. Si el protocolo para acceder a ellos puede ser el HTTP, puedes usar el módulo LWP::Simple (o muchos otros) para hacerlo. Por ejemplo:

my $pdf = get('http://servidor_externo/proyectoManu/pdf/NONONO.pdf');

(Si en lugar de 'servidor_externo' se trata de 'localhost', entonces nos estamos refiriendo a nuestro propio sistema informático, por lo que, normalmente, no será necesario hacer una petición HTTP, ya que con un simple open() podremos acceder al fichero NONONO.pdf, con tan solo indicar la ruta hacia él.)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Guardar PDF

Notapor manu8c » 2011-04-03 11:31 @521

Hola, gracias por la respuesta.

Me ha quedado muy claro. Definitivamente he usado el método open(), ya que el sistema solo accederá al pdf que tenga en él.

Entonces, ahora con
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $pdf = get('http://servidor_externo/proyectoManu/pdf/NONONO.pdf');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

tengo el pdf en la variable $pdf.

¿Cómo hago para que el usuario lo pueda descargar?
He probado con:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
print 'Content-Type:application/octet-stream; name= "" \r\n';
print 'Content-Disposition: attachment;name ""  \r\n\n';
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Pero no sé cómo usarlo. Ya que el fichero lo tengo ya y no necesito un 'name'.

Gracias de nuevo por tu tiempo.
manu8c
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-03-31 09:45 @448

Re: Guardar PDF

Notapor explorer » 2011-04-03 14:41 @654

Si vas a usar el método del open(), no necesitas hacer lo del get().

Entonces, te lees el pdf con el open(), binmode(), read() (o <>), close() a la variable $pdf.

Luego, como estás usando el módulo CGI, puedes agregar las cabeceras necesarias para que el navegador entienda que va a recibir un fichero PDF y que quieres, preferentemente, que lo guarde a disco:

(no probado)
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $cgi = CGI->new();
  2.  
  3. print $cgi->header(
  4.     -type        => 'application/pdf',                       # vamos a enviar un PDF
  5.     -Disposition => 'attachment; filename="fichero.pdf"',    # nombre recomendado para guardarlo en disco
  6. );
  7.  
  8. binmode STDOUT;    # activamos la salida estándar en modo binario
  9.  
  10. print $pdf;        # ¡Bumm!, el pdf sale
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Guardar PDF

Notapor manu8c » 2011-04-03 21:00 @916

Bueno, dejo el código funcionando.

Lo comentado son pruebas que no han funcionado. Algunas no sé por qué.

Mañana haré que en vez de leer todo el fichero con un número grande, vaya leyendo hasta que encuentre EOF.

Gracias por toda la ayuda prestada.

Preguntaría por el módulo DBD::Oracle para otra cosa, pero me he dado por vencido con él y con Oracle en general.

Bueno, dejo el código.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!"C:\xampp\perl\bin\perl.exe" 
  2.  
  3.  
  4. use DBI;
  5. use CGI;
  6. my $cgi = CGI->new();
  7. my %FORM = $cgi->Vars;
  8.  
  9.  
  10. open(PDF,"C:/xampp/htdocs/proyectoManu/PDF/NONONO.pdf");
  11.  
  12. #open(PDF,"http://localhost/proyectoManu/PDF/NONONO.pdf"); Ya sabia que no funcionaba
  13. #open open(PDF,"../NONONO.pdf");
  14. ##open open(PDF,"<../NONONO.pdf");
  15.  
  16.  
  17. binmode PDF;
  18.  
  19. $out='';
  20. read (PDF,$out,10000005);
  21. close(PDF);
  22.  
  23. print $cgi->header(
  24.      -type        => 'application/pdf',                       # vamos a enviar un PDF
  25.      -Disposition => 'attachment; filename="fichero.pdf"',    # nombre recomendado para guardarlo en disco
  26. );
  27.      
  28. binmode STDOUT;    # activamos la salida estándar en modo binario
  29.      
  30. print $out;
  31.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
manu8c
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-03-31 09:45 @448

Re: Guardar PDF

Notapor explorer » 2011-04-04 03:23 @182

Otra forma: usando el operador -s puedes saber el tamaño del fichero.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $fichero_pdf = 'C:/xampp/htdocs/proyectoManu/PDF/NONONO.pdf';
  2.  
  3. open(PDF, $fichero_pdf);
  4. binmode PDF;
  5. my $out;
  6. read (PDF, $out, -s $fichero_out);   # Leemos todo el fichero
  7. close(PDF);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Sobre el tema del Oracle: la experiencia dice que hay que usar el intérprete perl y el módulo DBD::Oracle que trae en la propia distribución de Oracle.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Guardar PDF

Notapor manu8c » 2011-04-04 10:58 @499

El tema es que se supone que Oracle viene instalado. Pero poniendo # C/Perl/bin/perl.exe
Me dice que no encuentra el módulo.

Entonces uso, como uso en todos los CGI, # C/XAMPP/Perl/bin/perl.exe e intento instalar el módulo DBD::Oracle con ppm dándome el siguiente error.

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Cant locate object method 'rvalidate' via package "PPM::XML::PPD::html at C:/xampp/perl/site/lib/PPM.pm line 1682, <> line 2.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


He intentado de mil maneras, pero no me ha sido posible.

Al principio tenía montado todo el proyecto en Mac OS y lo migré todo a Windows debido a que no pude lanzar un servidor Oracle con la consola. Cuando lo migro, instalo Oracle 11, 10, y 9. Y al final consigo hacer que el 9 vaya en XP. Y cuando lo tengo subido no consigo acceder con Perl. Vamos, un caos.

El proyecto en sí, es un generador de reportes automático, y sobre bases de datos MySQL y PostgreSQL funciona bien. El problema es Oracle, pero bueno...


Gracias por la ayuda.

Edito: ahora que leo bien tu mensaje: ¿El módulo DBD que trae el propio Oracle? ¿Me puedes explicar un poco más?
manu8c
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-03-31 09:45 @448

Re: Guardar PDF

Notapor explorer » 2011-04-04 11:54 @537

En los últimos Oracle que instalé en Windows, había una carpeta perl/ dentro de la carpeta de Oracle. Y allí estaba tanto el intérprete como los módulos, entre ellos el DBI y el DBD::Oracle. Hice una prueba, consistente en escribir un programa mínimo que abriese una comunicación con nuestra base de datos, y hacer alguna consulta.

Para hacerlo funcionar, hay que asegurarse de que accedemos al intérprete (la variable de entorno %PATH% tiene una ruta a perl/bin/, y el intérprete es capaz de localizar los módulos y librerías (se puede usar la variable de entorno %PERL5LIB% está correctamente puesta, o indicamos la ruta con -I al perl; o quizás no sea necesario. Ejecutando perl -V podemos ver las rutas en donde está buscando los módulos. Si aparece la ruta donde están los módulos que trae Oracle, entonces no hay que hacer nada).

Pero eso no es todo...

En estos foros hemos comentado varias veces sobre Oracle. Usa el sistema de búsqueda.

En Google encontrarás documentación al respecto. Verás que la opción de instalar desde cero en Windows se hace muy complicada, pues necesitas tener instalada el SDK completo y un compilador de C y otras herramientas (ver fichero README de la distribución DBD::Oracle).

La solución, entonces, era instalar, con ppm, la versión ya compilada, de DBD::Oracle, pero la empresa ActiveState ya no lo distribuye, porque Oracle eliminó la posibilidad de distribuir los clientes de Oracle junto con él (encontrarás más explicaciones sobre esto en la web de ActiveState). Bueno, esto es lo que pasaba hace un par de años. Quizás la situación haya cambiado.

Hoy en día, se recomienda no usar Oracle. MySQL, PostGreSQL, MariaDB tienen potencia suficiente para dar respuesta a buena parte de los requerimientos de casi cualquier empresa. Y las empresas que no tienen más remedio que usar Oracle, casi siempre tienen el dinero suficiente para contratar con Oracle la instalación de una versión de Perl.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Guardar PDF

Notapor manu8c » 2011-04-04 16:55 @746

Gracias por toda la ayuda prestada.

Voy a acabar con todos los retoques del proyecto y si tengo tiempo me pondré con MariaDB. He leído los documentos de Oracle y pinta imposible. Bueno, así podré explicar por qué no he usado Oracle.

De nuevo, gracias por todo.
manu8c
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-03-31 09:45 @448

Re: Guardar PDF

Notapor manu8c » 2011-04-13 12:46 @574

Hola de nuevo, al final he tenido que dejar Oracle, aunque gracias a ti, lo he implementado para MariaDB. Curioso el tema de MariaDB...

Bueno a lo que voy. He hecho que el sistema dé a elegir al usuario si desea salvar el archivo en xls o pdf.
El archivo XLS lo creo sin ningún problema, el problema es otra vez lo mismo de antes.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!"C:\xampp\perl\bin\perl.exe" 
  2.  
  3. use CGI qw(:standard);
  4.  
  5. my $q    = new CGI;
  6. my %FORM = $q->Vars;
  7.  
  8. $name = $FORM{'xls'};
  9.  
  10. open( FILE, "C:/xampp/htdocs/proyectoManu/PDF/$name.xls" )
  11.     or die "File won't open: $!";
  12.  
  13. binmode FILE;
  14.  
  15. $out = '';
  16. read( FILE, $out, -s FILE );
  17. close(FILE);
  18.  
  19. print $q- header(
  20.     -type        => "application/vnd.ms-excel",
  21.     -Disposition => 'attachment; filename="fichero.xls"'
  22. );
  23.  
  24. binmode STDOUT;                        # activamos la salida estándar en modo binario
  25.  
  26. print $out
  27.  
  28.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Buscando por Internet he encontrado que el tipo de cabecera tiene que ser application/vnd.ms-excel. Pero cuando ejecuto el CGI lo que me da la opción de guardar el el código fuente de la página en formato Perl.

Otra cosa, ¿existe alguna página que esté todo Perl documentado aparte de CPAN?

Por ejemplo, no he sido capaz de encontrar los tipos de posibles cabeceras que utiliza el paquete CGI.

Gracias de nuevo.
manu8c
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-03-31 09:45 @448

Siguiente

Volver a Web

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados

cron