Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions report_docx/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
============
DOCX reports
============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:79e0f48df24a25104ed7488dce18fa34f20814020b270bb7a7682746a4616596
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/16.0/report_docx
:alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-16-0/reporting-engine-16-0-report_docx
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows to provide docx files as report templates to generate
docx reports.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

This module was developed because for some users it is easier to use the
docx format for their templates.

As it uses a slightly different templating language, it is *not* a
drop-in replacement for report_py3o.

It also does not provide any format conversions, though it should be
pretty simple to write a glue module that converts the resulting docx
files to formats supported by report_py3o.

Installation
============

To install this module, you need to:

::

pip install docxtpl

Configuration
=============

To configure this module, you need to:

1. Go to Settings / Technical / Actions / Report
2. Create a new report with type DOCX
3. Fill in the name of a model, ie ``crm.lead``
4. Upload your DOCX file in the ``Template`` field
5. To help with crafting expressions in the template, switch to the DOCX
tab, select a record and fill in some expression. When happy with the
result, copy the code into your template document. Don't forget to
read the extensive documentation on the right hand side

Usage
=====

To use this module, you need to:

1. Print some report created according to the configuration manual

Known issues / Roadmap
======================

- support images and embedded objects
- support concatenating docx files for multiple records
- support embedding html

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_docx%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Hunki Enterprises BV

Contributors
------------

- Holger Brunn <[email protected]>
(https://hunki-enterprises.com)

Other credits
-------------

The development of this module has been financially supported by:

- The Open Source Company (https://tosc.nl)

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-hbrunn| image:: https://github.com/hbrunn.png?size=40px
:target: https://github.com/hbrunn
:alt: hbrunn

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-hbrunn|

This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/16.0/report_docx>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions report_docx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import controllers
from . import models
32 changes: 32 additions & 0 deletions report_docx/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2026 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

{
"name": "DOCX reports",
"summary": "Create report templates in DOCX and receive DOCX files",
"version": "16.0.1.0.0",
"development_status": "Alpha",
"category": "Reporting",
"website": "https://github.com/OCA/reporting-engine",
"author": "Hunki Enterprises BV, Odoo Community Association (OCA)",
"maintainers": ["hbrunn"],
"license": "AGPL-3",
"external_dependencies": {
"python": ["docxtpl"],
},
"depends": [
"mail",
],
"data": [
"views/ir_actions_report.xml",
"views/templates.xml",
],
"demo": [
"demo/ir_actions_report.xml",
],
"assets": {
"web.assets_backend": [
"/report_docx/static/src/report_docx.esm.js",
]
},
}
1 change: 1 addition & 0 deletions report_docx/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import report
72 changes: 72 additions & 0 deletions report_docx/controllers/report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2026 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

import json
import logging

from jinja2 import exceptions as jinja2_exceptions

from odoo import http, tools

from odoo.addons.web.controllers import report

_logger = logging.getLogger(__name__)


class ReportController(report.ReportController):
@http.route(["/report_docx"], type="http", auth="user")
def report_docx(self, report_name, ids=None, context=None, data=None, **kwargs):
ids = ids and json.loads(ids) or []
data = data and json.loads(data) or {}
try:
docx, ext = (
http.request.env["ir.actions.report"]
.with_context(**(context and json.loads(context) or {}))
._render_docx(report_name, ids, data=data)
)
except jinja2_exceptions.TemplateError as e:
_logger.exception("Error while generating report %s", report_name)
return http.request.make_response(
tools.html_escape(
json.dumps(
{
"code": 200,
"message": e.message,
"data": http.serialize_exception(e),
}
)
)
)
except Exception as e:
_logger.exception("Error while generating report %s", report_name)
return http.request.make_response(
tools.html_escape(
json.dumps(
{
"code": 200,
"message": "Odoo Server Error",
"data": http.serialize_exception(e),
}
)
)
)

report = http.request.env["ir.actions.report"]._get_report(report_name)
filename = report._render_docx_filename(report, ids, data, ext)

return http.request.make_response(
docx,
headers=[
(
"Content-Type",
"application/zip"
if ext == "zip"
else (
"application/vnd.openxmlformats-officedocument"
".wordprocessingml.document"
),
),
("Content-Length", len(docx)),
("Content-Disposition", http.content_disposition(filename)),
],
)
33 changes: 33 additions & 0 deletions report_docx/demo/ir_actions_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2026 Hunki Enterprises BV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0) -->
<data>
<record id="report_ir_module_multi_mode_template" model="ir.actions.report">
<field name="name">DOCX (one file)</field>
<field name="model">ir.module.module</field>
<field name="report_type">docx</field>
<field name="report_name">ir_module_multi_mode_template</field>
<field name="print_report_name">object.name</field>
<field
name="docx_template"
type="base64"
file="report_docx/static/examples/modules_multi_mode_template.docx"
/>
<field name="docx_multi_mode">template</field>
<field name="binding_model_id" ref="base.model_ir_module_module" />
</record>
<record id="report_ir_module_multi_mode_zip" model="ir.actions.report">
<field name="name">DOCX (zip if multiple)</field>
<field name="model">ir.module.module</field>
<field name="report_type">docx</field>
<field name="report_name">ir_module_multi_mode_zip</field>
<field name="print_report_name">object.name</field>
<field
name="docx_template"
type="base64"
file="report_docx/static/examples/modules_multi_mode_zip.docx"
/>
<field name="docx_multi_mode">zip</field>
<field name="binding_model_id" ref="base.model_ir_module_module" />
</record>
</data>
1 change: 1 addition & 0 deletions report_docx/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import ir_actions_report
Loading
Loading