Report Builder — QWeb editor
Edit a report as its real QWeb tree: click any node to select it, edit its field or attributes, or paste an existing template to start from it.
Your Company Name
Street, City · VAT: XX0000000000
Quotation S00025
Customer
Acme Corporation
Paris
Order date
7/7/2026
| Description | Qty | Unit price | Subtotal |
|---|---|---|---|
| Consulting services | 10 | 50.00 | 500.00 |
| Priority support | 5 | 100.00 | 500.00 |
Terms: Payment due within 30 days.
Illustrative — your Odoo company's Document Layout settings decide the real header/footer.
Click any node on the report to edit it here.
The basics
A real QWeb XML tree, not a fixed set of block kinds
Click any node on the canvas — a paragraph, a field, a table cell, a whole section — to select and edit it directly, on a page-shaped surface that resolves against sample data as you build, so it reads like the real report instead of a form next to a separate preview. Because the model underneath is a generic XML tree (matching how Odoo Studio's own report editor works) rather than a fixed menu of block types, pasting an existing real template just works, and every edit always compiles back to real, inspectable QWeb XML — the same "never a black box" guarantee every tool in this hub makes. There's no Odoo instance behind this static site, so it can't pull real records or introspect your model's actual fields; enter a few sample values yourself in the Sample Data tab to see the canvas resolve to something that looks real.
Getting started
Building blocks
The Add tab groups its building blocks the same way Odoo Studio does — click one to insert it right after your current selection.
Full-width content: Text, Field, Title Block, Field & Label, Image, Address Block — each inserts a real element (or elements) right after whatever you have selected.
Text and Field variants that stay inline with surrounding content instead of starting a new block-level element — for a value that belongs mid-sentence.
Data table (a real <table>/<thead>/<tbody> with the header set to repeat on every printed page), Field Column, Text/Field in Cell, and Subtotal & Total (a real account.document_tax_totals call).
Two Columns / Three Columns lay their contents side by side, compiling to genuine Bootstrap grid markup (.row/.col-N) — every column then gets its own width/offset control.
Getting started
Edit on the canvas, seven panels alongside it
The selected node's field/attributes: a schema-driven field picker, widget options, layout (color/background/bold/italic/align/padding/border), column width, visible-if, visible-for, and a guided suggestion list for any other attribute.
Studio's own building-block taxonomy — click one to insert it right after your current selection, or at the end if nothing is selected.
Paste an existing QWeb report — including its own web.html_container/layout-call/div.page boilerplate — and it becomes an editable tree; the pasted layout is even detected and applied to Settings automatically.
Model, module, report title, output type, Print-menu visibility, groups, layout, paper format, orientation, margins, DPI, and the header ruled-line toggle — every field a select, number, or checkbox.
A guided form — one input per field you've actually used, pre-filled with an illustrative example — no JSON, no code. Stays in your browser only.
Optional: point it at your own Odoo (URL, database, login, password or API key) to browse its real installed models, pull a model's real fields into the picker, and load one real sample record — including a row from its one2many relations. The one panel in this tool that talks to a server; see the disclosure inside it for exactly what that means.
The real, generated ir.actions.report record (plus a res.paperformat record whenever your Settings need one) and the full <template> XML — always one click away.
Example
What Settings' paper depth compiles to
Set an orientation, margin, DPI, or the header line toggle away
from the stock defaults, and the generated ir.actions.report
references a real res.paperformat record built from
exactly those values — not a guess.
<record id="paperformat_sale_order_report" model="res.paperformat">
<field name="name">Quotation</field>
<field name="format">a4</field>
<field name="orientation">Landscape</field>
<field name="margin_top">20</field>
<field name="margin_bottom">20</field>
<field name="margin_left">16</field>
<field name="margin_right">16</field>
<field name="header_line" eval="True"/>
<field name="dpi">90</field>
</record>
Referenced by the action's own paperformat_id — the same View Code panel
shows both records together.
FAQ
Frequently asked questions
Can I import an existing QWeb report to edit it here?
Yes — paste it into the Import tab. Because the editor works on a generic XML tree rather than a fixed set of block kinds, any well-formed QWeb is immediately editable: every node becomes selectable, and the standard web.html_container/t-foreach/layout-call/div.page wrapper a real template comes with is automatically detected and stripped (so re-generating the code doesn't double it up), with the detected layout applied to Settings for you.
Does the canvas show exactly what Odoo will render?
No, and it never claims to — it's an illustration built from the sample data you enter, using plain JavaScript formatting. There's no Odoo instance, no ORM, and no live QWeb/Python engine behind this site. The header/footer chrome shown around an External or Internal layout is illustrative too — a placeholder logo and generic company text, not your real company's Document Layout settings, which is what actually decides that look. It's accurate enough to sanity-check your layout and logic, not a substitute for testing inside a real Odoo database.
What exactly does View Code generate?
Two real, paste-ready panels: the ir.actions.report record (model, report type, paperformat reference, groups, and a commented Print-menu binding guide) and the full <template> — wrapped in the layout you picked in Settings. If your Settings use anything beyond the stock A4/US Letter paperformat (a custom orientation, margins, DPI, or the header line toggle), a real res.paperformat record is generated too and referenced automatically — never a guessed reference.
Why doesn't the tool guess the Print-menu binding automatically?
Showing a report in a record's own Print menu needs that model's own external id (e.g. sale.model_sale_order), which is defined by whichever module introduced the model — not something a model name string alone reliably tells you. Rather than emit a plausible-looking but possibly wrong reference, turning on "Show in the Print menu" adds a commented template showing exactly what to fill in.
Is my sample data sent anywhere?
Not unless you opt into the Connect panel — by default it only exists in your browser tab, used to compute the illustrative canvas preview client-side. Nothing is uploaded, logged, or stored.
What does the Connect panel actually do with my Odoo credentials?
It's the one feature in this tool that talks to a server. Browsers block a report page on this site from calling your Odoo instance directly (CORS), so Connect sends your URL/database/login/password-or-API-key to a small backend we run, which calls your Odoo on your behalf and returns the result — models, a model's fields, or one sample record. That backend keeps no database and writes nothing to disk: every request carries its own full credentials and they're discarded the moment that request finishes, never logged, never reused for a later call. Everything else in this tool — the arch editor, the canvas, Sample Data, View Code — still runs entirely in your browser exactly as before; Connect only feeds real schema/data into that same client-side pipeline.
What happens if I reference a field the model doesn't actually have?
Without a live connection, the tool has no ORM to introspect your model's real fields — its client-side schema only knows the common models it ships with (sale.order, account.move, res.partner, and a few more reached through relations), so a typo'd or unknown field path still compiles exactly as written, showing up as an empty or unresolved value on the canvas rather than being caught early. Connecting your own Odoo (the Connect panel) and fetching a model's real fields there closes that gap for exactly the models you fetch — the picker then only offers fields that really exist.
How is this different from Odoo Studio?
Studio is a paid Enterprise app that runs inside a real Odoo instance with live data, live model introspection, and the real QWeb engine — it has a fidelity advantage this tool can't match standalone. This tool is free, needs no login or Odoo instance, and — like every tool in this hub — always shows you the real, copyable QWeb it generates, rather than hiding it behind a black box.
Can I undo a change?
Yes — Ctrl+Z / Ctrl+Shift+Z (or the Undo/Redo buttons) step through every structural edit to the report tree. Report Settings changes are a separate, single reversible form field each, so they're deliberately not part of the same history stack.