En esta entrada generaremos un archivo PDF desde PHP mediante la implementación libre de Tiny RML2PDF que convierte Report Markup Language (RML) de ReportLab de Python en PDF. Para ello usaremos trml2pdf. Básicamente tendremos una interfaz web lograda con PHP la cual hará un llamado al terminal (consola) para invocar a trml2pdf para leer la plantilla RML y presentar de vuelta en la interfaz web el PDF generado.
¿Qué es RML?
RML es Report Markup Language, un miembro de la familia de los lenguajes XML, su dialecto XML es utilizado por rml2pdf para producir documentos en formato de Adobe’s Portable Document (PDF). Los documentos RML pueden ser escritos automáticamente por un programa o manualmente usando cualquier procesador de textos. Los documentos RML son archivos de texto básicos, que pueden ser creados al vuelo por scripts en Python, Perl, o casi cualquier otro lenguaje de programación. RML permite crear documentos en PDF de forma tan simple como crear una página web básica, RML es tan fácil de escribir como HTML o cualquier otro lenguaje de marcado como XML. Es mucho más fácil que tratar de generar un PDF mediante programación.
¿Qué es Tiny RML2PDF ó TRML2PDF?
Tiny RML2PDF es un módulo de Python para crear fácilmente documentos PDF sin necesidad de programación. Puede ser utilizado como una biblioteca de Python o como un binario independiente. Convierte archivos RML, en un dialecto XML que permite definir la apariencia exacta de un documento impreso, a un PDF. Puedes usar tus actuales herramientas para generar un archivo de entrada que describa exactamente la plantilla o layout de un documento impreso, la cual RML2PDF convertirá en un PDF. RML es una alternativa mucho más potente y flexible para XSL: FO.
Trml2pdf fue escrito por Fabien Pinckaers fundador de Oddo
Como generar el PDF desde PHP mediante una plantilla RML usando trml2pdf de Python desde Debian GNU / Linux
El código presentado a continuación es una adaptación de «RML with PHP» de ReportLab: http://www.reportlab.com/documentation/sample-projects/rml-with-php/ ajustada a usar trml2pdf sobre el sistema operativo Debian GNU / Linux.
1 – Instalaremos el modulo de python trml2pdf
#aptitude install python-trml2pdf
2 – Crearemos el directorio y archivos con el código fuente
En el document root de tu servidor web crearemos el directorio «rml-php» el cual contendrá los archivos index.php y hello.rml quedando así:
leninmhs@debian:~/www$ tree rml-php/
rml-php/
├── hello.rml
└── index.php
Archivo index.php
[sourcecode language=»php»]
<?php
/*
This is a sample project which takes user input from an HTML form and generates a PDF containing what the user submitted. An RML file is read which contains the structure of the PDF document. A simple ‘str_replace’ replaces a variable name in the RML source with the value submitted by the user.
A similar principal could be used for generating personalised documents and mail merges by adding more fields such as address and post/zip code. For more advanced uses such as conditionals and for loops, users will probably want make use of a template engine such as Smarty or ReportLab’s own Preppy.
*/
$RML2PDF = "/usr/bin/trml2pdf"; # RML2PDF compiled python file
$RML_INPUT = "hello.rml"; # RML document source
$RML_OUTPUT = "output.rml"; # temporary location for RML after template processing
# If a GET parameter is supplied, generate and return a PDF, otherwise show a form where the user can fill in their name.
if ($_GET[‘q’]) {
# Call function that reads RML file and does templating replacements
$rml_fn = getRML($RML_INPUT, $RML_OUTPUT, $_GET[‘q’]);
# Output file name
$fn = str_replace(".rml", ".pdf", $RML_INPUT);
# Execute the python command with rml2pdf.pyc and relevant arguments
//exec("PYTHONPATH=$PYTHONPATH $PYTHON $RML2PDF_DIR$RML2PDF_EXE $rml_fn");
exec("$RML2PDF $rml_fn > $fn");
# Check a PDF file was created
$fh = fopen($RML_OUTPUT, ‘r’) or die("Can’t open PDF file $fn");
fclose($fh);
# Send PDF file to browser and appropriate headers
header("Content-type: application/pdf");
header("Content-disposition: attachment; filename=$fn");
readfile($fn);
}
else {
?>
<html>
<head>
<title>Create a PDF</title>
</head>
<body>
<h1>Create a dynamic PDF!
<p>Enter your name:</pre>
&nbsp;
<pre>
<form action="." method="get">
<input type="text" name="q" />
<br />
<input type="submit" value="Make a PDF" />
</form>
</body>
</html>
<?php
}
function getRML($RML_INPUT, $RML_OUTPUT, $name) {
# Get content of the RML file
$rml = file_get_contents($RML_INPUT) or die("Can’t open input RML file $RML_INPUT");
# Replace special string ‘##NAME##’ with the variable submitted as GET request
# This is the simplest example of templating. You can use your preferred templating system here instead (e.g. Smarty or Preppy) for more control such as iteration loops.
$rml = str_replace( ‘##NAME##’, $name, $rml);
# Write the new RML string to a temporary file so it can be passed in as an argument to the RML2PDF script
$fh = fopen($RML_OUTPUT, ‘w’) or die("Can’t open output RML file $RML_OUTPUT");
fwrite($fh, $rml);
fclose($fh);
return $RML_OUTPUT;
}
?>
[/sourcecode]
Archivo hello.rml
[sourcecode language=»xml»]
<!– This is very simple RML template for illustrative purposes. –>
<!– –>
<!– A basic RML template has three sections. The ‘template’ –>
<!– section is where you define fixed position elements, along –>
<!– with ‘frames’ containing flowing text. The ‘stylesheet’ –>
<!– section contains re-useable text style definitions. The –>
<!– ‘story’ section contains the text and graphics which fill –>
<!– up the frames defined in the template section. –>
<!– –>
<!– For more information, please read the documentation at –>
<!– http://www.reportlab.com/software/documentation/ –>
<!DOCTYPE document SYSTEM "rml.dtd">
<document filename="hello.pdf">
<template showBoundary="0">
<!–define a ‘frame’ into which the content will flow.–>
<pageTemplate id="main">
<frame id="first" x1="50" y1="200" width="450" height="300"/>
</pageTemplate>
</template>
<stylesheet>
<!– define a text style –>
<paraStyle name="textstyle1" fontName="Helvetica" fontSize="24" leading="24" />
</stylesheet>
<story>
<!–The elements in this section will fill up the frames –>
<!–defined in the section above. –>
<!–The text inside double hashes is replaced dynamically–>
<!–inside Default.aspx–>
<para style="textstyle1">
Welcome <b>##NAME##</b>, to the world of RML!
</para>
</story>
</document>
[/sourcecode]
Documentación de Report Markup Language – RML
RML User Guide http://www.reportlab.com/docs/rml2pdf-userguide.pdf
Conclusión RML + TRML2PDF + PYTHON + PHP + PDF
En pocos pasos vimos como implementar una solución elegante para generación de PDF ideal para arquitecturas de aplicaciones web que necesiten escapar al servidor web para generar PDF sea por tiempo ó volumen de datos que deban gestionar lo cual excedería el tiempo de ejecución ó la memoria asignada al servicio web. La solución vista anteriormente separa la presentación del PDF deseado mediante RML a diferencia de las soluciones cotidianas en php de armar la presentación y sus contenidos al vuelo consumiendo mas recursos, así como la generación del PDF directamente por terminal vía trml2pdf con lo cual nos desprendernos de todas las restricciones del servicio web y captamos todas las posibilidades y utilitarios del sistema operativo GNU / Linux.
Excelente.. gracias por el aporte.
Estamos para servirle 😉
Un excelente tutorial, gracias por compartir.