Enable Dark Mode!
By: Jumana Jabin MP

How to Customize Header/Footer for All Reports in Odoo 17 ERP

Technical Odoo 17

Reports serve as crucial documents facilitating the exchange of information and comprehensive data analysis within the business realm. Within the Odoo platform, an extensive array of report types, including purchase, sale, and invoice reports, are at the disposal of businesses. Odoo further enhances flexibility by offering predefined report layouts such as "external_layout_standard," "external_layout_striped," and "external_layout_bold," all meticulously crafted using HTML/QWeb. To tailor reports to specific needs, users can personalize the header and footer elements by either crafting a new layout or inheriting and modifying an existing one. This versatility empowers businesses to present information in a manner that aligns precisely with their unique requirements and preferences

a) Activate debug mode in Odoo.

b) Navigate to the configuration settings Document layout configuration and choose the preferred layout, such as "external_layout_standard."

c) Opt for the "Edit Layout" option to access the report template for modification.

d) Utilize the "Inherit View" option to generate a new view that inherits from the existing layout.

Customize Header and Footer:

e) Tailor the header and footer sections to your specific requirements.

Save and Apply Changes:

f) Save the modifications and apply them to the report.

By employing the inheritance of the existing layout, you can seamlessly adjust the header and footer sections of a report to align with your distinctive needs.

How to Customize Header/Footer for All Reports in Odoo 16 ERP-cybrosys

To customize the report, inherit the external_layout_standard template and define inherit_id in the template.

<template  inherit_id="module_name.layout name" id="">

After inheriting the template make the following changes.

<?xml version="1.0" encoding="UTF-8"?>
   <!--STANDARD Layout-->
   <!--Inherited the standard external layout for changing company address position-->
   <template id="custom_standard_external_layout"
       <!--report header-->
       <xpath expr="//div[1]" position="replace">
           <div t-attf-class="header o_company_#{company.id}_layout"
               <!--Company Logo-->
               <div class="row mb8">
                   <div class="col-12">
                       <div class="d-flex justify-content-end">
                           <img t-if="company.logo"
                       <div class="col-9 text-end"
                            name="moto">Company tagline
               <!--Company Address-->
               <div class="row">
                   <div class="col-12" name="company_address">
                       <div class="d-flex justify-content-end" 
                            style="text-align: right;">
                           <ul class="list-unstyled" name="company_address_list">
                               <li t-if="company.is_company_details_empty">
                                   <span t-field="company.partner_id"                          t-options='{"widget": "contact", "fields": 
["address", "name"], "no_marker": true}'>
                                   <div class="bg-light border-1 rounded h-100                       d-flex flex-column align-items-center 
justify-content-center p-4 w-100 opacity-75 
text-muted text-center">
                                          <strong>Company address block</strong>
                                       <div>Contains the company address.</div>
                               <li t-else="">
                                   <span t-field="company.company_details">
                                       <div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
                                           <strong>Company details block</strong>
                                           <div>Contains the company details.</div>
                               <li t-if="not forced_vat"/>
                               <li t-else="">
                                   <t t-esc="company.country_id.vat_label or 'Tax ID'">Tax ID</t>:
                                   <span t-esc="forced_vat">US12345671</span>
               <!--Header Border-->
               <div t-if="company.logo or company.report_header"
                    class="row zero_min_height">
                   <div class="col-12">
                       <div style="border-bottom: 1px solid black;"/>
       <!--report footer-->
       <xpath expr="//div[@t-attf-class='footer o_standard_footer         o_company_#{company.id}_layout']" position="replace">
           <div t-attf-class="footer o_standard_footer o_company_#{company.id}_layout">
               <div class="text-center" style="border-top: 1px solid black;">
                   <h5 style="color:black;">
                       <b><t t-esc="company.name"/></b>
                   <h6 style="color:black;">Your company details</h6>
                   <span class="page"/>/<span class="topage"/>

After inheriting the template, customizing the report header and footer can be achieved by creating XML code and using XPath expressions. Depending on our specific customization requirements, we have the option to use positional values ??such as "replace", "after" or "before".

For example, to replace the first <div> element that usually contains the header in 'external_layout_striped', we can use the following XPath expression:

<xpath expr="//div[1]" position="replace">
<!-- Customized header with client details -->

Similarly, to replace the footer block and add a custom footer, we can use an XPath expression:

<xpath expr="//div[@t-attf-class='footer o_standard_footer   o_company_#{company.id}_layout']" position="replace">
<!-- Customized footer content with company name and page number -->

To display page numbers in the footer, you can use <span> elements with the "page" and "topage" classes:

These range classes will provide page number information to your PDF report, and you can use them in both header and footer sections.

To access data from the corresponding model, you can use variables like 'o' or 'docs' and access other models using dotted paths like 'o.partner_id.name' to retrieve specific values. You can print these values ??using <span> elements with "t-field" or "t-esc" attributes:

<span t-esc="o"/>

To avoid duplicating the design of the same layout, you can use the "t-call" directive to include additional layouts in your inherited layout:


The standard header and footer in "external_layout_striped" often include a logo in the header and a page number in the footer. In the example shown, a purchase order is printed instead.

Note that the XML snippets provided are placeholders and you must replace them with the actual customization code.

The header and footer of the Sales order report without customization are shown below.

How to Customize Header/Footer for All Reports in Odoo 16 ERP-cybrosys

After customization, the message is shown below.

How to Customize Header/Footer for All Reports in Odoo 16 ERP-cybrosys

In the same way, we can easily adapt reports in Odoo to our requirements, if you want to read more about How to Customize Header/Footer for All Reports in Odoo, please refer to our previous blog.

If you need any assistance in odoo, we are online, please chat with us.


Leave a comment




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