Appy framework offers pod, a library that allows to easily generate documents whose content is dynamic.
First of all download it from https://launchpad.net/appy and install it to your python environment (just copy appy folder to dist-packages/site-packages)
Let's assume for example we have a simple db table containings informations about some persons as follows:
db.define_table('persons', Field('name','string'), Field('surname','string'), Field('adress','string', required=False))
Now, we want to create a report which lists all these persons.
First of all we need to create a template file to generate our report, we can easily set up a nice template using openoffice/libreoffice writer.
Our template will be very simple, just a table with a column for each field of the table and a row for each person, let's create a table with 3 columns and 2 rows and set the fields description in the first row.
The template needs to be informed that we need to repeat the second row for each person, in the Insert menu->Comment
do row for p in persons
Now we just have to set the variables names in the second row, in the Edit menu->Modifications->Record and add respectively: p.name, p.surname, p.adress.
The only thing to remember is that template variables and python code variables must have the same names!
Let's see what we have to do in our python code; in our controller:
import os import uuid import subprocess from appy.pod.renderer import Renderer def createReport(): persons = [] for person in db().select(db.persons.ALL): persons.append(dict(name=person.name, surname=person.surname, adress=person.adress)) # Report creation template_file = os.path.join(request.folder, 'private', 'template.odt') tmp_uuid = uuid.uuid4() output_file_odt = "/var/tmp/%s.odt"%tmp_uuid output_file_pdf = "/var/tmp/%s.pdf"%tmp_uuid beingPaidForIt = True renderer = Renderer(template_file, locals(), output_file_odt) renderer.run() subprocess.Popen("libreoffice --headless --invisible --convert-to pdf %s --outdir %s "%(output_file_odt, "/var/tmp") ,shell=True) while True: if os.path.exists(output_file_pdf): break data = open(output_file_pdf, "rb").read() for file in [output_file_odt, output_file_pdf]: os.unlink(file) response.headers['Content-Type'] = 'application/pdf' response.headers['Content-Disposition'] = 'attachment; filename=PersonsListing.pdf' return data
Appy pod creates an odt file but we want to send to the browser the pdf, so we call libreoffice via server mode to convert the odt to pdf file, when it's done we delete both files and then we send back the pdf report.
Hope this helps!
Here the Template file
Comments (0)