odoo-2-flectra-converter/odoo/ks_dashboard_ninja/controllers/ks_chart_export.py
2020-11-03 16:59:00 +01:00

135 lines
4.8 KiB
Python

import datetime
import io
import json
import operator
import re
from odoo import http
from odoo.addons.web.controllers.main import ExportFormat, serialize_exception
from odoo.exceptions import UserError
from odoo.http import content_disposition, request
from odoo.tools import pycompat
from odoo.tools.misc import xlwt
from odoo.tools.translate import _
class KsChartExport(ExportFormat, http.Controller):
def base(self, data, token):
params = json.loads(data)
header,chart_data = operator.itemgetter('header','chart_data')(params)
chart_data = json.loads(chart_data)
chart_data['labels'].insert(0,'Measure')
columns_headers = chart_data['labels']
import_data = []
for dataset in chart_data['datasets']:
dataset['data'].insert(0, dataset['label'])
import_data.append(dataset['data'])
return request.make_response(self.from_data(columns_headers, import_data),
headers=[('Content-Disposition',
content_disposition(self.filename(header))),
('Content-Type', self.content_type)],
cookies={'fileToken': token})
class KsChartExcelExport(KsChartExport, http.Controller):
# Excel needs raw data to correctly handle numbers and date values
raw_data = True
@http.route('/ks_dashboard_ninja/export/chart_xls', type='http', auth="user")
@serialize_exception
def index(self, data, token):
return self.base(data, token)
@property
def content_type(self):
return 'application/vnd.ms-excel'
def filename(self, base):
return base + '.xls'
def from_data(self, fields, rows):
if len(rows) > 65535:
raise UserError(_
('There are too many rows (%s rows, limit: 65535) to export as Excel 97-2003 (.xls) format. Consider splitting the export.') % len
(rows))
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Sheet 1')
for i, fieldname in enumerate(fields):
worksheet.write(0, i, fieldname)
worksheet.col(i).width = 8000 # around 220 pixels
base_style = xlwt.easyxf('align: wrap yes')
date_style = xlwt.easyxf('align: wrap yes', num_format_str='YYYY-MM-DD')
datetime_style = xlwt.easyxf('align: wrap yes', num_format_str='YYYY-MM-DD HH:mm:SS')
for row_index, row in enumerate(rows):
for cell_index, cell_value in enumerate(row):
cell_style = base_style
if isinstance(cell_value, bytes) and not isinstance(cell_value, pycompat.string_types):
# because xls uses raw export, we can get a bytes object
# here. xlwt does not support bytes values in Python 3 ->
# assume this is base64 and decode to a string, if this
# fails note that you can't export
try:
cell_value = pycompat.to_text(cell_value)
except UnicodeDecodeError:
raise UserError(_
("Binary fields can not be exported to Excel unless their content is base64-encoded. That does not seem to be the case for %s.") % fields[cell_index])
if isinstance(cell_value, pycompat.string_types):
cell_value = re.sub("\r", " ", pycompat.to_text(cell_value))
# Excel supports a maximum of 32767 characters in each cell:
cell_value = cell_value[:32767]
elif isinstance(cell_value, datetime.datetime):
cell_style = datetime_style
elif isinstance(cell_value, datetime.date):
cell_style = date_style
worksheet.write(row_index + 1, cell_index, cell_value, cell_style)
fp = io.BytesIO()
workbook.save(fp)
fp.seek(0)
data = fp.read()
fp.close()
return data
class KsChartCsvExport(KsChartExport, http.Controller):
@http.route('/ks_dashboard_ninja/export/chart_csv', type='http', auth="user")
@serialize_exception
def index(self, data, token):
return self.base(data, token)
@property
def content_type(self):
return 'text/csv;charset=utf8'
def filename(self, base):
return base + '.csv'
def from_data(self, fields, rows):
fp = io.BytesIO()
writer = pycompat.csv_writer(fp, quoting=1)
writer.writerow(fields)
for data in rows:
row = []
for d in data:
# Spreadsheet apps tend to detect formulas on leading =, + and -
if isinstance(d, pycompat.string_types) and d.startswith(('=', '-', '+')):
d = "'" + d
row.append(pycompat.to_text(d))
writer.writerow(row)
return fp.getvalue()