Custom Paper Format in Odoo QWeb Reports
How to create, configure, and bind custom paper formats to Odoo QWeb reports — covering UI setup, XML override, margin control, and header/footer sizing.
Odoo's QWeb engine renders PDF reports using a paper format that controls page size, orientation, margins, and the space reserved for headers and footers. The default paper format (A4 portrait) suits most standard documents — invoices, purchase orders, delivery slips. When a business needs a custom document size, a landscape layout, or specific margin widths for pre-printed stationery, a custom paper format is required.
This guide covers three approaches: configuring a paper format through the Odoo UI, binding it to a report action in XML, and overriding it directly in a QWeb report template. All three approaches are compatible and can be combined.
What Is a Paper Format in Odoo?
A paper format in Odoo is a record in the `ir.paper.format` model that defines the physical and layout properties of a printed PDF page. Every `ir.actions.report` (report action) has a `paper_format_id` field — when that field is empty, the report falls back to the company default format.
| Field name | Type | Description | Common values |
|---|---|---|---|
| name | Char | Display name shown in the UI and report action dropdown | "A4 Custom", "Invoice Landscape" |
| default | Boolean | If True, this format is the company default for all reports without an explicit paper_format_id | True / False |
| format | Selection | Named standard size — used when custom dimensions are not set | A4, A3, Letter, Legal |
| orientation | Selection | Portrait or Landscape page rotation | Portrait / Landscape |
| margin_top / margin_bottom / margin_left / margin_right | Float | Page margins in mm. These values pass directly to wkhtmltopdf | 10.0, 15.0, 20.0 |
| header_line | Boolean | Draw a horizontal rule below the header area | True / False |
| header_spacing | Integer | Vertical space (in mm) between the top of the page and the start of body content. Must be ≥ the height of your QWeb header template. | 30, 40, 60 |
| page_width / page_height | Float | Custom page dimensions in mm. When set, these override the `format` field. | 210.0 / 297.0 for A4 |
Create a Custom Paper Format via the Odoo UI
- Navigate to Settings → Technical → Reporting → Paper Formats.
- Click New.
- Set Name to a descriptive identifier (e.g. "Invoice A4 Narrow Margin").
- Choose Format (A4, A3, Letter, Legal) or leave it blank if you will set custom dimensions via Page Width / Page Height.
- Set Orientation to Portrait or Landscape.
- Set the four margin fields (Top, Bottom, Left, Right) in mm. A safe starting point for invoices is 10 / 10 / 10 / 10.
- Set Header Spacing in mm. This controls the gap between the page top edge and where body content begins. Start with the height of your header in mm and add 5–10 mm buffer.
- Save the record. The paper format is now available in the Paper Format dropdown of any report action.
Bind a Paper Format to a Report Action in XML
For custom modules, define both the paper format record and the report action binding in XML data files. This approach is repeatable, version-controlled, and installs correctly on any Odoo instance.
Step 1 — Define the paper format record
<!-- data/paper_format_data.xml -->
<odoo>
<record id="paperformat_invoice_custom" model="ir.paper.format">
<field name="name">Invoice A4 Narrow Margin</field>
<field name="default" eval="False"/>
<field name="format">A4</field>
<field name="orientation">Portrait</field>
<field name="margin_top">10.0</field>
<field name="margin_bottom">10.0</field>
<field name="margin_left">10.0</field>
<field name="margin_right">10.0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">40</field>
</record>
</odoo>Step 2 — Bind the paper format to the report action
<!-- report/account_invoice_report.xml -->
<odoo>
<!-- Define the report action and reference the paper format -->
<report
id="account_invoices_custom"
model="account.move"
string="Custom Invoice"
report_type="qweb-pdf"
name="your_module.report_invoice_custom_document"
file="your_module.report_invoice_custom_document"
paper_format="your_module.paperformat_invoice_custom"
print_report_name="(object.name or 'Invoice')"
/>
</odoo>QWeb Report Template — Header, Footer, and Body Layout
The paper format controls the available print area. The QWeb report template controls what renders within that area. The three parts — header, footer, and body — are defined using specific `t-call` inheritance points in Odoo's base report layout.
<!-- report/report_invoice_custom_document.xml -->
<odoo>
<!-- Outer wrapper must inherit web.html_container -->
<template id="report_invoice_custom_document">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="web.external_layout">
<t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)"/>
<!-- Body content goes here -->
<div class="page">
<h2 t-field="doc.name"/>
<p t-field="doc.invoice_date"/>
<!-- ... your report body ... -->
</div>
</t>
</t>
</t>
</template>
</odoo>Custom header and footer templates
Odoo renders headers and footers via `web.external_layout_header` and `web.external_layout_footer`. To replace them for a specific report, inherit these templates and restrict the override with `t-if` on the `report_name` variable.
<!-- Custom header for a specific report only -->
<template id="report_invoice_custom_header"
inherit_id="web.external_layout_header">
<xpath expr="//div[hasclass('header')]" position="replace">
<!-- Only override for our custom report -->
<t t-if="report_name == 'your_module.report_invoice_custom_document'">
<div class="header" style="height: 35mm;">
<!-- Your custom header HTML here -->
<img t-att-src="'/web/image/res.company/%s/logo' % company.id"
style="max-height: 30mm;"/>
<div class="text-right">
<strong t-field="company.name"/>
</div>
</div>
</t>
<t t-else="">
<!-- Fall back to default header for all other reports -->
<t t-call="web.external_layout_standard_header"/>
</t>
</xpath>
</template>Common Paper Format Issues and Fixes
| Symptom | Root cause | Fix |
|---|---|---|
| Header overlaps body content on every page | header_spacing is smaller than the rendered height of the header HTML | Increase header_spacing on the paper format. Measure your header height in a browser at 96 DPI (1 mm ≈ 3.78 px), then add 5–10 mm buffer. |
| PDF is A4 even though a custom page_width / page_height was set | The `format` field on ir.paper.format is still set to "A4", which overrides the custom dimensions in some wkhtmltopdf versions | Clear the `format` field (set it to a blank / custom option) when using page_width / page_height. Both fields cannot be active simultaneously. |
| Report ignores the paper format set on the report action | A company-level default paper format is set to `default = True` and is overriding the action-level format | Either unset `default` on the company paper format, or explicitly set `paper_format_id` on the report action rather than relying on the default. |
| Right margin is ignored; content bleeds off the page | Hardcoded width styles in the QWeb template (e.g. `width: 210mm`) do not account for margins | Use percentage widths or `max-width: 100%` in your QWeb CSS instead of absolute mm widths. Let the paper format margins define the print area. |
| Footer content is cut off at the bottom of the page | margin_bottom is too small for the footer HTML height | Increase margin_bottom on the paper format. The footer renders within the bottom margin area — if the footer HTML is taller than margin_bottom, it gets clipped. |
Version Notes and Spot-Check Guide
| Odoo version | PDF engine | UI path | Notable change |
|---|---|---|---|
| Odoo 16 / 17 | wkhtmltopdf (primary) | Settings → Technical → Reporting → Paper Formats | Headless Chrome added as optional engine for some reports; QWeb paper format API unchanged |
| Odoo 18 | wkhtmltopdf (primary) | Settings → Technical → Reporting → Paper Formats | No API changes to ir.paper.format. Header/footer template inheritance unchanged. |
| Odoo 19 | wkhtmltopdf (primary) | Settings → Technical → Reporting → Paper Formats | No API changes to ir.paper.format. Verified June 2026. |
| Odoo 20 (expected late 2026) | TBC — run spot-check above | Expected stable — verify on release | Check if wkhtmltopdf is still primary or replaced by headless Chrome as default. The paper format model API is expected to remain stable. |
Need help with custom Odoo reports for your Saudi or Bahrain business?
iWesabe's Odoo development team handles custom QWeb report templates, paper format configuration, and ZATCA-compliant invoice layouts. Get a scoping call.
Frequently Asked Questions
Where is the Paper Formats menu in Odoo 19?
How do I set a custom page size (not A4 or Letter) in Odoo?
How do I apply a paper format only to one report, not all reports?
Why does my QWeb report header overlap the body content?
Can I use a different paper format for the first page vs. subsequent pages?
Does the paper format affect the report when printed from screen (not downloaded as PDF)?

iWesabe Editorial Team
Practitioner insights on Odoo ERP, ZATCA compliance, and Saudi enterprise digital operations — written by iWesabe's consulting, finance, and engineering teams.
Related Articles
Why Local Support Matters in Odoo ERP Implementations in Saudi Arabia (2026)
Offshore Odoo partners get the demos right and the rollouts wrong. The on-the-ground discipline a Saudi CFO, COO, or IT lead actually needs from a local Odoo partner — defined, costed, and audit-ready.
Best Odoo ERP Software Provider in Saudi Arabia: 7 Buyer-Diligence Markers (2026)
What separates an audit-defensible Odoo partner from a sales pitch: certification chain, named-client references, regulatory depth (ZATCA / GOSI / PDPL), Arabic-hours support, commercial model, methodology, and exit clause — with the red flags to watch for.
What Is Odoo ERP? The Complete Guide to Odoo (Formerly OpenERP) for Saudi Businesses
From TinyERP to OpenERP to Odoo 19 — how the platform evolved and why 12 million+ businesses run on it today
Explore Related Solutions
Financial Management
Automate your Saudi Arabia accounting — ZATCA Phase 2 e-invoicing, VAT returns, Zakat provisioning, multi-currency bank reconciliation, and real-time financial reporting — all inside one connected Odoo platform. Fully localised for KSA and the GCC by iWesabe.
ExploreCRM & Customer Relationship Management
Turn every lead into a closed deal. Odoo CRM gives your sales team a structured Kanban pipeline, automated follow-up sequences, and a 360° customer view — all connected natively to Accounting, Inventory, and Email Marketing.
ExploreManufacturing Management ERP
Run lean, traceable production with Odoo Manufacturing — work orders, Bills of Materials, quality control, and real-time OEE dashboards built for KSA factory floors.
ExploreSupply Chain Management
From purchase order to final delivery — Odoo Supply Chain connects procurement, multi-warehouse inventory, demand forecasting, and vendor management into one real-time platform. Purpose-configured for Saudi Arabia and the GCC by iWesabe.
Explore