Customize the Dolibarr invoice PDF
Logo, legal mentions, VAT exemption note, late payment terms, IBAN, watermark, ODT template and PDF conversion, PHP template in custom: every step tested on Dolibarr 24.0.1, with the traps.
There are three ways to change how a Dolibarr invoice looks, from the simplest to the most flexible:
- settings, without a line of code: logo, legal mentions, bank details, footer texts, margins;
- an ODT template, a LibreOffice document with tags that Dolibarr fills in;
- a custom PHP template, stored apart so it does not vanish at the next upgrade.
Everything below was tested on 13 October 2026 on Dolibarr 24.0.1 and checked on the resulting PDF.
The starting template: sponge
In 24, the Invoices module setup offers a single PDF template: sponge. The crabe template, still quoted in many tutorials, was removed in 24.0; the upgrade script to 24 switches invoices and the default setting from crabe to sponge. The third template in the code, octopus, is for progress (situation) invoices and stays hidden until those are enabled.
Each invoice remembers the template it was last generated with. Changing the default template therefore does not change invoices already issued: they have to be generated again.
1. Without code
The logo
Setup › Company/Organization, Logo field, then Save. The logo replaces the company name at the top left of the invoice; Dolibarr creates the thumbnails itself. Its height is set in Setup › PDF, “Height for logo on PDF”.
Legal mentions
The identifiers entered on the same page (registration numbers, VAT number, capital…) are printed in the footer. Setup › PDF has an option to add the company address or the names of the managers to the footer.
The VAT exemption note
Choose “Sales tax is not used” in the Sales Tax Management section of Setup › Company/Organization if you are not registered for VAT. Dolibarr then prints a VAT exemption note under the invoice lines, but only for a company located in France, and the wording is French law:
- on an English PDF:
* Non applicable VAT art-293B of CGI; - on a French PDF:
* TVA non applicable, art. L. 223-3 du CIBS, a reference that is not in force before 1 January 2027 (reported to Dolibarr in issue #41540).
In another country, no note is printed automatically: put the wording your law requires in the “Free text on invoices” field (next section).
To change the French note, override the translation:
- Setup › Translation, Overwrite a translation string tab;
- turn on Allow customization of translations;
- language
fr_FR(oren_USfor English PDFs), keyVATIsNotUsedForInvoice, value* TVA non applicable, art. 293 B du CGI, then Add.
Generate the invoice again: the new note is printed instead of the old one.
The EU VAT Mentions module makes this replacement with a checkbox, “Correct the exemption statement Dolibarr prints (France)”, in French, English and German. It also prints the required notes for small businesses, intra-EU supplies, reverse charge and exports, for companies in France, Germany, Austria, Belgium and Luxembourg.
Late payment terms and other mentions
In the Invoices module setup, the Free text on invoices field is printed at the bottom of every invoice. This is the place for mandatory business-to-business mentions, such as late payment penalties.
Bank details
Still in the Invoices module setup, Suggest payment by withdrawal on account (the label means bank transfer): choose your bank account. The invoice then shows a bank transfer block with the bank, the account holder, the IBAN and the BIC, as entered on the account record (Banks & Cash module). The setting next to it, “Suggest payment by check to”, is for cheques.
Draft watermark
Watermark on draft invoices: the text entered (for example DRAFT) is printed large and slanted
across invoices not yet validated. It disappears on validation.
The Setup › PDF page
It gathers the settings shared by all documents: paper size and margins, borders of the address boxes, swapping the addresses, address position for French window envelopes, hiding product references or descriptions, labels in two languages.
2. An ODT template
An ODT template is a document made with LibreOffice, in which tags between curly braces are replaced with the invoice data.
Enable. In the Invoices module setup, on the ODT/ODS templates line, enable the template.
Files are read from DOL_DATA_ROOT/doctemplates/invoices, the doctemplates/invoices subfolder of
your documents. The upload button on the same page puts a template there from your computer.
Start from the bundled template, don’t keep it as is. template_invoice.odt is a demonstration
page: it shows the syntax, but it is not a presentable invoice. Open it in LibreOffice to see how it
is built, then make your own document.
The tags. A few of the 93 in the bundled template:
| Tag | Content |
|---|---|
{object_ref}, {object_date}, {object_date_limit} |
Reference, date, due date |
{mycompany_name}, {mycompany_address}, {mycompany_vatnumber}, {mycompany_logo} |
Your company |
{company_name}, {company_address}, {company_zip}, {company_town} |
The customer |
{object_total_ht}, {object_total_vat}, {object_total_ttc}, {object_remain_to_pay} |
Totals |
{object_payment_mode}, {object_payment_term}, {free_text} |
Payment, free text |
The invoice lines go in one table row framed by two markers, which Dolibarr repeats for each line:
[!-- BEGIN row.lines --]
{line_fulldesc} {line_qty} {line_up} {line_vatrate} {line_price_ht}
[!-- END row.lines --]
To show a passage depending on a value: [!-- IF {tag} --] … [!-- ELSE {tag} --] …
[!-- ENDIF {tag} --].
Generate. On the invoice record, pick the template in the list next to Generate: Dolibarr
produces an .odt file.
Getting a PDF from the ODT
You need LibreOffice on the server, and the constant MAIN_ODT_AS_PDF set to libreoffice
(Setup › Other Setup). Dolibarr then runs soffice and puts the PDF next to the ODT.
Without LibreOffice, generation shows:
ODT to PDF convert fail (option MAIN_ODT_AS_PDF is libreoffice, command was soffice --headless … , retval=127)
retval=127 means the soffice command cannot be found. That is the case with the official
Docker image, which does not include LibreOffice. This Dockerfile adds a reduced version
(tested; on our machine the image grows from 1.38 to 1.81 GB):
FROM dolibarr/dolibarr:24.0.1
RUN apt-get update \
&& apt-get install -y --no-install-recommends libreoffice-writer-nogui \
&& rm -rf /var/lib/apt/lists/*
Build it with docker build -t dolibarr-libreoffice:24.0.1 . and replace the web service image with
dolibarr-libreoffice:24.0.1 in your docker-compose.yml.
Beware if you ever go back to an image without LibreOffice: an invoice whose last template was an
ODT can no longer be regenerated as PDF while MAIN_ODT_AS_PDF stays set.
3. A custom PHP template that survives upgrades
To go beyond the settings, you edit a PHP template. Never touch the files in
htdocs/core/modules/facture/doc/: they are replaced at every upgrade, and moving to 24 removed
crabe. Put your template in a small module in the custom folder, which is never overwritten.
Rather than copying sponge in full (nearly 2,900 lines that would never get another fix), extend it and replace only what changes. Two files are enough.
custom/mypdftemplate/core/modules/modMyPdfTemplate.class.php declares the module:
<?php
include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
class modMyPdfTemplate extends DolibarrModules
{
public function __construct($db)
{
$this->db = $db;
$this->numero = 500100;
$this->rights_class = 'mypdftemplate';
$this->family = 'other';
$this->name = preg_replace('/^mod/i', '', get_class($this));
$this->description = 'My company invoice PDF template';
$this->version = '1.0';
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
$this->picto = 'generic';
$this->module_parts = array('models' => 1);
$this->depends = array('modFacture');
}
}
'models' => 1 tells Dolibarr to look for document templates in this module. Numbers above 500000
are free for a module you do not distribute.
custom/mypdftemplate/core/modules/facture/doc/pdf_mytemplate.modules.php holds the template. This
one keeps all of sponge and adds a contact line under the logo:
<?php
require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/doc/pdf_sponge.modules.php';
class pdf_mytemplate extends pdf_sponge
{
public function __construct($db)
{
parent::__construct($db);
$this->name = 'mytemplate';
$this->description = 'Sponge, with a contact line in the header';
}
protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
{
$result = parent::_pagehead($pdf, $object, $showaddress, $outputlangs, $outputlangsbis);
$pdf->SetFont('', 'I', 8);
$pdf->SetTextColor(80, 80, 80);
$pdf->SetXY($this->marge_gauche, $this->marge_haute + 20);
$pdf->MultiCell(90, 4, 'A question about this invoice? accounts@my-company.com', 0, 'L');
return $result;
}
}
The class name must be pdf_ followed by the file name, and $this->name that same name. Then:
- Setup › Modules/Applications: enable the MyPdfTemplate module;
- in the Invoices module setup, enable mytemplate and set it as default;
- generate an invoice again.
The methods you can replace the same way include _pagehead (header), _pagefoot (footer),
_tableau (lines frame), drawInfoTable (payment, mentions) and drawTotalTable (totals). After a
major Dolibarr upgrade, check that their signature has not changed in pdf_sponge.modules.php.
In Docker, custom is a volume: after the container was recreated, the template was still there and
still generated the invoice.
If you would rather have your template built for you, the Custom PDF documents package starts from your current invoice.