Development Book V17:Others

How to create Qweb based pdf reports

Odoo plays a crucial role in enhancing business efficiency. Analyzing different facets is essential for the organization's progress within the ERP system, and this is where reporting comes into play.

Qweb serves as a reporting engine designed to generate PDF reports by efficiently managing data through XML. The Qweb template engine typically transforms XML into HTML, and the actual rendering of PDFs is carried out by the wkhtmltopdf tool. Reports are generated through a combination of report actions and report templates specified for the respective actions.

Report Action:

Report actions are initiated when there is a need to generate reports. These actions are written within the XML file established in the report section of the module. A typical representation of a report action could be as follows:

 <record id="action_report_student_detail" model="">
   <field name="name">Student Detail</field>
   <field name="model">student.detail</field>
   <field name="report_type">qweb-pdf</field>
   <field name="report_name">student_registration.report_student_detail</field>
   <field name="report_file">student_registration.report_student_detail</field>
   <field name="print_report_name">'Student Report - %s' % (</field>
   <field name="binding_model_id" ref="model_student_detail"/>
   <field name="binding_type">report</field>

This specific report is related to the sale order module. Let's break down the key attributes in this XML record:

1. id: This uniquely identifies the record. In this case, it is set to "action_report_student_detail."

2. model: Specifies the model with which the report is associated. In this case, the report is associated with the "student.detail" model.

3. report_type: Defines the type of report. Here, it's set to "qweb-pdf," indicating that the report is in QWeb PDF format.

4. report_name: Specifies the technical name of the report. In this example, it is "student_registration.report_student_detail."

5. report_file: Specifies the name of the report file. In this case, it is also "student_registration.report_student_detail"

6. print_report_name: Defines the name that will be displayed when the report is printed

7. binding_model_id: Refers to the model (in this case, "model_student_detail") to which the report is bound.

8. binding_type attribute: Specifies the type of binding, which is set to "report" in this case.

Report Templates:

The report structure is defined within the report templates, which are XML files located inside the module's report file. Within these templates, HTML is utilized to tailor the report layout according to specific design requirements.

<template id="report_student_detail">
   <t t-call="web.html_container">
       <t t-call="web.internal_layout">
           <t t-foreach="docs" t-as="rec">
               <div class="text-center">
                       <u>Student Report</u>
               <t t-esc=""/>

The id of the template is external if that is mentioned in the report action. By calling the external_layout, the report will get the default layout of Odoo. The template always contains the variables like time, user, res_company, website, web_base_url, and context_timestamp.

Python Function:

The corresponding Python function for printing the report might look like this:

def action_print(self):
   return (self.env.ref(

Then the output of the function will is as shown below:


Multi Print:

In Odoo 17, there's a new feature called "do_multi_print" that makes it easy to print several reports at the same time. This can be achieved through the following JavaScript function:

       /** @odoo-module **/

import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { sprintf } from "@web/core/utils/strings";

async function doMultiPrint(env, action) {
   for (const report of action.params.reports) {
       if (report.type != "") {
 "Incorrect type of action submitted as a report, skipping action"), {
               title: _t("Report Printing Error"),
       } else if (report.report_type === "qweb-html") {
                   _t("HTML reports cannot be auto-printed, skipping report: %s"),
               , {
               title: _t("Report Printing Error"),
       // WARNING: potential issue if pdf generation fails, then action_service defaults
       // to HTML and rest of the action chain will break w/potentially never resolving promise
       await{ type: "", });
   if (action.params.anotherAction) {
   } else if (action.params.onClose) {
       // handle special cases such as barcode
   } else {

registry.category("actions").add("do_multi_print", doMultiPrint);

The provided JavaScript code defines an Odoo module that facilitates the printing of multiple reports. The doMultiPrint function, marked with the Odoo module comment, is asynchronous and takes two parameters: env and action. The function iterates through the specified reports, checks their types and report formats, and triggers the printing using Odoo's method. The module registers the doMultiPrint function under the "actions" category in the Odoo registry, making it available for use as an action in the Odoo system.

The Python function for performing multi-printing is exemplified below.

 def action_print(self):
   return {
       'type': 'ir.actions.client',
       'tag': 'do_multi_print',
       'context': {},
       'params': {
           'reports': [self.env.ref(
                       .report_action(self), self.env.ref(


● 'type': 'ir.actions.client': Specifies the type of action as a client action in Odoo.

● 'tag': 'do_multi_print': Associates this action with the previously defined client action named do_multi_print.

● 'context': {}: Provides an empty context for the action.

● 'params': Contains a dictionary with a key 'reports', which holds a list of reports to be printed.

The list includes two reports, presumably related to student details and student attendance.

First print is:


The second print is:


By utilizing the do_multi_print feature, this method enables the simultaneous printing of any number of reports.



Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635



Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.



Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message