From 19d6d98da83d9cb19d66741ed9377647ac34f762 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 5 Feb 2014 10:58:08 +0100 Subject: [PATCH] [IMP] completes the excel export functionality in graph view (addon web_graph) bzr revid: ged@openerp.com-20140205095808-8lzwv0yqcsjnvff9 --- addons/web_graph/controllers/main.py | 94 ++++++++++++------- .../web_graph/static/src/js/graph_widget.js | 27 +++--- 2 files changed, 78 insertions(+), 43 deletions(-) diff --git a/addons/web_graph/controllers/main.py b/addons/web_graph/controllers/main.py index 813f9426f69..589e9c6b76d 100644 --- a/addons/web_graph/controllers/main.py +++ b/addons/web_graph/controllers/main.py @@ -1,13 +1,13 @@ from openerp import http import simplejson from openerp.http import request, serialize_exception as _serialize_exception +from cStringIO import StringIO try: import xlwt except ImportError: xlwt = None - class TableExporter(http.Controller): @http.route('/web_graph/check_xlwt', type='json', auth='none') @@ -18,40 +18,70 @@ class TableExporter(http.Controller): @http.route('/web_graph/export_xls', type='http', auth="user") def export_xls(self, data, token): jdata = simplejson.loads(data) - model = jdata['headers'] - # field = jdata['field'] - # data = jdata['data'] - # id = jdata.get('id', None) - # filename_field = jdata.get('filename_field', None) - # context = jdata.get('context', {}) - filecontent='argh' - print model - print xlwt + nbr_measures = jdata['nbr_measures'] + workbook = xlwt.Workbook() + worksheet = workbook.add_sheet('Sheet 1') + bold_style = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;") + non_bold_style = xlwt.easyxf("pattern: pattern solid, fore_colour gray25;") + bold = xlwt.easyxf("font: bold on;") + + # Step 1: writing headers + headers = jdata['headers'] + x, y, L = 1, 0, [] + for i, header_row in enumerate(headers): + worksheet.write(i,0, '', non_bold_style) + for header in header_row: + while (L and L[0]['x'] == x): + cell = L.pop(0) + for i in range(nbr_measures): + worksheet.write(y,x+i, '', non_bold_style) + if cell['height'] > 1: + L.append({'x': x, 'height':cell['height'] - 1}) + x = x + nbr_measures + style = non_bold_style if 'expanded' in header else bold_style + for i in range(header['width']): + worksheet.write(y, x + i, header['title'] if i == 0 else '', style) + if header['height'] > 1: + L.append({'x': x, 'height':header['height'] - 1}) + x = x + header['width']; + while (L and L[0]['x'] == x): + cell = L.pop(0) + for i in range(nbr_measures): + worksheet.write(y,x+i, '', non_bold_style) + if cell['height'] > 1: + L.append({'x': x, 'height':cell['height'] - 1}) + x = x + nbr_measures + x, y = 1, y + 1 + + # Step 2: measure row + if nbr_measures > 1: + worksheet.write(y,0, '', non_bold_style) + for measure in jdata['measure_row']: + style = bold_style if measure['is_bold'] else non_bold_style + worksheet.write(y,x, measure['text'], style); + x = x + 1 + y = y + 1 + + # Step 3: writing data + x = 0 + for row in jdata['rows']: + worksheet.write(y, x, row['indent'] * ' ' + row['title'], non_bold_style) + for cell in row['cells']: + 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 + + fp = StringIO() + workbook.save(fp) + fp.seek(0) + filecontent = fp.read() + fp.close() return request.make_response(filecontent, headers=[('Content-Type', 'application/vnd.ms-excel'), ('Content-Disposition', 'attachment; filename=table.xls;')], cookies={'fileToken': token}) - # Model = request.session.model(model) - # fields = [field] - # if filename_field: - # fields.append(filename_field) - # if data: - # res = { field: data } - # elif id: - # res = Model.read([int(id)], fields, context)[0] - # else: - # res = Model.default_get(fields, context) - # filecontent = base64.b64decode(res.get(field, '')) - # if not filecontent: - # raise ValueError(_("No content found for field '%s' on '%s:%s'") % - # (field, model, id)) - # else: - # filename = '%s_%s' % (model.replace('.', '_'), id) - # if filename_field: - # filename = res.get(filename_field, '') or filename - # return request.make_response(filecontent, - # headers=[('Content-Type', 'application/octet-stream'), - # ('Content-Disposition', content_disposition(filename))], - # cookies={'fileToken': token}) diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 19b7b04e269..79d814460df 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -371,6 +371,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ headers: this.build_headers(), measure_row: this.build_measure_row(), rows: this.build_rows(), + nbr_measures: this.pivot.measures.length }; }, @@ -418,12 +419,15 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return result; }, - add_color: function (cell, row, col, index) { + make_cell: function (row, col, value, index) { + var formatted_value = openerp.web.format_value(value, {type:this.pivot.measures[index].type}), + cell = {value:formatted_value}; + if (this.heatmap_mode === 'none') { return cell; } var total = (this.heatmap_mode === 'both') ? this.pivot.get_total()[index] : (this.heatmap_mode === 'row') ? this.pivot.get_total(row)[index] : this.pivot.get_total(col)[index]; - var color = Math.floor(90 + 165*(total - Math.abs(cell.value))/total); + var color = Math.floor(90 + 165*(total - Math.abs(value))/total); if (color < 255) { cell.color = color; } @@ -433,21 +437,22 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ build_rows: function () { var self = this, pivot = this.pivot, - m, - add_total = pivot.get_cols_leaves().length > 1; + m, cell; return _.map(pivot.rows.headers, function (row) { var cells = []; _.each(pivot.get_cols_leaves(), function (col) { - var values = pivot.get_values(row.id, col.id); + var values = pivot.get_values(row.id,col.id); for (m = 0; m < pivot.measures.length; m++) { - cells.push(self.add_color({value:values[m], type:pivot.measures[m].type}, row,col,m)); + cells.push(self.make_cell(row,col,values[m], m)); } }); - if (add_total) { + if (pivot.get_cols_leaves().length > 1) { var totals = pivot.get_total(row); for (m = 0; m < pivot.measures.length; m++) { - cells.push(self.add_color({value:totals[m], type:pivot.measures[m].type, is_bold:true},row,pivot.main_col(),m)); + cell = self.make_cell(row, pivot.main_col(), totals[m], m); + cell.is_bold = 'true'; + cells.push(cell); } } return { @@ -549,8 +554,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ _.each(rows, function (row) { var html_row = $('').append(make_cell(row)); _.each(row.cells, function (cell) { - var value = openerp.web.format_value(cell.value, {type: cell.type}), - html_cell = $('').text(value); + var html_cell = $('').text(cell.value); if (_.has(cell, 'color')) { html_cell.css('background-color', $.Color(255, cell.color, cell.color)); } @@ -719,12 +723,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Controller stuff... // ---------------------------------------------------------------------- export_xls: function() { + var c = openerp.webclient.crashmanager; openerp.web.blockUI(); this.session.get_file({ url: '/web_graph/export_xls', data: {data: JSON.stringify(this.build_table())}, complete: openerp.web.unblockUI, - error: openerp.webclient.crashmanager.rpc_error.bind(c) + error: c.rpc_error.bind(c) }); },