The main aim of the present refactoring is twofold: - simplify the code that was largely complexified at the time of the introduction of comparisons in the pivot view (Time Ranges menu), - factorize the method expandHeader and _loadData that were too much complex. Along the way, the pivot model structure has been simplified and many tests have been added. Performances in mobile mode have been improved by avoiding unecessary operations due to useless column groupbys in that mode. It should now be easier to understand and modify the pivot view in future. Co-Authored-By: Aaron Bohy <aab@odoo.com> closes odoo/odoo#33615 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
105 lines
4.2 KiB
Python
105 lines
4.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from collections import deque
|
|
import json
|
|
|
|
from odoo import http
|
|
from odoo.http import request
|
|
from odoo.tools import ustr
|
|
from odoo.tools.misc import xlwt
|
|
|
|
|
|
class TableExporter(http.Controller):
|
|
|
|
@http.route('/web/pivot/check_xlwt', type='json', auth='none')
|
|
def check_xlwt(self):
|
|
return xlwt is not None
|
|
|
|
@http.route('/web/pivot/export_xls', type='http', auth="user")
|
|
def export_xls(self, data, token):
|
|
jdata = json.loads(data)
|
|
workbook = xlwt.Workbook()
|
|
worksheet = workbook.add_sheet(jdata['title'])
|
|
header_bold = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;")
|
|
header_plain = xlwt.easyxf("pattern: pattern solid, fore_colour gray25;")
|
|
bold = xlwt.easyxf("font: bold on;")
|
|
|
|
measure_count = jdata['measure_count']
|
|
origin_count = jdata['origin_count']
|
|
|
|
# Step 1: writing col group headers
|
|
col_group_headers = jdata['col_group_headers']
|
|
|
|
# x,y: current coordinates
|
|
# carry: queue containing cell information when a cell has a >= 2 height
|
|
# and the drawing code needs to add empty cells below
|
|
x, y, carry = 1, 0, deque()
|
|
for i, header_row in enumerate(col_group_headers):
|
|
worksheet.write(i, 0, '', header_plain)
|
|
for header in header_row:
|
|
while (carry and carry[0]['x'] == x):
|
|
cell = carry.popleft()
|
|
for j in range(measure_count * (2 * origin_count - 1)):
|
|
worksheet.write(y, x+j, '', header_plain)
|
|
if cell['height'] > 1:
|
|
carry.append({'x': x, 'height': cell['height'] - 1})
|
|
x = x + measure_count * (2 * origin_count - 1)
|
|
for j in range(header['width']):
|
|
worksheet.write(y, x + j, header['title'] if j == 0 else '', header_plain)
|
|
if header['height'] > 1:
|
|
carry.append({'x': x, 'height': header['height'] - 1})
|
|
x = x + header['width']
|
|
while (carry and carry[0]['x'] == x):
|
|
cell = carry.popleft()
|
|
for j in range(measure_count * (2 * origin_count - 1)):
|
|
worksheet.write(y, x+j, '', header_plain)
|
|
if cell['height'] > 1:
|
|
carry.append({'x': x, 'height': cell['height'] - 1})
|
|
x = x + measure_count * (2 * origin_count - 1)
|
|
x, y = 1, y + 1
|
|
|
|
# Step 2: writing measure headers
|
|
measure_headers = jdata['measure_headers']
|
|
|
|
if measure_headers:
|
|
worksheet.write(y, 0, '', header_plain)
|
|
for measure in measure_headers:
|
|
style = header_bold if measure['is_bold'] else header_plain
|
|
worksheet.write(y, x, measure['title'], style)
|
|
for i in range(1, 2 * origin_count - 1):
|
|
worksheet.write(y, x+i, '', header_plain)
|
|
x = x + (2 * origin_count - 1)
|
|
x, y = 1, y + 1
|
|
|
|
# Step 3: writing origin headers
|
|
origin_headers = jdata['origin_headers']
|
|
|
|
if origin_headers:
|
|
worksheet.write(y, 0, '', header_plain)
|
|
for origin in origin_headers:
|
|
style = header_bold if origin['is_bold'] else header_plain
|
|
worksheet.write(y, x, origin['title'], style)
|
|
x = x + 1
|
|
y = y + 1
|
|
|
|
# Step 4: writing data
|
|
x = 0
|
|
for row in jdata['rows']:
|
|
worksheet.write(y, x, row['indent'] * ' ' + ustr(row['title']), header_plain)
|
|
for cell in row['values']:
|
|
x = x + 1
|
|
if cell.get('is_bold', False):
|
|
worksheet.write(y, x, cell['value'], bold)
|
|
else:
|
|
worksheet.write(y, x, cell['value'])
|
|
x, y = 0, y + 1
|
|
|
|
response = request.make_response(None,
|
|
headers=[('Content-Type', 'application/vnd.ms-excel'),
|
|
('Content-Disposition', 'attachment; filename=table.xls')],
|
|
cookies={'fileToken': token})
|
|
workbook.save(response.stream)
|
|
|
|
return response
|