第十一章 报表
报表引擎
当前版本(17.0)odoo的报表引擎使用的是QWeb和wkhtmltopdf插件完成的,关于QWeb的的更多内容,会在第二部分中有单独的篇章介绍,本章主要介绍报表的创建流程。
创建报表
下面介绍一下编写报表的步骤
1. 定义报表动作
首先,我们需要定义一个报表:
<record model="ir.actions.report" id="sale_tag_report.report">
<field name="name">标签打印</field>
<field name="model">sale.order</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">sale_tag_report.tag</field>
<field name="print_report_name">(object.name)</field>
<field name="binding_model_id" ref="sale.model_sale_order"/>
</record>
报表定义有简化的写法:
<report id="report_product_packaging"
string="Product Packaging (PDF)"
model="product.packaging"
report_type="qweb-pdf"
name="product.report_packagingbarcode"
file="product.report_packagingbarcode"
print_report_name="'Products packaging - %s' % (object.name)"/>
简化写法在17.0中已失效
这在系统中将会生成一条记录(系统设置-技术-报表):
其中,binding_model_id决定了该按钮绑定在那个模型上面显示。
2. 报表的结构
odoo中的一个报表大致可以分为两块结构:
- 报表外层(container)
- 报表视图文件(document)
我们首先来定义一个报表的container外衣:
<template id="tag>
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="mommy_hr_expense.report_petty_cash_document"/>
</t>
</t>
</template>
这我们定义了一个html_container,在container中我们将当前模型docs进行了遍历,赋值给了变量doc.
然后我们来定义一个视图文件(报表主体):
<template id="report_petty_cash_document">
<t t-call="web.external_layout">
...
</t>
</template>
这里我们调用了external_layout视图,以保证我们的报表跟odoo原生的样式保持一致。
- style="page-break-before: always;" : 将页面分隔,每页一条记录。
3. 报表主体文件结构
通常odoo的报表主体文件可以分为下面几个结构:
- 页面(page)
- 标题(h2)
- 信息栏(info)
- 数据表(table)
- 尾页(footer)
结构代码:
<div class="page">
<div class="oe_structure"/>
<h2 class="mt-4">
<span t-field="doc.name">Documen Title</span>
</h2>
<div class="row mt-4 mb-2" id="informations">
<div t-if="doc.field" class="col-auto col-3 mw-100 mb-2" name="informations_reference">
<strong>Field:</strong><br/>
<span class="m-0" t-field="doc.employee_id">Value</span>
</div>
</div>
<div class="oe_structure"></div>
修改报表
对于我们需要修改的报表,可以在设置中-动作-报表中根据模型找到对应的模板文件。
由上图中的按钮Qweb视图可以找到对应的Qweb代码文件,我们可以通过修改Qweb代码的方式来修改报表。
FAQ
下面是一些在编写报表过程中常见的问题列表:
1. 如何修改报表字体
想要修改PDF的报表字体,只需要在div的样式表中添加如下的样式:
<div class="font-size: 35px !important;">
</div>
报表的修改通常是个耗费时间精力的事情,读者要是没有耐心,亦可选购笔者提供的报表修改服务。
2. 如何在报表中添加条码
odoo中内置了在报表中添加条码的功能,原理很简单,即使用img标签,将带有条码的URL链接添加到img的url属性中。
@http.route(['/report/barcode', '/report/barcode/<type>/<path:value>'], type='http', auth="public")
def report_barcode(self, type, value, width=600, height=100, humanreadable=0, quiet=1):
pass
从源代码层面上分析可以得出,条码的引用接受6个参数:
- type: 可选的参数有 'Codabar', 'Code11', 'Code128', 'EAN13', 'EAN8', 'Extended39',
'Extended93', 'FIM', 'I2of5', 'MSI', 'POSTNET', 'QR', 'Standard39', 'Standard93', 'UPCA', 'USPS_4State'
- value: 生成的条码内容
- width: 条码宽度
- height: 条码高度
- humanreadable: 0 或 1,是否在条码中添加可读性文本
- quiet: 0 或 1,是否添加页面留白
例如:
<td>
<img t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s&humanreadable=1' % ('Code128', object.quantity, 600, 50)" style="width:100%;height:4rem" alt="Barcode"/>
</td>
3. 报表中的需要转义特殊字符
xml中不能出现特殊字符,像&、>,< 等符号需要转义:
字符 | 转移字符 |
---|---|
& | \& amp; |
< | \& lt; |
> | \& gt; |
" | \& quot; |
' | \& apos; |
&和amp;中间没有空格
4. 报表中日期字段的格式化
如果想要把模型中的datetime类型的字段格式化成date类型,那么可以使用t-options选项。
例子:
<span t-field="o.date_invoice" t-options='{"format": "MM/dd/yyyy"}'/>
5. 报表样式文件
我们可以自己定义报表的样式,但是不是像普通的后台样式文件一样的继承方式,而是需要继承自web.report_assets_common。
6. 在页面中添加页码
我们可以在报表中给每页添加一个页码,具体样式代码如下:
<div class="footer">
<div class="text-center" style="border-top: 1px solid black;">
<ul class="list-inline">
<li>Page: <span class="page"/>/<span class="topage"/></li>
</ul>
</div>
</div>
*: 此处表述不够准确,odoo实际上支持自定义docs的内容,但具体方法相对隐晦,简单起见这里不进行过多介绍。