[FIX] Error in excel export when sheet name > 31 characters
[odoo/odoo.git] / addons / web_graph / controllers / main.py
1 from openerp import http
2 import simplejson
3 from openerp.http import request, serialize_exception as _serialize_exception
4 from cStringIO import StringIO
5 from collections import deque
6
7 try:
8     import xlwt
9 except ImportError:
10     xlwt = None
11
12 class TableExporter(http.Controller):
13
14     @http.route('/web_graph/check_xlwt', type='json', auth='none')
15     def check_xlwt(self):
16         return xlwt is not None
17
18
19     @http.route('/web_graph/export_xls', type='http', auth="user")
20     def export_xls(self, data, token):
21         jdata = simplejson.loads(data)
22         nbr_measures = jdata['nbr_measures']
23         workbook = xlwt.Workbook()
24         worksheet = workbook.add_sheet(jdata['title'][:30])
25         header_bold = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;")
26         header_plain = xlwt.easyxf("pattern: pattern solid, fore_colour gray25;")
27         bold = xlwt.easyxf("font: bold on;")
28
29         # Step 1: writing headers
30         headers = jdata['headers']
31
32         # x,y: current coordinates 
33         # carry: queue containing cell information when a cell has a >= 2 height
34         #      and the drawing code needs to add empty cells below
35         x, y, carry = 1, 0, deque()  
36         for i, header_row in enumerate(headers):
37             worksheet.write(i,0, '', header_plain)
38             for header in header_row:
39                 while (carry and carry[0]['x'] == x):
40                     cell = carry.popleft()
41                     for i in range(nbr_measures):
42                         worksheet.write(y, x+i, '', header_plain)
43                     if cell['height'] > 1:
44                         carry.append({'x': x, 'height':cell['height'] - 1})
45                     x = x + nbr_measures
46                 style = header_plain if 'expanded' in header else header_bold
47                 for i in range(header['width']):
48                     worksheet.write(y, x + i, header['title'] if i == 0 else '', style)
49                 if header['height'] > 1:
50                     carry.append({'x': x, 'height':header['height'] - 1})
51                 x = x + header['width'];
52             while (carry and carry[0]['x'] == x):
53                 cell = carry.popleft()
54                 for i in range(nbr_measures):
55                     worksheet.write(y, x+i, '', header_plain)
56                 if cell['height'] > 1:
57                     carry.append({'x': x, 'height':cell['height'] - 1})
58                 x = x + nbr_measures
59             x, y = 1, y + 1
60
61         # Step 2: measure row
62         if nbr_measures > 1:
63             worksheet.write(y,0, '', header_plain)
64             for measure in jdata['measure_row']:
65                 style = header_bold if measure['is_bold'] else header_plain
66                 worksheet.write(y, x, measure['text'], style);
67                 x = x + 1
68             y = y + 1
69
70         # Step 3: writing data
71         x = 0
72         for row in jdata['rows']:
73             worksheet.write(y, x, row['indent'] * '     ' + row['title'], header_plain)
74             for cell in row['cells']:
75                 x = x + 1
76                 if cell.get('is_bold', False):
77                     worksheet.write(y, x, cell['value'], bold)
78                 else:
79                     worksheet.write(y, x, cell['value'])
80             x, y = 0, y + 1
81
82         response = request.make_response(None,
83             headers=[('Content-Type', 'application/vnd.ms-excel'),
84                     ('Content-Disposition', 'attachment; filename=table.xls;')],
85             cookies={'fileToken': token})
86         workbook.save(response.stream)
87
88         return response