Odoo · QWeb · Informes
Un informe PDF en Odoo es una plantilla QWeb que wkhtmltopdf convierte en papel. La mayoría de fallos no están en el código: están en el paperformat, en los márgenes o en que wkhtmltopdf no está instalado en el contenedor. Esta guía monta un informe mínimo y esquiva las trampas clásicas.
Anatomía
Las tres piezas de un informe
| Pieza | Modelo | Responsabilidad |
|---|---|---|
| Acción de informe | ir.actions.report | Vincula modelo, plantilla y paperformat |
| Plantilla QWeb | ir.ui.view | El HTML con t-foreach, t-out, t-field |
| Paperformat | report.paperformat | Tamaño, márgenes, cabecera/pie |
Acción
Declarar el informe
<record id="action_report_diagnostic" model="ir.actions.report">
<field name="name">Informe de diagnóstico</field>
<field name="model">diagnostic.test</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">mi_modulo.report_diagnostic</field>
<field name="paperformat_id" ref="mi_modulo.paperformat_diagnostic"/>
<field name="binding_model_id" ref="model_diagnostic_test"/>
</record>
binding_model_id añade el informe al menú «Imprimir» de la vista. Sin él, la acción existe pero no aparece en la UI.
Plantilla
QWeb mínimo con t-out y t-foreach
<template id="report_diagnostic">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="web.external_layout">
<div class="page">
<h2>Diagnóstico <span t-field="doc.name"/></h2>
<p>Paciente: <span t-field="doc.partner_id"/></p>
<table class="table">
<thead>
<tr><th>Prueba</th><th>Resultado</th></tr>
</thead>
<tbody>
<tr t-foreach="doc.line_ids" t-as="line">
<td><t t-out="line.name"/></td>
<td><t t-out="line.value"/></td>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</t>
</template>
t-field="doc.amount" cuando quieras el formato del campo (moneda, fecha localizada). Usa t-out="expresión" para valores calculados o texto plano. t-esc está deprecado desde Odoo 17.
Paperformat
Tamaño, márgenes y cabecera
<record id="paperformat_diagnostic" model="report.paperformat">
<field name="name">Diagnóstico A4</field>
<field name="format">A4</field>
<field name="orientation">Portrait</field>
<field name="margin_top">25</field>
<field name="margin_bottom">20</field>
<field name="header_spacing">15</field>
<field name="dpi">90</field>
</record>
El margin_top debe dejar sitio a la cabecera de web.external_layout. Si el contenido pisa el logo de la empresa, sube margin_top y header_spacing.
Docker
wkhtmltopdf en el contenedor
La imagen oficial de Odoo ya incluye wkhtmltopdf con el patch de Qt. Si construyes una imagen propia, instala la versión parcheada (la de los repos de Debian/Ubuntu no sirve para cabeceras y pies).
wkhtmltopdf --version: debe decir «with patched qt».
Depuración
Errores frecuentes
| Síntoma | Causa | Solución |
|---|---|---|
| PDF en blanco | wkhtmltopdf sin patch Qt | Instalar versión parcheada |
| Estilos no aplican | CSS fuera del bundle de informes | Usar web.report_assets_common |
| Contenido pisa cabecera | margin_top insuficiente | Subir margen y header_spacing |
docs vacío en plantilla | report_name mal escrito | Debe ser modulo.template_id |
Para depurar el HTML antes del PDF, cambia report_type a qweb-html temporalmente y abre el informe en el navegador: ves el render exacto sin la capa de wkhtmltopdf.
Resumen
Un informe = acción + plantilla QWeb + paperformat. Usa web.external_layout para cabecera/pie corporativos, t-field para formato y t-out para texto plano. El 80% de los problemas de PDF en producción son wkhtmltopdf sin patch Qt: verifícalo en el contenedor antes de tocar la plantilla.