import uuid, json, werkzeug, werkzeug.utils from reportbro import Report, ReportBroError from odoo import http from odoo.tools import date_utils from odoo.http import request, Response,JsonRPCDispatcher from jinja2 import Environment, PackageLoader from urllib.parse import quote from werkzeug.exceptions import NotFound # def _json_response(self, result=None, error=None): # ir_http = self.request.registry['ir.http'] # try: # rule, args = ir_http._match(self.request.httprequest.path) # except NotFound: # self.params = self.request.get_http_params() # response = ir_http._serve_fallback() # if response: # self.dispatcher.post_dispatch(response) # return response # raise # # # if rule.endpoint and rule.endpoint.routing.get('my_json'): # response = {} # if error is not None: # response['error'] = error # if result is not None: # response = result # else: # # odoo返回的默认数据格式 # response = { # 'jsonrpc': '2.0', # 'id': self.jsonrequest.get('id') # } # if error is not None: # response['error'] = error # if result is not None: # response['result'] = result # # mime = 'application/json' # body = json.dumps(response, default=date_utils.json_default) # # return Response( # body, status=error and error.pop('http_status', 200) or 200, # headers=[('Content-Type', mime), ('Content-Length', len(body))] # ) # # # 重写JsonRequest中的_json_response方法 # # setattr(JsonRPCDispatcher, '_response', _json_response) class WmsReportServer(http.Controller): @http.route('/report_designer', type='http', auth='public', csrf=False, methods=['Get'], website=True, cors="*") def report_designer(self, **kw): env = Environment(loader=PackageLoader('odoo.addons.reportbro', 'templates')) template = env.get_template('report_designer.html') return template.render() @http.route('/api/report/get_report_id', type='json', auth='public', csrf=False, methods=['Post'], website=True, cors="*", my_json=True) def get_report_id(self, *args, **kwargs): res=request.env['report.designer'].sudo().search([],limit=1,order='create_date desc') id=res.name #res.sudo().unlink() return {'id':id,'code':0} @http.route('/api/report/report_save', type='json', auth='public', csrf=False, methods=['Post'], website=True, cors="*", my_json=True) def report_save(self, *args, **kwargs): data = dict(request.dispatcher.jsonrequest or {}) report_id = data.get('report_id', None) report_data = data.get('report_data', None) print(json.dumps(report_data)) if report_data is None or report_id is None: return {'code': 1, 'msg': '保存失败'} res = request.env['report.report'].sudo().search([('id', '=', int(report_id))], limit=1) if res: res.sudo().write({'report_data': json.dumps(report_data)}) return {'code': 0, 'msg': '保存成功'} else: return {'code': 1, 'msg': '保存失败'} @http.route('/api/report/report_read', type='json', auth='public', csrf=False, methods=['Post'], website=True,cors="*", my_json=True) def report_read(self, *args, **kwargs): data = dict(request.dispatcher.jsonrequest or {}) report_id = data.get('report_id', None) if report_id is None: return {'code': 1, 'msg': '读取失败'} res = request.env['report.report'].sudo().search([('id', '=', int(report_id))], limit=1) if res: report_data=res.report_data if res.report_data is False: report_data =str(json.dumps({'docElements': [], 'parameters': [ { 'id': 1, 'name': 'page_count', 'type': 'number', 'arrayItemType': 'string', 'eval': False, 'nullable': False, 'pattern': '', 'expression': '', 'showOnlyNameType': True, 'testData': '111' }, { 'id': 2, 'name': 'page_number', 'type': 'number', 'arrayItemType': 'string', 'eval': False, 'nullable': False, 'pattern': '', 'expression': '', 'showOnlyNameType': True, 'testData': '222' }], 'styles': [], 'version': 3, 'documentProperties': { 'pageFormat': 'A4', 'pageWidth': '', 'pageHeight': '', 'unit': 'mm', 'orientation': 'portrait', 'contentHeight': '', 'marginLeft': '', 'marginTop': '', 'marginRight': '', 'marginBottom': '', 'header': True, 'headerSize': '80', 'headerDisplay': 'always', 'footer': True, 'footerSize': '80', 'footerDisplay': 'always', 'patternLocale': 'en', 'patternCurrencySymbol': '$' }})) return {'code': 0, 'msg': json.loads(report_data)} else: return {'code': 1, 'msg': '模板不存在'} @http.route('/api/report/report_server/run', type='http', auth='public', methods=['Get', 'Post'], csrf=False, website=True, cors="*", my_json=True) def report_run(self, **kw): add_fonts = [dict(value='msyh', filename='msyh.ttf',bold_filename='msyhbd.ttf',italic_filename='msyh.ttf',bold_italic_filename='msyh.ttf')] method = str(request.httprequest.method) if method == 'POST': json_data = json.loads(kw['data']) report_definition = json_data.get('report') output_format = json_data.get('outputFormat') if output_format not in ('pdf', 'xlsx'): return {'HttpCode': 400, 'Msg': 'outputFormat parameter missing or invalid'} data = json_data.get('data') data=eval(str(json.dumps(data)).replace('False','')) is_test_data = bool(json_data.get('isTestData')) try: report = Report(report_definition, data, is_test_data, additional_fonts=add_fonts) except Exception as e: return {'HttpCode': 400, 'Msg': 'failed to initialize report: ' + str(e)} if report.errors: return {'HttpCode': 400, 'Msg': 'ReportError: ' + str(report.errors)} try: key = str(uuid.uuid4()) report_file_pdf = bytes(report.generate_pdf()) report_file_xlsx = bytes(report.generate_xlsx()) if request.env['wms.print.list'].search_count([('p_key', '=', key)]) == 0: request.env['wms.print.list'].create({'p_key': key, 'report_file_pdf': report_file_pdf, 'report_file_xlsx': report_file_xlsx}) return request.make_response('key:' + key, headers=[('Content-Type', 'text/html')]) except ReportBroError as err: return {'HttpCode': 400, 'Msg': 'ReportBroError: ' + str(err.error)} if method == 'GET': key = kw['key'] output_format = kw['outputFormat'] report = request.env['wms.print.list'].search([('p_key', '=', key)], limit=1) fname = 'report' if 'report_id' in kw: fname = kw['report_id'] if report: report_file = report.report_file_pdf if output_format == 'pdf': report_headers = [('Content-Type', 'application/pdf'), ('Content-Length', len(report_file)), ( 'Content-Disposition', 'inline; filename="%s.pdf"'%(quote(fname)))] else: report_file = report.report_file_xlsx report_headers = [ ('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'), ('Content-Length', len(report_file)), ('Content-Disposition', 'inline; filename="%s.xlsx"'%(quote(fname)))] return werkzeug.wrappers.Response(report_file, status=200, headers=report_headers) else: return {'HttpCode': 400, 'Msg': 'ReportBroError: '}