Odoo 12开发之报表和服务端 QWeb
前言
Odoo内置的QWeb引擎是报表的默认引擎.
使用 QWeb 模板设计的报表可生成 HTML 文件并被转化成 PDF
一·安装wkhtmltopdf模块
odoo 利用 whktmltopdf 将渲染的HTML页面转换成PDF文档
wkhtmltopdf --version
sudo apt-get remove --purge wkhtmltopdf
wget "https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.bionic_amd64.deb" -O /tmp/wkhtml.deb
sudo dpkg -i /tmp/wkhtml.deb
sudo apt-get -f install
$ wkhtmltopdf --version
wkhtmltopdf 0.12.5 (with patched qt)
二·创建业务报表
报表模样:

<?xml version="1.0"?>
<odoo>
<report id="action_library_book_report"
string="Library Books"
model="library.book"
report_type="qweb-pdf"
name="library_app.report_library_book_template" />
</odoo>
report 标签表示是一个报表
三·QWeb 报表模板
### 报表遵循一个基本框架
<template id="report_library_book_template">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<div class="page">
<t t-foreach="docs" t-as="o">
</t>
</div>
</t>
</t>
</template>
四·在报表中展示数据
#### 添加表格表头
<div class="container">
<div class="row bg-primary">
<div class="col-3">Title</div>
<div class="col-2">Publisher</div>
<div class="col-2">Date</div>
<div class="col-3">Publisher Address</div>
<div class="col-2">Authors</div>
</div>
<t t-foreach="docs" t-as="o">
<div class="row">
</div>
</t>
</div>
### 循环数据 , 在 t-foreach 标签取出数据
# docs指定可迭代的集合 t-as 作为别名
# t-options属性添加额外的选项,widget键的json字典. 有时候需要渲染出地址,默认widget为contact,类似与地图图标
<div class="col-3">
<h4><span t-field="o.name" /></h4>
</div>
<div class="col-2">
<span t-field="o.publisher_id" />
</div>
<div class="col-2">
<span t-field="o.date_published"
t-options="{'widget': 'date'}"/>
</div>
<div class="col-3">
<span t-field="o.publisher_id"
t-options='{
"widget": "contact",
"fields": ["address", "email", "phone", "website"],
"no_marker": true}'/>
</div>
<div class="col-2">
</div>
五·渲染图片
<ul class="list-unstyled">
<t t-foreach="o.author_ids" t-as="author">
<li class="media">
<span t-field="author.image_small"
t-options="{'widget': 'image'}" />
<div class="media-body">
<p class="mt-0">
<span t-field="author.name" />
</p>
</div>
</li>
</t>
</ul>
六·报表汇总
<div class="row">
<div class="col-3">
Count: <t t-esc="len(docs)" />
</div>
<div class="col-2" />
<div class="col-2" />
<div class="col-3" />
<div class="col-2" />
</div>
七·定义纸张样式
<record id="paperformat_euro_landscape"
model="report.paperformat">
<field name="name">European A4 Landscape</field>
<field name="default" eval="True" />
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Landscape</field>
<field name="margin_top">40</field>
<field name="margin_bottom">23</field>
<field name="margin_left">7</field>
<field name="margin_right">7</field>
<field name="header_line" eval="False" />
<field name="header_spacing">35</field>
<field name="dpi">90</field>
</record>
八·在报表中启用语言翻译
<report id="action_library_book_report"
...
name="library_app.report_library_book_translated"
paperformat="paperformat_euro_landscape" />
<template id="report_library_book_template">
<t t-call="library_app.report_library_book_translated"
t-lang="user.lang" />
</template>
####### 有些情况下,我们可能需要每条记录以指定语言进行渲染。比如在销售订单中,我们可能要各条记录按照对应合作方/客户的首选语言进行打印。假设我们需要每本书按照对应出版商的语言进行渲染,QWeb模板可以这么写
<template id="report_library_book_translated">
<t t-foreach="docs" t-as="o">
<t t-call="library_app.report_library_book_template"
t-lang="o.publisher_id.lang">
<t t-set="docs" t-value="o" />
</t>
</t>
</template>
九·使用自定义 SQL 创建报表
from odoo import models, fields
class BookReport(models.Model):
_name = 'library.book.report'
_description = 'Book Report'
_auto = False
name = fields.Char('Title')
publisher_id = fields.Many2one('res.partner')
date_published = fields.Date()
def init(self):
self.env.cr.execute("""
CREATE OR REPLACE VIEW library_book_report AS
(SELECT *
FROM library_book
WHERE active=True)
""")
access_library_book_report,access_library_book_report,model_library_book_report,
library_group_user,1,0,0,0
# 在 reports/library_book_sql_report.xml 新增一个报表
<?xml version="1.0"?>
<odoo>
<report id="action_library_book_sql_report"
string="Library Book SQL Report"
model="library.book.report"
report_type="qweb-html"
name="library_app.report_library_book_sql" />
<template id="report_library_book_sql">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<div class="page">
<table class="table table-striped">
<tr>
<th>Title</th>
<th>Published</th>
<th>Date</th>
</tr>
<t t-foreach="docs" t-as="o">
<tr>
<td class="col-xs-6">
<span t-field="o.name" />
</td>
<td class="col-xs-3">
<span t-field="o.publisher_id" />
</td>
<td class="col-xs-3">
<span t-field="o.date_published"
t-options="{'widget': 'date'}" />
</td>
</tr>
</t>
</table>
</div>
</t>
</t>
</template>
</odoo>
# 在views/library_menu.xml中添加如下内容
<act_window id="action_library_book_report"
name="Book Report"
res_model="library.book.report"
view_mode="tree,form"
/>
<menuitem id="menu_library_book_report"
name="Book Report"
parent="menu_library"
action="action_library_book_report"
/>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
2019-06-11 Python基础知识(六)------小数据池,集合set,深浅拷贝
2019-06-11 Python基础知识(五)------字典 , 解包 , 枚举 ,嵌套
2019-06-11 Python基础知识(四) 列表 , 字典 , 元组. 切片