用户故事:
在打印大批量pdf 文件时会有较长事件的等待, 而且容易中断
原因
中断原因, 有内存及超时限制,wkhtmltopdf工具比较吃内存
解决方案:
内存限制的问题可以分批处理,比如每次只处理50条记录
代码示例,使用按钮触发的打印功能:
# model: res.partner
@api.model
def save_attachment(self, datas,report_name, file_name,res_id=None, res_model='queue.job'):
"""
<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>
pdf文件保存在附件中,并绑定queque_job 记录
"""
attach = self.env['ir.attachment']
var = dict(name=report_name,
datas_fname=file_name,
datas=base64.b64encode(datas).decode('utf-8'),
folder_id=self.env.ref('documents.documents_finance_folder').id,
res_model=res_model,
res_id=res_id
)
attach.create([var])
def do_button_print_statement(self):
_logger.info('do_button_print_statement_context:{}'.format(self._context))
report_info = self.env.ref('account_statement.report_customert_print').report_action(self)
if self._context.get('is_backend'):
# 用户可以选择是否后台运行打印任务
self.save_in_attachment(report_info)
return None
return report_info
@api.model
def save_in_attachment(self, report_info):
"""
将打印的文件保存在附件中,odoo 服务器中,不直接下载, 针对打印的pdf 数量太多的情况
"""
report_name = report_info.get('report_name')
name = report_info.get('name')
report_type = report_info.get('report_type')
report = self.env['ir.actions.report']._get_report_from_name(report_name)
context = report_info.get('context')
context.update(date_end = str(context.get('date_end')))
list_pdf_bytes = []
for list_id in list_split(self.ids, 50):
pdf_bytes = report.with_context(context).render_qweb_pdf(list_id, data=context)[0]
list_pdf_bytes.append(pdf_bytes)
sum_pdf = merge_pdf(list_pdf_bytes)
job_uid = context.get('job_uuid')
queue = self.env['queue.job'].search([('uuid','=',job_uid)])
self.save_attachment(sum_pdf, name, '{}.pdf'.format(name), queue.id)
queue.message_subscribe(partner_ids=queue.user_id.partner_id.ids)
queue.sudo().message_post(body='Report generate success!', message_type='notification', subtype='queue_job.mt_job_failed')
效果展示
- 后台任务完成后会发送完成提示
- 附件可以在queue_job 记录中获取
- 附件可以在document 模块中中获取
- 前端界面:
懂得,原来世界如此简单!