无one2many字段时,如何将Odoo SQL视图树视图导出为PDF
解决Odoo中SQL视图模型PDF报表分页及循环问题
核心问题分析
你的purchase.comp模型是基于SQL视图创建的_auto=False模型,每条记录对应一个采购订单行(从SQL查询能看到,是purchase_order和purchase_order_line关联后的扁平化结果),所以不存在one2many字段——因为这个模型本身就是行级数据,而非主记录带子行的结构。之前PDF每页只显示一行,大概率是因为你在QWeb模板里错误地将每条记录单独放在了一个<div class="page">容器中。
1. XML报表中可直接循环的内容
你不需要找one2many字段,直接循环报表传入的docs变量即可——docs就是purchase.comp模型的记录集,每条记录对应一个采购订单行的完整数据,你可以直接访问模型定义的所有字段:name、origin、date_order、product_id、product_qty等。
2. 正确的QWeb报表模板写法
以下是实现所有行在同一页面展示的模板示例:
<odoo> <!-- 注册报表 --> <report id="report_purchase_comp" string="Purchase Comparison Report" model="purchase.comp" report_type="qweb-pdf" name="your_module_name.report_purchase_comp_template" file="your_module_name.report_purchase_comp_template" /> <!-- 报表模板 --> <template id="report_purchase_comp_template"> <t t-call="web.html_container"> <!-- 只创建一个页面容器,所有行都放在这个页面里 --> <div class="page"> <h2>Purchase Order Comparison</h2> <!-- 用表格展示所有数据 --> <table class="table table-bordered"> <thead> <tr> <th>Purchase Order</th> <th>Purchase Agreement</th> <th>Order Date</th> <th>Status</th> <th>Product</th> <th>Quantity</th> <th>Unit Price</th> <th>Subtotal</th> <th>Vendor</th> <th>Currency</th> </tr> </thead> <tbody> <!-- 循环所有purchase.comp记录,生成表格行 --> <t t-foreach="docs" t-as="line"> <tr> <td><t t-esc="line.name"/></td> <td><t t-esc="line.origin"/></td> <td><t t-esc="line.date_order"/></td> <td><t t-esc="line.state"/></td> <td><t t-esc="line.product_id"/></td> <td><t t-esc="line.product_qty"/></td> <td><t t-esc="line.price_unit"/></td> <td><t t-esc="line.price_subtotal"/></td> <td><t t-esc="line.vendor"/></td> <td><t t-esc="line.currency_id"/></td> </tr> </t> </tbody> </table> </div> </t> </template> </odoo>
3. 优化分页行为(强制同一页)
如果数据量不大,上述模板已经能让所有行在同一页展示。如果数据较多导致自动分页,可以添加CSS禁止表格内分页:
在模板中加入样式块:
<template id="report_purchase_comp_style" inherit_id="web.report_assets_common"> <xpath expr="." position="inside"> <style> @media print { .page { page-break-inside: avoid !important; } table tbody { page-break-inside: avoid !important; } } </style> </xpath> </template>
注意:如果数据量极大(超过单页可容纳的内容),浏览器还是会自动分页,这是PDF打印的固有限制,无法完全避免。
4. 额外注意事项
- 打印时确保在Odoo列表视图中选中所有需要导出的记录,再点击打印按钮;如果直接打开单个记录的打印,只会导出当前行。
- 你的模型字段
currency_id定义为Char类型,其实可以改成Many2one关联res.currency,这样在报表中可以直接显示货币符号或格式化金额,更规范:
对应的SQL查询中改为currency_id = fields.Many2one('res.currency', string='Currency')d.id as currency_id即可(不需要d.name,因为Many2one会自动关联显示名称)。
内容的提问来源于stack exchange,提问作者Abdullah Rehman
相关产品推荐
相关产品推荐

