跳至内容
菜单
此问题已终结

Hello,

I am building a custom PDF report in Odoo (v18) using QWeb.

  • I defined a custom report.paperformat (A4, portrait) with correct margins, so my header is aligned properly.
  • The problem:
    • I want the invoice lines table to stretch and fill the available vertical space until the bottom of the page.
    • I also need to position a declaration/div block always at the bottom of the last page, just above the footer.
  • When I tried using Bootstrap flex / CSS positioning, it didn’t apply in the PDF output (because Odoo uses wkhtmltopdf with limited CSS support).

<div class="page">
   <!-- Header (works fine) -->

   <table class="inv-tbl">
      <!-- invoice lines -->
   </table>

   <!-- I want this block always pushed to bottom -->
   <div class="declaration">
      Company Declaration and Bank Details
   </div>
</div>


What I tried:

  • Flexbox and min-height:100% → not applied.
  • Absolute positioning with bottom:0 → overlaps table content.
  • Adjusting paperformat margins → helps only for header, not for body stretching.


So,

What is the recommended approach in Odoo QWeb reports to:

  1. Stretch a table so it occupies remaining height,
  2. Always push a block (div) to the bottom of the last page (above footer)?

Any examples or best practices would be appreciated.

形象
丢弃
最佳答案

Hi,



For the table (invoice lines) to stretch and fill remaining vertical space in Odoo PDF reports:


Wrap the whole page in a container with display: table; height: 100%, then put the invoice lines inside a display: table-row; height: 100%.


Example:


<div style="display: table; width: 100%; height: 100%;">

    <div style="display: table-row; height: 100%;">

        <table class="inv-tbl" style="width:100%;">

            <!-- invoice lines -->

        </table>

    </div>

</div>



This makes the invoice lines table expand automatically to use the available vertical space between header and footer.



To print the header/footer only on the first/last page, you can use the OCA module.


* https://odoo-community.org/shop/report-qweb-element-page-visibility-2192


After installing the module, use the first-page or last-page class.


Header


<div class="header">

    <div class="first-page">

        <div class="row">

            <img t-if="company.custom_report_header"

                 t-att-src="image_data_uri(company.custom_report_header)"

                 alt="Logo" width="100%"/>

        </div>

    </div>

</div>



Footer.


<div class="footer o_standard_footer">

    <div class="last-page">

        <div style="width: 100%;">

             <img t-if="company.custom_report_footer"

             t-att-src="image_data_uri(company.custom_report_footer)"

             alt="Logo" width="100%"/>

          </div>


      </div

</div>



Hope it helps



形象
丢弃
编写者 最佳答案

Hi, thanks for the suggestion!

I tried wrapping my report in display: table; height: 100% with the invoice lines inside a table-row as you mentioned.

It works fine when the content fits in a single page — the table expands to the bottom and the footer stays fixed at the bottom.

But when I add more rows (e.g., range(35)), the table correctly flows to the next page, but on the last page the table doesn’t stretch down to fill the available vertical space above the footer.

Is there a way to make the last page’s body area also expand until the footer, even if the table breaks across multiple pages?

Thanks again for your help!



I'm attaching sample code and outputs below 👇



<?xml version="1.0" encoding="utf-8"?>

<odoo>

<!-- Report Action -->

<record id="action_report_stretch_test" model="ir.actions.report">

<field name="name">Stretch Test Report</field>

<field name="model">sale.order</field>

<field name="report_type">qweb-pdf</field>

<field name="report_name">custom_sale.custom_sale_tax_report_test</field>

<field name="report_file">custom_sale.custom_sale_tax_report_test</field>

<field name="binding_model_id" ref="sale.model_sale_order" />

<field name="binding_type">report</field>

</record>


<!-- Report Template -->

<template id="custom_sale_tax_report_test">

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

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


<!-- Header (first page only) -->

<div class="header">

<div class="">

<div class="h2 text-center">

Header

</div>

</div>

</div>


<!-- Page container: behave like a table -->

<div style="display: table; width: 100%; height: 100%;">


<!-- Stretchy middle row -->

<div style="display: table-row; height: 100%;">

<div style="padding: 10px;">


<h3 style="margin-bottom: 10px;">Body Part </h3>


<table class="inv-tbl"

style="width:100%; border:1px solid #000; border-collapse: collapse;">

<thead>

<tr>

<th style="border:1px solid #000; padding:4px;">Sl No</th>

<th style="border:1px solid #000; padding:4px;">Description</th>

<th style="border:1px solid #000; padding:4px;">Value</th>

</tr>

</thead>

<tbody>

<t t-set="count" t-value="1" />

<t t-foreach="range(15)" t-as="i">

<tr>

<td style="border:1px solid #000; padding:4px;">

<t t-esc="i" />

</td>

<td style="border:1px solid #000; padding:4px;">Sample</td>

<td style="border:1px solid #000; padding:4px;">Value</td>

</tr>

</t>

</tbody>

</table>


</div>

</div>


<div class="bottom-box last-page" style="">

<table class="table table-striped inv-tbl"

style="width:100%; border:1px solid #000; border-collapse: collapse;">

<thead>

<tr>

<th colspan="2">Bank Details</th>

</tr>

</thead>

<tbody>

<tr>

<td>Name</td>

<td>HDFC</td>

</tr>

<tr>

<td>ACC No.</td>

<td>--------</td>

</tr>

<tr>

<td>Branch</td>

<td>Kozhikode</td>

</tr>

</tbody>

</table>

</div>


</div>


<div class="footer o_standard_footer">

<div class="">

<div style="width: 100%; text-align:center; padding:10px; background:#eee;">

<span>Footer Part</span>

</div>

</div>

</div>


</t>

</t>

</template>

</odoo>

output


When the range is set to 35 : to observe the overflow output was like



形象
丢弃
相关帖文 回复 查看 活动
0
5月 24
1894
2
5月 24
3693
3
2月 24
3175
2
11月 22
6011
0
6月 20
2652