构建 PDF 报告

重要

本教程是 服务器框架101 教程的扩展。确保您已完成它并使用您构建的 estate 模块作为本教程中练习的基础。

我们之前在 introduced to QWeb 中使用它来构建看板视图。现在我们将扩展 QWeb 的其他主要用途之一:创建 PDF 报告。一个常见的业务需求是能够创建发送给客户并在内部使用的文档。这些报告可用于在有组织的模板中汇总和显示信息,以不同的方式支持业务。 Odoo 还可以轻松地将我们公司的页眉和页脚添加到我们的报告中。

与此主题相关的文档可以在操作参考的 QWeb 模板QWeb 报告报告操作 (ir.actions.report) 部分中找到。

文件结构

PDF 报告的大部分内容是其 QWeb 模板。它通常还需要相应的“ir.actions.report` to include the report within a module’s business logic. There is no strict rule for the file names or where they are located, but these two parts are typically stored in 2 separate files within a report folder at the top level of your module’s directory. If a module has many or multiple long report templates, then they are often organized logically across different files named after the report(s) they contain. All actions for the reports are usually stored in the same file ending with ``_reports.xml`”,无论它包含多少个报告。

因此,预计您的工作树将如下所示:

estate
├── models
│   ├── *.py
│   └── __init__.py
├── report
│   ├── estate_property_templates.xml
│   └── estate_property_reports.xml
├── security
│   └── ir.model.access.csv
├── views
│   └── *.xml
├── __init__.py
└── __manifest__.py

不要忘记将模板和操作视图将要放入的任何文件添加到“__manifest__.py`. In this case, you will want to add the files to the ``data`”列表中,并记住清单中列出的文件是按顺序加载的!

基本报告

注解

目标:在本节结束时,我们将能够打印一份报告,显示该房产的所有报价。

简单的 PDF 报告

在我们的房地产示例中,我们可以创建许多有用的报告。我们可以创建一份简单的报告,显示一处房产的所有报价。

报告数据

在我们做任何事情之前,我们首先需要一些数据来填充我们的报告,否则本教程不会很有趣。创建报告时,您将需要一些数据来测试报告代码并检查生成的外观是否符合预期。最好使用涵盖大部分或全部预期用例的数据进行测试。我们的简单报告的一个很好的表示集是:

  • 至少 3 处房产,其中 1 处为“已售”,1 处为“已收到报价”,1 处为“新”。

  • 我们的“已售出”和“已收到报价”房产至少有 2-3 个报价

如果您还没有这样的数据集,您可以:

  • 完成 定义模块数据 教程(如果您还没有这样做)并将额外的案例添加到演示数据中(您可能需要创建一个新数据库来加载演示数据)。

  • 在数据库中手动创建数据。

  • 将此 data file 复制到您的房地产模块中的新目录(数据)中,并将 these lines 复制到您的 __manifest__.py 文件中(您可能需要创建一个新数据库来加载演示数据)。

在继续之前,请单击数据库中的数据并确保您的数据符合预期。当然,您可以在编写报告代码后添加数据,但随后您将无法在编写代码时增量测试部分代码。从长远来看,对于复杂的报告来说,这可能会使检查错误和调试代码变得更加困难。

最小模板

最小可行模板可在 报告模板 文档的“最小可行模板”部分中查看。我们可以修改此示例来构建我们的最小属性报价模板文件:

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <template id="report_property_offers">
        <t t-foreach="docs" t-as="property">
            <t t-call="web.html_container">
                <t t-call="web.external_layout">
                    <div class="page">
                        <h2>
                            <span t-field="property.name"/>
                        </h2>
                        <div>
                            <strong>Expected Price: </strong>
                            <span t-field="property.expected_price"/>
                        </div>
                        <table class="table">
                            <thead>
                                <tr>
                                    <th>Price</th>
                                </tr>
                            </thead>
                            <tbody>
                                <t t-set="offers" t-value="property.mapped('offer_ids')"/>
                                <tr t-foreach="offers" t-as="offer">
                                    <td>
                                        <span t-field="offer.price"/>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </t>
            </t>
        </t>
    </template>
</odoo>

我们文件中的大多数 Odoo 特定(即非 HTML)项目在最小可行模板部分中进行了解释。我们的模板中的一些附加功能包括:

  • 使用``class=”table”``属性,所以我们的表有一些很好的格式。 Twitter Bootstrap(在本例中我们使用其表类)和 Font Awesome(对于添加图标很有用)类可以在您的报告模板中使用。

  • 使用``t-set``, t-value, t-foreach, and t-as so that we can loop over all the offer_ids

如果您已经熟悉网站模板引擎,那么 QWeb 指令(即 t- 命令)可能不需要太多解释,您只需查看它的 documentation 并跳到下一小节。

否则,我们鼓励您阅读有关它们的更多信息(Wikipedia 有很好的高级描述),但总体思路是 QWeb 提供了基于 Odoo 数据和简单命令动态生成 W​​eb 代码的能力。 IE。 QWeb 可以访问记录集数据(和方法)并处理简单的编程操作,例如设置和访问临时变量。例如,在上面的例子中:

  • t-set creates a temporary variable called “offers” that has its value set by t-value to the current estate.property recordset’s offer_ids

  • t-foreach and t-as 用法与 Python 等效:

for offer in offers:

报告行动

现在我们有了一个模板,我们需要通过``ir.actions.report``. A practical example of ir.actions.report is here corresponding to `this template <https://github.com/odoo/odoo/blob/0e12fa135882cd5095dbf15fe2f64231c6a84336/addons/event/report/event_event_templates.xml#L5>`__在我们的应用程序中访问它。其内容均在:ref:`the documentation <reference/actions/report>`中解释。

ir.actions.report is primarily used via the Print menu of a model’s view. In the practical example, the binding_model_id 指定报告应显示哪个模型的视图,Odoo 会自动为您添加它。报告操作的另一个常见用例是将其链接到我们在 第 9 章:准备好采取行动了吗? 中了解到的按钮。这对于仅在特定条件下有意义的报告非常方便。例如,如果我们想要制作“最终销售”报告,那么我们可以将其链接到仅当属性为“已售出”时出现在表单视图中的“打印销售信息”按钮。

打印菜单按钮

您可能已经注意到或想知道为什么我们的报告模板会循环遍历记录集。当我们的模板传递多条记录时,它可以为所有记录生成一份 PDF 报告。使用列表视图中的“打印”菜单并选择多个记录将演示这一点。

做报告

最后,您现在知道在哪里创建文件以及文件内容应如何显示。快乐的报告制作!

Exercise

做报告。

  • 将属性提供报告从最小模板子部分添加到属性视图的打印菜单。

  • 通过添加更多数据来改进报告。请参阅本节的**目标**,了解您可以添加哪些附加数据,并随意添加更多数据。

  • 奖励:通过添加一些逻辑来制作一个额外灵活的报告,这样当某个房产没有报价时,我们就不会创建一个表格,而是写一些关于如何还没有报价的内容。提示:您需要使用“t-if` and ``t-else`”。

请记住检查您的 PDF 报告是否与预期的数据相符。

子模板

注解

目标:在本节末尾,我们将有一个在 2 个报告中使用的子模板。

使用子模板进行报告

使用子模板有两个主要原因。一是在使用超长或复杂的模板时使代码更易于阅读。另一个是尽可能重用代码。我们简单的房产报价报告非常有用,但列出房产报价信息不仅仅对一个报告模板有用。一个例子是一份列出推销员所有房产报价的报告。

看看您是否可以通过阅读子模板上的 documentation 和/或查看 example 来了解如何调用子模板(请记住,无论是用于 Odoo 中的报表还是视图,QWeb 使用相同的控制流。)

Exercise

创建并使用子模板。

  • 将报价的表格部分拆分为自己的模板。请记住检查您的原始报告之后是否仍能正确打印。

  • 添加“res.users` that allows you to print all of the Real Estate Properties that are visible in their form view (i.e. in the “Settings” app). Include the offers for each of those saleman’s properties in the same report. Hint: since the binding_model_id in this case will not be within the estate module, you will need to use ``ref=”base.model_res_users”`”的新报告。

    您的最终结果应类似于本节 目标 中的图像。

请记住检查您的报告是否与预期的数据相符!

报告继承

注解

目标:在本节结束时,我们将继承``estate_account``模块中的属性报告。

继承的报告

QWeb 中的继承使用相同的 xpath elements as views inheritance. A QWeb template refers to its parent template in a different way though. It is even easier to do by just adding the inherit_id attribute to the template 元素并将其设置为等于 module.parent_template_id

我们没有向 estate_account 中的任何房地产模型添加任何新字段,但我们仍然可以向现有的房地产报告添加信息。例如,我们知道任何“已售出”房产都已经为其创建了发票,因此我们可以将此信息添加到我们的报告中。

Exercise

继承报告。

  • 扩展财产报告以包括有关发票的一些信息。您可以查看本节的 目标 以获取灵感(即,当属性完成时打印一行,否则不打印任何内容)。

再次强调,请记住检查您的报告是否与预期的数据相符!

附加功能

QWeb 报告 文档中进一步描述了以下所有额外功能,包括如何实现每个功能。

翻译

我们都知道,由于自动和手动翻译,Odoo 可用于多种语言。 QWeb 报告也不例外!请注意,如果模板的文本内容中存在不必要的空格,有时翻译将无法正常工作,因此请尽可能避免使用它们(尤其是前导空格)。

报告是网页

您可能已经厌倦了 QWeb 创建 HTML,但我们再说一遍!用 QWeb 编写的报告的一大优点是可以在 Web 浏览器中查看它们。如果您想嵌入指向特定报告的超链接,这会很有用。请注意,通常的安全检查仍然适用,以防止未经授权的用户访问报告。

条形码

Odoo 有一个内置的条形码图像创建器,允许将条形码嵌入到您的报告中。查看相应的 code 以查看所有支持的条形码类型。