QWeb 报表¶
报表使用 HTML/QWeb 编写,与 Odoo 中的网站视图类似。可以使用常规的 QWeb 控制流工具。PDF 渲染本身由 wkhtmltopdf 完成。
如有用或有必要,还可以为报表指定 纸张格式。
报表模板¶
报表模板始终提供以下变量:
time对 Python 标准库中
time的引用user打印报表用户的
res.user记录res_company当前
user所属公司的记录website当前网站对象(如果有)(该项可能存在但为
None)web_base_urlWeb 服务器的基础 URL
context_timestamp一个接收采用 UTC1 的
datetime.datetime并将其转换为打印报表用户时区的函数
最小可用模板¶
最小模板如下所示:
<template id="report_invoice">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="web.external_layout">
<div class="page">
<h2>Report title</h2>
<p>This object's name is <span t-field="o.name"/></p>
</div>
</t>
</t>
</t>
</template>
调用 external_layout 会为报表添加默认页眉和页脚。PDF 正文将是 <div class="page"> 中的内容。模板的 id 必须是报表声明中指定的名称;例如上述报表使用 account.report_invoice。由于这是 QWeb 模板,你可以访问模板接收到的 docs 对象的所有字段。
默认情况下,渲染上下文还会暴露以下条目:
docs当前报表的记录
doc_idsdocs记录的 ID 列表doc_modeldocs记录的模型
如果希望在模板中访问其他记录/模型,则需要 自定义报表;但在这种情况下,如需上述条目,你必须自行提供。
可翻译模板¶
如果希望翻译报表(例如翻译为业务伙伴的语言),需要定义两个模板:
主报表模板
可翻译文档
然后可以在主模板中调用可翻译文档,并将 t-lang 属性设为语言代码(例如 fr 或 en_US)或记录字段。如果使用了可翻译字段(如国家名称、销售条款等),还需要使用正确的上下文重新浏览相关记录。
警告
如果你的报表模板不使用可翻译的记录字段,则用另一种语言重新浏览记录是 不 必要的,且会影响性能。
例如,我们来看销售模块中的销售订单报表:
<!-- Main template -->
<template id="report_saleorder">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="sale.report_saleorder_document" t-lang="doc.partner_id.lang"/>
</t>
</t>
</template>
<!-- Translatable template -->
<template id="report_saleorder_document">
<!-- Re-browse of the record with the partner lang -->
<t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)" />
<t t-call="web.external_layout">
<div class="page">
<div class="oe_structure"/>
<div class="row">
<div class="col-6">
<strong t-if="doc.partner_shipping_id == doc.partner_invoice_id">Invoice and shipping address:</strong>
<strong t-if="doc.partner_shipping_id != doc.partner_invoice_id">Invoice address:</strong>
<div t-field="doc.partner_invoice_id" t-options="{"no_marker": True}"/>
<...>
<div class="oe_structure"/>
</div>
</t>
</template>
主模板以 doc.partner_id.lang 作为 t-lang 参数调用可翻译模板,因此会以业务伙伴的语言渲染。这样一来,每张销售订单都会以对应客户的语言打印。如果只想翻译文档正文,而让页眉和页脚保持默认语言,可以这样调用报表的外部布局:
<t t-call="web.external_layout" t-lang="en_US">
小技巧
请注意,这仅在调用外部模板时有效;无法通过在 t-call 以外的 xml 节点上设置 t-lang 属性来翻译文档的某一部分。如果希望翻译模板的一部分,可以创建包含该部分模板的外部模板,并在主模板中通过 t-lang 属性调用它。
条码作业¶
条形码是由控制器返回的图像,借助 QWeb 语法可以轻松嵌入报表中(例如参见 attributes):
<img t-att-src="'/report/barcode/QR/%s' % 'My text in qr code'"/>
更多参数可以通过查询字符串传递
<img t-att-src="'/report/barcode/?
barcode_type=%s&value=%s&width=%s&height=%s'%('QR', 'text', 200, 200)"/>
实用备注¶
可以在报表模板中使用 Twitter Bootstrap 和 FontAwesome 类
本地 CSS 可以直接放入模板中
全局 CSS 可以通过继承主报表布局的模板并插入你的 CSS,将其添加到主报表布局中:
<template id="report_saleorder_style" inherit_id="report.style"> <xpath expr="."> <t> .example-css-class { background-color: red; } </t> </xpath> </template>
如果你的 PDF 报表缺少样式,请查看 这些说明。
纸张格式¶
纸张格式是 report.paperformat 的记录,可以包含以下属性:
name(必填)仅在某种列表中查找报表时用作助记或描述
description格式的简短描述
format预定义格式(A0 至 A9、B0 至 B10、Legal、Letter、Tabloid……)或
custom;默认为 A4。如果定义了页面尺寸,则不能使用非自定义格式。dpi输出 DPI;默认为 90
margin_top,margin_bottom,margin_left,margin_right以毫米为单位的边距大小
page_height,page_width以毫米为单位的页面尺寸
orientation横向(Landscape)或纵向(Portrait)
header_line是否显示页眉线的布尔值
header_spacing以毫米为单位的页眉间距
示例:
<record id="paperformat_frenchcheck" model="report.paperformat">
<field name="name">French Bank Check</field>
<field name="default" eval="True"/>
<field name="format">custom</field>
<field name="page_height">80</field>
<field name="page_width">175</field>
<field name="orientation">Portrait</field>
<field name="margin_top">3</field>
<field name="margin_bottom">3</field>
<field name="margin_left">3</field>
<field name="margin_right">3</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">3</field>
<field name="dpi">80</field>
</record>
自定义报表¶
默认情况下,报表系统根据 model 字段指定的目标模型构建渲染值。
但是,它会先查找名为 report.module.report_name 的模型,并调用该模型的 _get_report_values(doc_ids, data),为模板准备渲染数据。
这可用于在渲染模板时加入要使用或显示的任意内容,例如来自其他模型的数据:
from odoo import api, models
class ParticularReport(models.AbstractModel):
_name = 'report.module.report_name'
def _get_report_values(self, docids, data=None):
# get the report action back as we will need its data
report = self.env['ir.actions.report']._get_report_from_name('module.report_name')
# get the records selected for this rendering of the report
obj = self.env[report.model].browse(docids)
# return a custom rendering context
return {
'lines': docids.get_lines()
}
警告
使用自定义报表时,与文档相关的“默认”内容(doc_ids、doc_model 和 docs) 不会 被包含。如果需要,你必须自行包含它们。
在上面的示例中,渲染上下文将包含“全局”值以及我们在其中放入的 lines,除此之外没有其他内容。
自定义字体¶
如果你想使用自定义字体,需要将自定义字体及相关的 less/CSS 添加到 web.reports_assets_common 资源包中。将自定义字体添加到 web.assets_common 或 web.assets_backend 并不能使字体在 QWeb 报表中可用。
示例:
<template id="report_assets_common_custom_fonts" name="Custom QWeb fonts" inherit_id="web.report_assets_common">
<xpath expr="." position="inside">
<link href="/your_module/static/src/less/fonts.less" rel="stylesheet" type="text/less"/>
</xpath>
</template>
你需要在这个 less 文件中定义 @font-face,即使你已在另一个资源包(web.reports_assets_common 之外)中使用过它。
示例:
@font-face {
font-family: 'MonixBold';
src: local('MonixBold'), local('MonixBold'), url(/your_module/static/fonts/MonixBold-Regular.otf) format('opentype');
}
.h1-title-big {
font-family: MonixBold;
font-size: 60px;
color: #3399cc;
}
将 less 添加到资源包后,你便可以在自定义 QWeb 报表中使用这些类,例如本例中的 h1-title-big。
报表即网页¶
报表由 report 模块动态生成,可以直接通过 URL 访问:
例如,你可以通过访问 http://<server-address>/report/html/sale.report_saleorder/38 以 html 模式打开销售订单报表
或者你可以通过访问 http://<server-address>/report/pdf/sale.report_saleorder/38 获取 pdf 版本
- 1
无论
python:datetime对象实际处于哪个时区(包括无时区),在调整为用户的时区之前,其时区都会被无条件 设置 为 UTC