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.