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")