myFAB Rapport docx
myFAB · Rapport DOCX — Référence rapide
Prérequis :
pip install docxtpl docxcompose htmldocx· LibreOffice requis pour le mode PDF
Créer un paramétrage
Technique → Rapport DOCX → Configurations → Nouveau
| Champ | Valeur attendue | Obligatoire |
|---|---|---|
| Nom du rapport | Libellé affiché dans l'interface | ✓ |
| Code rapport | Identifiant technique unique, sans espaces — ex : declaration_conformite_ce |
✓ |
| Modèle | Modèle Odoo cible (ex : sale.order, mrp.production) |
✓ |
| Champ nom fichier | Champ Char du modèle utilisé pour nommer le fichier |
✓ |
| Template DOCX | Fichier .docx avec balises Jinja2 |
✓ |
| Préfixe | Texte ajouté au début du nom de fichier généré | |
| Mode de fusion | composer (DOCX unique) · zip (un fichier/enregistrement) · pdf (via LibreOffice) |
✓ |
| Nom fichier impression | Formule Jinja — ex : {{ docs.name }} |
|
| Autoescape | Activer si le template contient <, > ou & |
Publier via le bouton Publier — tous les champs passent en lecture seule.
Pour modifier : Dépublier d'abord.
Syntaxe du template
Champs
{{docs.nom_du_champ}}
{{docs.relation_id.champ}}
Fonctions utilitaires
| Fonction | Description |
|---|---|
{{spelled_out(docs.champ)}} |
Nombre en toutes lettres |
{{formatdate(docs.champ)}} |
Date formatée (Babel, fr_FR par défaut) |
{{fdate(docs.champ, "%d/%m/%Y")}} |
Date avec format personnalisé |
{{fnum(docs.champ, " ", ",", 2)}} |
Numérique — fnum(val, sep_milliers, sep_décimal, décimales) |
{{parsehtml(docs.champ)}} |
HTML → texte brut |
{{p html2docx(docs.champ)}} |
HTML → sous-document Word |
{{convert_currency(docs.champ, docs.currency_id)}} |
Montant avec devise |
{{render_image(docs.champ, width=30, height=30)}} |
Image binaire (mm) |
{{r rich_text(docs.champ)}} |
Texte enrichi |
{{p add_subdoc(docs.champ)}} |
Sous-document DOCX binaire |
{{replace_image('nom', docs.champ)}} |
Remplacement d'image dans le template |
Langue surchargeable par fonction :
{{formatdate(docs.champ, lang='en_US')}}
Boucles dans un tableau
Chaque directive {%tr %} doit occuper une ligne entière du tableau, avec une cellule fusionnée sur toute la largeur.
{%tr for line in docs.order_line_ids %}
{{line.product_id.display_name}} | {{line.qty}} | {{line.price_unit}}
{%tr endfor %}
- Les lignes
foretendforsont supprimées du rendu final. - Les champs s'accèdent via la variable de boucle (
line).
Conditions dans un tableau
Utiliser impérativement if / else / endif — deux blocs if séparés provoquent une TemplateSyntaxError.
{%tr for line in docs.order_line_ids %}
{%tr if not line.uom_qty %}
[cellule fusionnée] {{line.product_id.display_name}} ← ligne de section
{%tr else %}
{{line.product_id.display_name}} | {{line.uom_qty}} | {{line.price_unit}}
{%tr endif %}
{%tr endfor %}
Ordre obligatoire : for → if → else → endif → endfor
Préférer
not line.champàline.champ == 0pour couvrir0,0.0,FalseetNone.
La directive
{%tr if %}et le contenu{{champ}}doivent être dans deux<w:r>séparés dans le XML Word — sinon le contenu ne s'affiche pas.
Mode PDF
Configurer le chemin LibreOffice dans Paramètres → Technique → Paramètres système :
| OS | Valeur |
|---|---|
| Linux | /usr/bin/libreoffice |
| Windows | C:\Program Files\LibreOffice\program\soffice.exe |
Clé : default_libreoffice_path
Erreurs courantes
| Erreur | Cause | Solution |
|---|---|---|
TemplateSyntaxError: unknown tag 'endif' |
Deux blocs if séparés dans un for |
Remplacer par if / else / endif |
| Ligne fusionnée vide | {%tr if %} et {{champ}} dans le même <w:r> |
Les séparer en deux runs distincts |
Condition == 0 ignorée |
Le champ est un float (0.0 != 0) |
Utiliser not line.champ |
| Erreur 500 générique | Erreur Python non affichée | journalctl -u odoo -n 100 ou tail -f /var/log/odoo/odoo.log |
| PDF non généré | LibreOffice absent ou mal configuré | Installer + configurer default_libreoffice_path |