Integrating ReportLab into your website

Report Markup Language from ReportLab is the simplest way to programatically produce great looking PDF documents with the minimum of fuss.

It's an XML dialect which, combined with a python module which converts the XML files into PDF. Because RML files are just plain text, and Python runs on a plethora of platforms, it's very easy to plug RML into your existing solution or build something new using your favourite language.

Using RML inside a web framework

How to produce dynamic PDF documents using RML and your favourite web framework. These examples show how to integrate a small "Hello, World"-type dynamic PDF solution into popular web frameworks.

 

RML with PHP

You should download the ZIP archive of the entire project to get the full code listing and to try it out.


rml-sample-php.zip

(3.3 KB, 18 Mar 2010, md5 checksum=38f9fff2dae7ad16ebfd6cd47c1bf3e3)


Introduction

Report Markup Language™ is an XML-style language created by ReportLab that describes the precise look of a printed page. This sample application shows how you can use the RML2PDF conversion library from within PHP.

RML is commercial software which is part of the ReportLab PLUS package. You will need to create a user account to download a trial version of ReportLab PLUS.

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 text pre-processor.

Code overview

Here are some explanations of the most interesting parts of the sample application. The downloadable archive also contains a README file and commented code.

First of all index.php has some constants defined. You will want to set $RML2PDF_DIR to your own location. Windows users will also probably need to change $PYTHON to the location of python.exe.

<?php

$PYTHON = "python";  # You can use a custom python build/version
$PYTHONPATH = "\$PYTHONPATH";  # Override PYTHONPATH if you installed somewhere unusual
$RML2PDF_DIR = "/path/to/rlextra/rml2pdf/";  # Where you installed rlextra
$RML2PDF_EXE = "rml2pdf.pyc";  # RML2PDF compiled python file
$RML_INPUT = "hello.rml";  # RML document source
$RML_OUTPUT = "output.rml";  # temporary location for RML after template processing

...

There are two ways the script can be called. 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']) {
    # Create a PDF using 'q' variable and send it to the browser
}
else {
    # This is what initially will get returned - HTML with a form for the user to enter their name
?>
...
    <form action="." method="get">
        <input type="text" name="q" />
        <input type="submit" value="Make a PDF" />
    </form>
...
<?php
}
...

The getRML() function takes a source RML XML file $RML_INPUT, replaces the occurrence ##NAME## with the supplied variable $name (GET parameter q in this case), then finally writes out the resulting string into the file named $RML_OUTPUT. This is the simplest way to make the content dynamic but you are expected to use another template system if you require more advanced features like conditionals and loops.

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

When we receive our GET parameter q, call getRML(), then pass the the generated RML file along with other parameters to the rml2pdf script on the command line. We then read in the generated PDF file and return it to the browser with the correct mime/content types. If we do not set these, PHP will assume we are returning text/html and the browser will try and display binary data.

# Call function that reads RML file and does templating replacements
$rml_fn = getRML($RML_INPUT, $RML_OUTPUT, $_GET['q']);

# Execute the python command with rml2pdf.pyc and relevant arguments 
exec("PYTHONPATH=$PYTHONPATH $PYTHON $RML2PDF_DIR$RML2PDF_EXE $rml_fn");

# Output file name
$fn = str_replace(".rml", ".pdf", $RML_INPUT);

# 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);
 

RML with TurboGears 2

You should download the ZIP archive of the entire project to get the full code listing and to try it out.


rml-sample-turbogears2.zip

(4.0 KB, 23 Mar 2010, md5 checksum=5c10cf7bc44ba77ff6dc4a405bffe554)


Introduction

Report Markup Language™ is an XML-style language created by ReportLab that describes the precise look of a printed page. This sample application shows how you can use the RML2PDF conversion library from within Turbogears 2.

RML is commercial software which is part of the ReportLab PLUS package. You will need to create a user account to download a trial version of ReportLab PLUS.

Integrate Report Markup Language into your TurboGears project and add great looking dynamic PDF output to your website. This sample project shows you how - it's a simple demonstration of how to merge an RML 'template' with user-submitted, variable content - in this case the user's name - and convert the output into a PDF which is returned to the browser.

Its easy to expand on the principles shown here. Use Genshi, or another templating engine, to include conditionals and loops, and create complex PDF documents with any kind of dynamic content.

Code overview

Here's a walkthrough of the most interesting parts of the sample application. The downloadable archive also contains a README file with installation instructions and commented code.

The project serves up a simple HTML form. The user enters their name and clicks the 'submit' button, and this calls a function in the RootController class which uses the Genshi templating engine to substitute the name entered in the form in the relevant part of our RML template ('hello.rml')

from genshi.template import TemplateLoader
loader = TemplateLoader(os.getcwd() + '/rptlabrmlsample/templates/')
rml = loader.load('hello.rml')
return rml.generate(name=personName).render('xml')

Next, create a CStringIO buffer and send the rml we've created to the rml2pdf.go() function. The resulting PDF is returned as a byte array.

from rlextra.rml2pdf import rml2pdf
rml = mergeRML(q)  #merge the template and variables
buf = cStringIO.StringIO()
rml2pdf.go(rml, outputFileName=buf) #creates the pdf
pdfData = buf.read()

The only remaining task is to return the PDF to the user. Set the appropriate properties in the response object, and return the contents of the buffer.

response.headers["Content-Type"] = "application/pdf"
response.headers["Content-disposition"] = "attachment; filename=report.pdf"
response.headers["Content-Length"] = len(a)
return a
 

RML on Rails

You should download the ZIP archive of the entire project to get the full code listing and to try it out.


rml-sample-ruby.zip

(13.5 KB, 25 Mar 2010, md5 checksum=d5b56ed8acb88d24ad8a4eff59f02e16)


Introduction

Report Markup Language™ is an XML-style language created by ReportLab that describes the precise look of a printed page. This sample application shows how you can use the RML2PDF conversion library from Ruby on Rails.

RML is a commercial software which is part of the ReportLab PLUS package. You will need to create a user account to download a trial version of ReportLab PLUS.

This is a sample project which takes user input from an HTML form and generates a PDF containing what the user submitted. An rml template is processed using the ruby on rails template engine to substitute a string dynamically. It then writes the text to a temporary file and uses the ruby system function to call the rml2pdf python module with the relevant command line string. This converts the RML to a PDF, and the file is returned to the browser.

Code overview

Here are some explanations of the most interesting parts of the sample application. The downloadable archive also contains a README file and commented code.

First of all rml_sample_controller.rb has some constants defined. You will want to set rml2pdfpyc to your own location. Windows users will also probably need to change python to the location of python.exe.

python = "python"                            # You can use a custom python build/version
pythonpath = '$PYTHONPATH'                   # Override PYTHONPATH if you installed somewhere unusual
rml2pdfpyc = '/path/to/rml2pdf.pyc'          # Path to RML2PDF compiled python file
tmp_path = '/tmp/' 
tmp_rml_file = "#{tmp_path}rml_sample.rml"   # Path to rml generated rml file
pdf_filename = 'hello.pdf'                   # PDF filename - used in rml
tmp_pdf_file = "#{tmp_path}#{pdf_filename}"  # Path to rml generated pdf file

...

RML is generated using render_to_string function. Result is saved to temporary file.

rml = render_to_string :template => "rml_sample/rml/sample.rml",
    :locals => {
        :name => params[:name],
        :pdf_filename => pdf_filename
    }

# create rml file
file = File.open(tmp_rml_file, 'w')
file.puts(rml)
file.close()

...

The generated RML file along with other parameters are passed to the rml2pdf script on the command line. At this point we just read the generated PDF file and return it to the browser with the correct mime/content types. If we do not set these, RoR will assume we are returning text/html and the browser will try and display binary data.

system("PYTHONPATH=#{pythonpath} python #{rml2pdfpyc} #{tmp_rml_file}")

# open pdf file
pdf_file = open(tmp_pdf_file, 'r')

# send pdf to browser
send_data(pdf_file.read, :filename => pdf_filename, :type => "application/pdf")
 

RML2PDF with Django

You should download the ZIP archive of the entire project to get the full code listing and to try it out.


rml-sample-django.zip

(5.9 KB, 01 Dec 2010, md5 checksum=0279b9699042e868079b168e1362d7cc)


Introduction

Report Markup Language™ is an XML-style language created by ReportLab that describes the precise look of a printed page. This sample application shows how you can use the RML2PDF conversion library from within the Django web framework.

RML is commercial software which is part of the ReportLab PLUS package. You will need to create a user account to download a trial version of ReportLab PLUS.

It's simple to integrate Report Markup Language into your Django project, and add great looking dynamic PDF output to your website. RML lets you add complex and great looking PDF document output to your site, with the minimum of development time.

This is a simple demonstration of how to merge an RML 'template' with user-submitted, variable content - in this case the user's name - and convert the output into a PDF which is returned to the browser.

This project simply reads the template file 'hello.rml' into memory, and then substitutes a particular string using the Django templating engine. It then uses the rml2pdf python module's 'go' method to create a PDF from the RML. The resulting PDF is turned into a byte stream and returned to the browser.

Code overview

Here's a walkthrough of the most interesting parts of the sample application. The downloadable archive also contains a README file and commented code.

The code generates a PDF file with a single page containing the text "Welcome <name> to the world of RML", where <name> is a variable that you submit through a Django form. The form is really simple with one field to submit:

<p>Enter your name:</p>
<form action="/getPDF/" method="get">
    <input type="text" name="q">
    <br>
    <input type="submit" value="Make a PDF">
</form>

A function in views.py loads the RML template into a Template object and substitutes the variable.

t = Template(open('hello.rml').read())
c = Context({"name": name})
rml = t.render(c)

The resulting RML is passed into the rml2pdf.go() to generate the PDF.

buf = cStringIO.StringIO()
rml2pdf.go(rml, outputFileName=buf)
pdfData = buf.read()

Set the relevant properties for the response object and return the PDF to the browser.

response = HttpResponse(mimetype='application/pdf')
response.write(pdfData)
response['Content-Disposition'] = 'attachment; filename=output.pdf'
return response
 

RML with Microsoft .NET

You should download the ZIP archive of the entire project to get the full code listing and to try it out.


rml-sample-dotnet.zip

(13.4 KB, 26 Mar 2010, md5 checksum=9a4a412630366a625f86f593b6c1d392)


Introduction

Report Markup Language™ is an XML-style language created by ReportLab that describes the precise look of a printed page. This sample application shows how you can use the RML2PDF conversion library from within the Microsoft .NET framework.

RML is commercial software which is part of the ReportLab PLUS package. You will need to create a user account to download a trial version of ReportLab PLUS.

It's simple to integrate Report Markup Language into your Microsoft .NET project, and add great looking dynamic PDF output to your .NET based website or desktop application. And you don't need to learn Python to do so - if you can code in HTML, you'll find RML easy to learn. RML lets you add complex and great looking PDF document output to your site, with the minimum of development time.

This sample project shows you how. It's a simple demonstration of how to merge an RML 'template' with user-submitted, variable content - in this case the user's name - and convert the output into a PDF which is returned to the browser.

It's easy to expand on the principles demonstrated here. When merging the template with the variable content, we've used a simple string 'replace' function. However, for more advanced output, users will probably want make use of a template engine such as StringTemplate.NET or NVelocity which will help you construct the RML using loops, conditionals and other programming constructs.

Code overview

Here's a walkthrough of the most interesting parts of the sample application. The downloadable archive also contains a README file and commented code.

The project serves up a simple HTML form, and the code is all behind the 'click' event for the 'submit' button. First, we set up a Process object from the System.Diagnostics namespace. This is what makes it possible to execute the Python module rml2pdf from inside the .NET application - just give it the name of the python executable.

Dim pythonProcess As Process
Dim pythonPSI As ProcessStartInfo
pythonPSI = New ProcessStartInfo("python")

Next, read the RML template ('hello.rml') into an IO.StreamReader object, and use the 'replace' function to substitute the user's name with the placeholder in the template.

Dim sw As IO.StreamWriter = New IO.StreamWriter(tmpFileName)
Dim txt As String
txt = sr.ReadToEnd
txt = txt.Replace("##NAME##", name)

The resulting rml file is saved to disk in a temporary location. Then a command line string is constructed in the format "<path\to\rml2pdf.pyc> <path\to\tempRMLfile.rml>" and passed to the process object, which executes Python with that string as an argument. The rml2pdf python module creates the PDF document in the current working directory, and returns the filename, which can be read from the Process.StandardOutput.Readline() function.

pythonProcess = New Process()
pythonProcess.StartInfo = pythonPSI
pythonProcess.Start()

Dim outputPDF As String = System.IO.Path.GetTempPath & pythonProcess.StandardOutput.ReadLine()

Now we have a PDF document in the temp directory, and the only remaining task is to return it to the user. So we get the file into a IO.BinaryReader object, set the appropriate properties in the response object, and use Response.BinaryWrite() to send it back to the browser.

Dim input As New IO.FileStream(outputPDF, IO.FileMode.Open)
Dim reader As New IO.BinaryReader(input)
Dim bytes() As Byte
bytes = reader.ReadBytes(CInt(input.Length))
input.Close()

Response.AddHeader("Content-Disposition", "attachment;filename=ReportLabRMLSample.pdf")
Response.BinaryWrite(bytes)