summaryrefslogtreecommitdiff
path: root/addons/web/controllers
diff options
context:
space:
mode:
authorLucas Lefèvre <lul@odoo.com>2019-09-12 13:16:10 +0000
committerYannick Tivisse <yti@odoo.com>2019-09-16 13:57:40 +0000
commitac00548b28c0c384b5b1423f65405e4918101872 (patch)
tree37d3d94cc8dd82e0ff295f893f797541fd138a74 /addons/web/controllers
parent35cbb430ce79ce26d8cd1b7c2f9f112b35d1e6a1 (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__.py2
-rw-r--r--addons/web/controllers/list_controller.py98
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