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

无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,这样在报表中可以直接显示货币符号或格式化金额,更规范:
    currency_id = fields.Many2one('res.currency', string='Currency')
    
    对应的SQL查询中改为d.id as currency_id即可(不需要d.name,因为Many2one会自动关联显示名称)。

内容的提问来源于stack exchange,提问作者Abdullah Rehman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:36:16