diff options
| author | Lucas Lefèvre <lul@odoo.com> | 2019-09-12 13:16:10 +0000 |
|---|---|---|
| committer | Yannick Tivisse <yti@odoo.com> | 2019-09-16 13:57:40 +0000 |
| commit | ac00548b28c0c384b5b1423f65405e4918101872 (patch) | |
| tree | 37d3d94cc8dd82e0ff295f893f797541fd138a74 /addons/web/controllers | |
| parent | 35cbb430ce79ce26d8cd1b7c2f9f112b35d1e6a1 (diff) | |
[IMP] web: Export list view as XLS file
Purpose
=======
Have a quick export feature.
The current export wizard is quite complex.
We want to be able to quickly export a tree view,
with the group by correctly represented, depending on the fields
visible in the list view.
Specification
=============
Add an "EXPORT (XLS)" button in the list view (a little download icon)
- export only columns visible in list view
- export all the records
- while respecting the group by
This should be a generic feature but should be applied to all
the account.move.lines list views.
account.view_move_line_tree_grouped_sales_purchases
account.view_move_line_tree_grouped_bank_cash
account.view_move_line_tree_grouped_misc
Task 2031835
closes odoo/odoo#36943
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Diffstat (limited to 'addons/web/controllers')
| -rw-r--r-- | addons/web/controllers/__init__.py | 2 | ||||
| -rw-r--r-- | addons/web/controllers/list_controller.py | 98 |
2 files changed, 99 insertions, 1 deletions
diff --git a/addons/web/controllers/__init__.py b/addons/web/controllers/__init__.py index 48cc37266c6..2113dfa39c9 100644 --- a/addons/web/controllers/__init__.py +++ b/addons/web/controllers/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import main, pivot +from . import main, pivot, list_controller diff --git a/addons/web/controllers/list_controller.py b/addons/web/controllers/list_controller.py new file mode 100644 index 00000000000..7ac98b79220 --- /dev/null +++ b/addons/web/controllers/list_controller.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import json +from datetime import datetime + +from odoo import http +from odoo.http import request +from odoo.tools.misc import xlwt + + +HEADER_BOLD = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;") + +class TableListExporter(http.Controller): + + def _write_group_header(self, worksheet, x, y, group, columns, group_depth=0): + aggregates = group.get('aggregateValues', {}) + title = group.get('value') + + if group.get('hideHeader'): + return x, y + + title = '%s%s (%s)' % ('>' * group_depth, title, group.get('count', 0)) + worksheet.write(x, y, title, HEADER_BOLD) + for column in columns[1:]: # No aggregates allowed in the first column + y += 1 + worksheet.write(x, y, aggregates.get(column['field'], ''), HEADER_BOLD) + return x + 1, 0 + + def _write_record(self, worksheet, x, y, record, columns): + for column in columns: + worksheet.write(x, y, record[column['field']]) + y += 1 + return x + 1, 0 + + def _write_groups(self, worksheet, x, y, groups, columns, group_depth=0): + """ + Write groups to the xls worksheet. Recursive if groups are nested (chained groupby) + :param worksheet: + :param x: start position where to write the group (vertical axis, pointing downward) + :param y: start position where to write the group (horizontal axis, pointing to the right) + :param groups: list of groups. Each group is a dict containing either records' data + or sub-groups. A group has the following structure: + 'data': list of records or list of sub-groups + 'isGrouped': True if data contains sub-groups + 'value': title of the group + 'count': number of records in the group + 'aggregateValues': dict container aggregated values of fields {field: aggregatedValue, ...} + 'hideHeader': self explanatory, used when the records are not grouped at all. + :param columns: list of displayed columns. Each column is a dict with the following keys: + 'field': field name + 'aggregateValue': aggregate for all records + 'string': + """ + for group in groups: + x, y = self._write_group_header(worksheet, x, y, group, columns, group_depth) + if group['isGrouped']: + # Recursively write sub-groups + x, y = self._write_groups(worksheet, x, y, group['data'], columns, group_depth + 1) + else: + for record in group['data']: + x, y = self._write_record(worksheet, x, y, record, columns) + return x, y + + def _write_worksheet(self, worksheet, data): + bold = xlwt.easyxf("font: bold on;") + + columns = data['columns'] + groups = data['groups'] + + # Write main header + for y, field in enumerate(columns): + worksheet.write(0, y, field['string'], bold) + + # Write data + x, y = 1, 0 + x, y = self._write_groups(worksheet, x, y, groups, columns) + + # Write column aggregates + for y, field in enumerate(columns): + worksheet.write(x, y, field.get('aggregateValue', ''), bold) + + @http.route('/web/list/export_xls', type='http', auth="user") + def export_xls(self, data, token): + data = json.loads(data) + title = data.get('title', 'export') + workbook = xlwt.Workbook() + worksheet = workbook.add_sheet(title) + + self._write_worksheet(worksheet, data) + + response = request.make_response(None, + headers=[('Content-Type', 'application/vnd.ms-excel'), + ('Content-Disposition', 'attachment; filename="%s - %s.xls"' % (title, datetime.now()))], + cookies={'fileToken': token}) + workbook.save(response.stream) + + return response |
