Generar PDF usando RML y TRML2PDF de Python desde PHP

rml php python reportlab rml2pdf

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


<?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;
}

?>

 

Archivo hello.rml


<!-- 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>

 

Documentación de Report Markup Language – RML

RML for Idiots An easy introduction to Report Markup Language http://www.reportlab.com/docs/rml-for-idiots.pdf

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.

Anuncios

3 comentarios en “Generar PDF usando RML y TRML2PDF de Python desde PHP

Responder

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