Documents and Reports

Generate documents

Generating reports and documents is an important part of any application. Python and Qt provide various ways to generate documents. Each of them with its own advantages and disadvantages.

Method Advantages Disadvantages
PDF documents through reportlab
  • Perfect control over layout
  • Excellent for mass creation of documents
  • Relatively steep learning curve
  • User cannot edit document
  • Easy to get started
  • Print preview within Camelot
  • No dependencies
  • Not much layout control
  • User cannot edit document
Docx Word documents
  • User can edit document
  • Proprietary format
  • Word processor needed

Camelot leaves all options open to the developer.

Please have a look at Creating a Report with Camelot to get started with generating documents.

Generating a document or report is nothing more than yielding the appropriate action step during the model_run() method of an Action.

Action steps usable for reporting are :

  • camelot.view.action_steps.print_preview.PrintPreview
  • camelot.view.action_steps.print_preview.PrintHtml
  • camelot.view.action_steps.print_preview.PrintJinjaTemplate
  • camelot.view.action_steps.open_file.OpenFile
  • camelot.view.action_steps.open_file.OpenStream
  • camelot.view.action_steps.open_file.OpenJinjaTemplate

HTML based documents

        class MovieSummary( Action ):
            verbose_name = _('Summary')
            def model_run(self, model_context):
                from camelot.view.action_steps import PrintHtml
                movie = model_context.get_object()
                yield PrintHtml( "<h1>This will become the movie report of %s!</h1>" % movie.title )

The supported html subset is documented here :

Alternative rendering

Instead of QtGui.QTextDocument another html renderer such as QtWebKit.QWebView can be used in combination with the camelot.view.action_steps.print_preview.PrintPreview action step. The QWebView class has complete support for html and css.

        class WebkitPrint( Action ):
            def model_run( self, model_context ):
                from PyQt4.QtWebKit import QWebView
                from camelot.view.action_steps import PrintPreview
                movie = model_context.get_object()
                document = QWebView()
                document.setHtml( '<h2>%s</h2>' % movie.title )
                yield PrintPreview( document )

Docx based documents

Create a template document with MS Office

Create a document using MS Office and with some placeholder text on places where you want to insert data.


And save it as an xml file :


Clean the XML generated by MS Office

The XML file generated by MS Office can be cleaned using xmllint:

xmllint --format template.xml > template_clean.xml

Replace the placeholders

The template will be merged with the objects in the selection using jinja, where the object in the selection will be available as a variable named obj and the time of merging the document is available as now: