You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo万级记录PDF报表生成遇Wkhtmltopdf(-11)错误求助

解决Odoo大规模报表生成时Wkhtmltopdf报错问题

一、调整系统与Wkhtmltopdf配置

针对错误提示的内存/子进程限制问题,先从基础配置入手优化:

  • 增加Wkhtmltopdf内存配额:在Odoo调用Wkhtmltopdf的参数中添加--memory-size 2048(单位MB,可根据服务器配置调整),提升其可用内存上限。可修改Odoo的report模块中_run_wkhtmltopdf方法的command_args列表,加入该参数。
  • 放宽系统资源限制:
    • 临时调整Odoo运行用户的文件句柄限制:执行ulimit -n 4096(需重启Odoo生效)
    • 永久配置:在/etc/security/limits.conf中添加:
      odoo soft nofile 4096
      odoo hard nofile 8192
      
  • 更新Wkhtmltopdf版本:旧版本存在内存泄漏问题,升级至与当前Odoo版本兼容的最新稳定版(如0.12.6)。

二、分批生成并合并PDF(最佳实践)

直接生成10000条记录的超大HTML会耗尽内存,核心解决方案是拆分批次生成后合并:

代码实现示例

import base64
import io
from PyPDF2 import PdfMerger

def print_pdf(self):
    batch_size = 1000  # 可根据服务器性能调整
    sale_lines = self.sale_ids or self.env['sale.order.line'].search(
        [], ['salesman_id', 'product_id', 'name', 'price_unit',
             'qty_to_deliver', 'price_subtotal', 'state'])
    total_batches = (len(sale_lines) + batch_size - 1) // batch_size
    merger = PdfMerger()

    # 分批生成PDF并合并
    for batch_num in range(total_batches):
        start = batch_num * batch_size
        end = start + batch_size
        batch_data = {'inner': sale_lines[start:end].read([
            'salesman_id', 'product_id', 'name', 'price_unit',
            'qty_to_deliver', 'price_subtotal', 'state'
        ])}
        # 渲染单批次PDF
        pdf_content, _ = self.env.ref('coc_bot.sale_order_report').render_qweb_pdf(
            res_ids=None, data=batch_data)
        merger.append(io.BytesIO(pdf_content))

    # 生成合并后的PDF附件并返回下载链接
    merged_buffer = io.BytesIO()
    merger.write(merged_buffer)
    merged_buffer.seek(0)
    attachment = self.env['ir.attachment'].create({
        'name': '批量销售订单报表.pdf',
        'datas': base64.b64encode(merged_buffer.getvalue()),
        'type': 'binary'
    })
    return {
        'type': 'ir.actions.act_url',
        'url': f'web/content/?model=ir.attachment&id={attachment.id}&filename_field=name&field=datas&download=true&filename=批量销售订单报表.pdf',
        'target': 'new',
    }

注意:需先安装PyPDF2库(pip install PyPDF2)

三、优化报表HTML结构

  • 添加分页CSS:在报表XML模板中加入分页样式,避免Wkhtmltopdf因处理超长表格耗尽内存:
    <style>
        table { page-break-inside: avoid; }
        tr { page-break-inside: avoid; }
        .page-break { page-break-after: always; }
    </style>
    
  • 简化DOM元素:移除模板中不必要的嵌套标签、冗余样式,减少HTML解析时的内存占用。

四、Odoo内部逻辑优化

  • 避免一次性加载全量数据:原代码中search_read一次性读取10000条记录,改为分批读取减少内存占用。
  • 启用异步任务:若报表生成耗时较长,使用Odoo的queue_job模块将生成任务放入后台队列,避免阻塞前端界面。

五、错误排查补充

  • 查看系统内核日志(如/var/log/syslog),确认是否存在OOM(内存不足)或进程资源耗尽的详细记录。
  • 逐步调整批次大小,找到服务器能稳定处理的最大单批次记录数。

内容的提问来源于stack exchange,提问作者Abhin k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:32:39