Luc De Meyer
6 years ago
25 changed files with 363 additions and 47 deletions
-
11report_xlsx_helper/README.rst
-
3report_xlsx_helper/__init__.py
-
4report_xlsx_helper/__manifest__.py
-
1report_xlsx_helper/controllers/__init__.py
-
54report_xlsx_helper/controllers/main.py
-
1report_xlsx_helper/models/__init__.py
-
21report_xlsx_helper/models/ir_actions_report.py
-
1report_xlsx_helper/readme/CONTRIBUTORS.rst
-
1report_xlsx_helper/readme/DESCRIPTION.rst
-
1report_xlsx_helper/readme/INSTALL.rst
-
32report_xlsx_helper/readme/USAGE.rst
-
4report_xlsx_helper/report/__init__.py
-
20report_xlsx_helper/report/report_xlsx_abstract.py
-
18report_xlsx_helper/report/test_partner_report_xlsx.py
-
2report_xlsx_helper/tests/__init__.py
-
13report_xlsx_helper/tests/test_report_xlsx_helper.py
-
58report_xlsx_helper_demo/README.rst
-
2report_xlsx_helper_demo/__init__.py
-
18report_xlsx_helper_demo/__manifest__.py
-
1report_xlsx_helper_demo/models/__init__.py
-
25report_xlsx_helper_demo/models/res_partner.py
-
1report_xlsx_helper_demo/report/__init__.py
-
99report_xlsx_helper_demo/report/partner_export_xlsx.py
-
BINreport_xlsx_helper_demo/static/description/icon.png
-
19report_xlsx_helper_demo/views/res_partner.xml
@ -1,2 +1,3 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
from . import controllers |
||||
|
from . import models |
||||
from . import report |
from . import report |
@ -0,0 +1 @@ |
|||||
|
from . import main |
@ -0,0 +1,54 @@ |
|||||
|
# Copyright 2009-2018 Noviat. |
||||
|
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). |
||||
|
|
||||
|
import json |
||||
|
|
||||
|
from odoo.addons.report_xlsx.controllers.main import ReportController |
||||
|
from odoo.http import content_disposition, route, request |
||||
|
|
||||
|
|
||||
|
class ReportController(ReportController): |
||||
|
|
||||
|
@route([ |
||||
|
'/report/<converter>/<reportname>', |
||||
|
'/report/<converter>/<reportname>/<docids>', |
||||
|
], type='http', auth='user', website=True) |
||||
|
def report_routes(self, reportname, docids=None, converter=None, **data): |
||||
|
report = request.env['ir.actions.report']._get_report_from_name( |
||||
|
reportname) |
||||
|
if converter == 'xlsx' and not report: |
||||
|
|
||||
|
context = dict(request.env.context) |
||||
|
if docids: |
||||
|
docids = [int(i) for i in docids.split(',')] |
||||
|
if data.get('options'): |
||||
|
data.update(json.loads(data.pop('options'))) |
||||
|
if data.get('context'): |
||||
|
# Ignore 'lang' here, because the context in data is the one |
||||
|
# from the webclient *but* if the user explicitely wants to |
||||
|
# change the lang, this mechanism overwrites it. |
||||
|
data['context'] = json.loads(data['context']) |
||||
|
if data['context'].get('lang'): |
||||
|
del data['context']['lang'] |
||||
|
context.update(data['context']) |
||||
|
context['report_name'] = reportname |
||||
|
|
||||
|
xlsx = report.with_context(context).render_xlsx( |
||||
|
docids, data=data |
||||
|
)[0] |
||||
|
report_file = context.get('report_file') |
||||
|
if not report_file: |
||||
|
active_model = context.get('active_model', 'export') |
||||
|
report_file = active_model.replace('.', '_') |
||||
|
xlsxhttpheaders = [ |
||||
|
('Content-Type', 'application/vnd.openxmlformats-' |
||||
|
'officedocument.spreadsheetml.sheet'), |
||||
|
('Content-Length', len(xlsx)), |
||||
|
( |
||||
|
'Content-Disposition', |
||||
|
content_disposition(report_file + '.xlsx') |
||||
|
) |
||||
|
] |
||||
|
return request.make_response(xlsx, headers=xlsxhttpheaders) |
||||
|
return super(ReportController, self).report_routes( |
||||
|
reportname, docids, converter, **data) |
@ -0,0 +1 @@ |
|||||
|
from . import ir_actions_report |
@ -0,0 +1,21 @@ |
|||||
|
# Copyright 2009-2018 Noviat. |
||||
|
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import api, models, _ |
||||
|
from odoo.exceptions import UserError |
||||
|
|
||||
|
|
||||
|
class IrActionsReport(models.Model): |
||||
|
_inherit = 'ir.actions.report' |
||||
|
|
||||
|
@api.model |
||||
|
def render_xlsx(self, docids, data): |
||||
|
if not self and self.env.context.get('report_name'): |
||||
|
report_model_name = 'report.{}'.format( |
||||
|
self.env.context['report_name']) |
||||
|
report_model = self.env.get(report_model_name) |
||||
|
if report_model is None: |
||||
|
raise UserError( |
||||
|
_('%s model was not found' % report_model_name)) |
||||
|
return report_model.create_xlsx_report(docids, data) |
||||
|
return super(IrActionsReport, self).render_xlsx(docids, data) |
@ -0,0 +1 @@ |
|||||
|
* Luc De Meyer <luc.demeyer@noviat.com> |
@ -0,0 +1 @@ |
|||||
|
This module provides a set of tools to facilitate the creation of excel reports with format xlsx. |
@ -0,0 +1 @@ |
|||||
|
This module requires report_xlsx version 11.0.1.0.3 or higher. |
@ -0,0 +1,32 @@ |
|||||
|
In order to create an Excel report you can define a report of type 'xlsx' in a static or dynamic way: |
||||
|
|
||||
|
* Static syntax: cf. ``account_move_line_report_xls`` for an example. |
||||
|
* Dynamic syntax: cf. ``report_xlsx_helper_demo`` for an example |
||||
|
|
||||
|
The ``AbstractReportXlsx`` class contains a number of attributes and methods to |
||||
|
facilitate the creation excel reports in Odoo. |
||||
|
|
||||
|
* Cell types |
||||
|
|
||||
|
string, number, boolean, datetime. |
||||
|
|
||||
|
* Cell formats |
||||
|
|
||||
|
The predefined cell formats result in a consistent |
||||
|
look and feel of the Odoo Excel reports. |
||||
|
|
||||
|
* Cell formulas |
||||
|
|
||||
|
Cell formulas can be easily added with the help of the ``_rowcol_to_cell()`` method. |
||||
|
|
||||
|
* Excel templates |
||||
|
|
||||
|
It is possible to define Excel templates which can be adapted |
||||
|
by 'inherited' modules. |
||||
|
Download the ``account_move_line_report_xls`` module |
||||
|
from http://apps.odoo.com as example. |
||||
|
|
||||
|
* Excel with multiple sheets |
||||
|
|
||||
|
Download the ``account_asset_management_xls`` module |
||||
|
from http://apps.odoo.com as example. |
@ -1,2 +1,2 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
from . import abstract_report_xlsx |
|
||||
|
from . import report_xlsx_abstract |
||||
|
from . import test_partner_report_xlsx |
@ -1,3 +1 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
from . import test_partner_report_xlsx |
|
||||
from . import test_report_xlsx_helper |
from . import test_report_xlsx_helper |
@ -0,0 +1,58 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png |
||||
|
:target: https://www.gnu.org/licenses/agpl |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
================================== |
||||
|
Excel report engine helpers - demo |
||||
|
================================== |
||||
|
|
||||
|
This module demonstrates the capabilities or the report_xlsx_helper module via |
||||
|
a basic example. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
Open a partner record and click on the 'Export XLS' button. |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
There is no specific installation procedure for this module. |
||||
|
|
||||
|
Configuration and Usage |
||||
|
======================= |
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/143/11.0 |
||||
|
|
||||
|
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 smashing it by providing a detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Luc De Meyer <luc.demeyer@noviat.com> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
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. |
||||
|
|
||||
|
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||||
|
from . import models |
||||
|
from . import report |
@ -0,0 +1,18 @@ |
|||||
|
# Copyright 2009-2018 Noviat. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
{ |
||||
|
'name': 'Report xlsx helpers - demo', |
||||
|
'author': 'Noviat,' |
||||
|
'Odoo Community Association (OCA)', |
||||
|
'category': 'Reporting', |
||||
|
'version': '11.0.1.0.0', |
||||
|
'license': 'AGPL-3', |
||||
|
'depends': [ |
||||
|
'report_xlsx_helper', |
||||
|
], |
||||
|
'data': [ |
||||
|
'views/res_partner.xml', |
||||
|
], |
||||
|
'installable': True, |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
from . import res_partner |
@ -0,0 +1,25 @@ |
|||||
|
# Copyright 2009-2018 Noviat |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import api, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
@api.multi |
||||
|
def export_xls(self): |
||||
|
module = __name__.split('addons.')[1].split('.')[0] |
||||
|
report_name = '{}.partner_export_xlsx'.format(module) |
||||
|
report = { |
||||
|
'type': 'ir.actions.report', |
||||
|
'report_type': 'xlsx', |
||||
|
'report_name': report_name, |
||||
|
# model name will be used if no report_file passed via context |
||||
|
'context': dict(self.env.context, report_file='partner'), |
||||
|
# report_xlsx doesn't pass the context if the data dict is empty |
||||
|
# cf. report_xlsx\static\src\js\report\qwebactionmanager.js |
||||
|
# TODO: create PR on report_xlsx to fix this |
||||
|
'data': {'dynamic_report': True}, |
||||
|
} |
||||
|
return report |
@ -0,0 +1 @@ |
|||||
|
from . import partner_export_xlsx |
@ -0,0 +1,99 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2009-2018 Noviat. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import models |
||||
|
|
||||
|
|
||||
|
class PartnerExportXlsx(models.AbstractModel): |
||||
|
_name = 'report.report_xlsx_helper_demo.partner_export_xlsx' |
||||
|
_inherit = 'report.report_xlsx.abstract' |
||||
|
|
||||
|
def _get_ws_params(self, wb, data, partners): |
||||
|
|
||||
|
partner_template = { |
||||
|
'name': { |
||||
|
'header': { |
||||
|
'value': 'Name', |
||||
|
}, |
||||
|
'data': { |
||||
|
'value': self._render("partner.name"), |
||||
|
}, |
||||
|
'width': 20, |
||||
|
}, |
||||
|
'number_of_contacts': { |
||||
|
'header': { |
||||
|
'value': '# Contacts', |
||||
|
}, |
||||
|
'data': { |
||||
|
'value': self._render("len(partner.child_ids)"), |
||||
|
}, |
||||
|
'width': 10, |
||||
|
}, |
||||
|
'is_customer': { |
||||
|
'header': { |
||||
|
'value': 'Customer', |
||||
|
}, |
||||
|
'data': { |
||||
|
'value': self._render("partner.customer"), |
||||
|
}, |
||||
|
'width': 10, |
||||
|
}, |
||||
|
'is_customer_formula': { |
||||
|
'header': { |
||||
|
'value': 'Customer Y/N ?', |
||||
|
}, |
||||
|
'data': { |
||||
|
'type': 'formula', |
||||
|
'value': self._render("customer_formula"), |
||||
|
}, |
||||
|
'width': 14, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
wanted_list = [ |
||||
|
'name', 'number_of_contacts', 'is_customer', |
||||
|
'is_customer_formula'] |
||||
|
ws_params = { |
||||
|
'ws_name': 'Partners', |
||||
|
'generate_ws_method': '_partner_report', |
||||
|
'title': 'Partners', |
||||
|
'wanted_list': wanted_list, |
||||
|
'col_specs': partner_template, |
||||
|
} |
||||
|
|
||||
|
return [ws_params] |
||||
|
|
||||
|
def _partner_report(self, workbook, ws, ws_params, data, partners): |
||||
|
|
||||
|
ws.set_portrait() |
||||
|
ws.fit_to_pages(1, 0) |
||||
|
ws.set_header(self.xls_headers['standard']) |
||||
|
ws.set_footer(self.xls_footers['standard']) |
||||
|
|
||||
|
self._set_column_width(ws, ws_params) |
||||
|
|
||||
|
row_pos = 0 |
||||
|
if len(partners) == 1: |
||||
|
ws_params['title'] = partners.name |
||||
|
row_pos = self._write_ws_title(ws, row_pos, ws_params) |
||||
|
row_pos = self._write_line( |
||||
|
ws, row_pos, ws_params, col_specs_section='header', |
||||
|
default_format=self.format_theader_yellow_left) |
||||
|
ws.freeze_panes(row_pos, 0) |
||||
|
|
||||
|
wl = ws_params['wanted_list'] |
||||
|
|
||||
|
for partner in partners: |
||||
|
is_customer_pos = 'is_customer' in wl and \ |
||||
|
wl.index('is_customer') |
||||
|
is_customer_cell = self._rowcol_to_cell( |
||||
|
row_pos, is_customer_pos) |
||||
|
customer_formula = 'IF({},"Y", "N")'.format(is_customer_cell) |
||||
|
row_pos = self._write_line( |
||||
|
ws, row_pos, ws_params, col_specs_section='data', |
||||
|
render_space={ |
||||
|
'partner': partner, |
||||
|
'customer_formula': customer_formula, |
||||
|
}, |
||||
|
default_format=self.format_tcell_left) |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_partner_form" model="ir.ui.view"> |
||||
|
<field name="name">res.partner.test_xlsx</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<div name="button_box" position="inside"> |
||||
|
<button type="object" class="oe_stat_button" icon="fa-file-excel-o" name="export_xls"> |
||||
|
<div class="o_form_field o_stat_info"> |
||||
|
<span class="o_stat_text">Export XLS</span> |
||||
|
</div> |
||||
|
</button> |
||||
|
</div> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue