How To Using QWeb for Advanced PDF Reporting in Odoo


✅ What is QWeb?

QWeb is Odoo’s XML-based templating engine used for:

  • Generating PDF reports (via wkhtmltopdf)
  • Rendering web templates, portal views, and emails
  • Designing highly customized and styled reports

QWeb is the backbone for Odoo’s printable documents like invoices, sales orders, delivery slips, and custom business reports.


📌 Key Characteristics

Feature

Description

Templating language

XML-based with dynamic Python expressions

Output format

HTML → converted to PDF using wkhtmltopdf

Engine used

report.report_sxw internally calls QWeb

Styling

Based on Bootstrap-like HTML + inline CSS


🧩 Real Business Use Case

Generate a custom Sales Summary Report with company logo, partner info, and a table of sale order lines.



🛠️ Steps to Create an Advanced QWeb PDF Report


1. Define the Report Action (XML)


<report

    id="report_sale_summary"

    model="sale.order"

    string="Sales Summary"

    name="custom_module.report_sale_summary"

    file="custom_module.report_sale_summary"

    report_type="qweb-pdf"

/>


  • model: The model this report applies to
  • name: Points to the QWeb template ID
  • report_type: Should be qweb-pdf for printable reports


2. Create the QWeb Template


<template id="report_sale_summary">

    <t t-call="web.html_container">

        <t t-foreach="docs" t-as="order">

            <div class="page">

                <h2>Sales Summary - <t t-esc="order.name"/></h2>

                <p><strong>Customer:</strong> <t t-esc="order.partner_id.name"/></p>

                <p><strong>Date:</strong> <t t-esc="order.date_order.strftime('%Y-%m-%d')"/></p>

                

                <table class="table table-sm">

                    <thead>

                        <tr>

                            <th>Product</th>

                            <th>Qty</th>

                            <th>Price</th>

                            <th>Subtotal</th>

                        </tr>

                    </thead>

                    <tbody>

                        <t t-foreach="order.order_line" t-as="line">

                            <tr>

                                <td><t t-esc="line.product_id.name"/></td>

                                <td><t t-esc="line.product_uom_qty"/></td>

                                <td><t t-esc="line.price_unit"/></td>

                                <td><t t-esc="line.price_subtotal"/></td>

                            </tr>

                        </t>

                    </tbody>

                </table>

            </div>

        </t>

    </t>

</template>



3. Download from UI or Call Programmatically

From form view of sale.order, click Print > Sales Summary.

You can also generate via code:

report = self.env.ref('custom_module.report_sale_summary')

pdf, _ = report._render_qweb_pdf([order.id])



🎨 Styling Tips

  • Use class="page" to force page breaks.
  • Odoo supports Bootstrap-like classes: table, text-center, mt-3.
  • Add <style> blocks if needed for layout tuning (avoid external CSS).



✅ Summary Table


Element

Notes

Template Engine

QWeb (XML-based, t-call, t-esc, t-if, etc.)

PDF Engine

wkhtmltopdf

Styling

Bootstrap-like HTML, inline <style> supported

Best Practice

Separate logic from template, keep templates clean

Security

Use t-esc to auto-escape values



🧠 Best Practices

  • Use t-esc to escape values for safety (XSS prevention).
  • Avoid heavy logic in templates – keep it in models or helpers.
  • Use report_type='qweb-pdf' for print and 'qweb-html' for preview.