odoo 下载大量pdf使用内存太大,异常退出,pdf 分页
说白了,还是因为wkhtmltopdf工具使用的内存太大,打印200个页面就会直接内存超标,直接退出
直接改源码了,每次让pdf 转换工具只处理50个记录
@http.route(['/report/download'], type='http', auth="user") def report_download(self, data, token): """This function is used by 'action_manager_report.js' in order to trigger the download of a pdf/controller report. :param data: a javascript array JSON.stringified containg report internal url ([0]) and type [1] :returns: Response with a filetoken cookie and an attachment header """ requestcontent = json.loads(data) url, type = requestcontent[0], requestcontent[1] try: if type in ['qweb-pdf', 'qweb-text']: converter = 'pdf' if type == 'qweb-pdf' else 'text' extension = 'pdf' if type == 'qweb-pdf' else 'txt' pattern = '/report/pdf/' if type == 'qweb-pdf' else '/report/text/' reportname = url.split(pattern)[1].split('?')[0] docids = None if '/' in reportname: reportname, docids = reportname.split('/') if docids: # Generic report: data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON response = self.report_routes(reportname, docids=docids, converter=converter, **dict(data)) else: # Particular report: data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON response = self.report_routes(reportname, converter=converter, **dict(data)) report_context = dict(url_decode(url.split('?')[1]).items()) report = request.env['ir.actions.report']._get_report_from_name(reportname) filename = "%s.%s" % (report.name, extension) report_name = report.name if docids: ids = [int(x) for x in docids.split(",")] obj = request.env[report.model].browse(ids) if report.print_report_name and not len(obj) > 1: report_name = safe_eval(report.print_report_name, {'object': obj, 'time': time}) filename = "%s.%s" % (report_name, extension) response.headers.add('Content-Disposition', content_disposition(filename)) response.set_cookie('fileToken', token) if report_context.get('backend'): # 如果选择了后台运行,则保存到附件中,并返回None self.save_attachment(response.data, report_name, filename) return None return response else: return except Exception as e: se = _serialize_exception(e) error = { 'code': 200, 'message': "Odoo Server Error", 'data': se } return request.make_response(html_escape(json.dumps(error))) @http.route([ '/report/<converter>/<reportname>', '/report/<converter>/<reportname>/<docids>', ], type='http', auth='user', website=True) def report_routes(self, reportname, docids=None, converter=None, **data): report = request.env['ir.actions.report']._get_report_from_name(reportname) context = dict(request.env.context) if docids: docids = [int(i) for i in docids.split(',')] if data.get('options'): data.update(json.loads(data.pop('options'))) if data.get('context'): # Ignore 'lang' here, because the context in data is the one from the webclient *but* if # the user explicitely wants to change the lang, this mechanism overwrites it. data['context'] = json.loads(data['context']) if data['context'].get('lang'): del data['context']['lang'] context.update(data['context']) if converter == 'html': html = report.with_context(context).render_qweb_html(docids, data=data)[0] return request.make_response(html) elif converter == 'pdf': list_pdf_temp= [] for list_docid in self.generator_five(docids, 50): pdf_temp = report.with_context(context).render_qweb_pdf(list_docid, data=data)[0] list_pdf_temp.append(pdf_temp) data_pdf = pdf_tool.merge_pdf(list_pdf_temp) pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(data_pdf))] return request.make_response(data_pdf, headers=pdfhttpheaders) elif converter == 'text': text = report.with_context(context).render_qweb_text(docids, data=data)[0] texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))] return request.make_response(text, headers=texthttpheaders) else: raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter) def save_attachment(self, datas,report_name, file_name): """ <record id="documents_vendor_bill_extract_azure_interior" model="ir.attachment"> <field name="name">Invoice Azure Interior</field> <field name="datas_fname">invoice_azure_interior.pdf</field> <field name="datas" type="base64" file="documents/demo/files/invoice_azure_interior.pdf"/> <field name="folder_id" ref="documents_finance_folder"/> </record> """ attach = request.env['ir.attachment'] var = dict(name=report_name, datas_fname=file_name, datas=base64.b64encode(datas).decode('utf-8'), folder_id=request.env.ref('documents.documents_finance_folder').id ) attach.create([var]) @staticmethod def generator_five(parm, num): """ 将列表切分成每5个来返回 :param parm: :return: """ length = len(parm) for i in range(0, length, num): yield parm[i:i + num]
本文来自博客园,作者:那时一个人,转载请注明原文链接:https://www.cnblogs.com/qianxunman/p/17635751.html
标签:
odoo
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下