OpenOffice.org 报表
文件流
OpenOffice.org是OpenERP中最常用的报表格式。OpenOffice.org Writer被用来生成RML模板,而RML模板用来生成pdf报表。
内部过程
.SXW 模板文件
- 我们用OpenOffice1.0的.sxw文件作为模板。模板中包含用中括号括起来的表达式或OpenOffice字段(field),用来提供给OpenERP server填充数据。但这只是作为帮助开发者更直观地生成.RML文件的一种方法。OpenERP并不需要SXW文件产生报表。
.RML 模板
- 可以使用Open SXW2RML从SXW文件生成RML文件。RML文件是一种表现PDF文档的XML格式,可以转换为PDF文件。RML是一种更容易的方法,至少XML语法比PDF语法更加通俗易懂。
报表引擎
- 报表引擎(report engine)从数据库中读出数据,插入在RML文件的表达式中。
在.RML文件中,将以发票上客户的城市名称替换掉相应表达式。报表引擎以真实数据替换所有表达式之后,生成相同的.RML文件。
生成最终文档
- 最后RML文件会根据OpenReport代码的需要,转换成PDF或者HTML文件。
生成 SXW 文件
你可以使用 OpenOffice 设计报表。举个例子,如: server/bin/addons/sale/report/order.sxw.
OpenOffice 报表中的动态内容
动态内容
SXW/RML报表中,你可以在中括号中加入Python代码,以获得OpenERP中的对象(object)。代码可以使用如下变量
可用的变量
可以用的 Python 对象/变量:
objects : 将要打印的object记录(例如发票(invoice)对象).
data : 向导(wizard)中获得的数据
time : Python的time模块(详见Python文档).
user : 运行这个报表的用户.
可用的函数
可以用的 Python 函数:
setLang(‘fr’) : 设置语言用于自动取得字段翻译.
repeatIn(list, varname[, tagname]) : 重复 模板(template)当前部分list中的对象 (整个文档, 当前段落, 表格中的当前行) 可以使用模板(template)的 varname标签 。 从 4.1.X版开始, 你可以使用第三个参数(可选的)选择你想在.RML标记(RML tag)中重复的内容
setTag(‘para’,’xpre’) : 在rml文档中(由sxw转换),用其它标记(0tag) (xpre 是一个预处理格式的段落,preformatted paragraph),替换封闭的 RML 标签 (一般是 ‘para’)(?)
removeParentNode(‘tr’) : 移除类型’tr’的父结点, 这个参数经常在条件语句中使用 (如下例)
有用的标签举例:
[[ repeatIn(objects,’o’) ]] : Loop on each objects selected for the print
[[ repeatIn(o.invoice_line,’l’) ]] : 循环每行数据.
[[ repeatIn(o.invoice_line,’l’, ‘td’) ]] : 循环每行,并为每行数据创建一个单元格
[[ (o.prop==’draft’)and ‘YES’ or ‘NO’ ]] : 根据标记(tag)‘prop’打印 YES或 NO
[[ round(o.quantity * o.price * 0.9, 2) ]] : 可以进行计算.
[[ ‘%07d’ % int(o.number) ]] : 数字的格式化输出
[[ reduce(lambda x, obj: x+obj.qty , list , 0 ) ]] : 列表中所有 qty 的和 (尝试列表中的每个 “object” )
[[ user.name ]] : 用户名
[[ setLang(o.partner_id.lang) ]] : 本地化输出(和翻译有关)
[[ time.strftime(‘%d/%m/%Y’) ]] : 以dd/MM/YYYY格式输出时间, 查阅python文档获得关于“%d”的帮助, …
[[ time.strftime(time.ctime()[0:10]) ]] 或 [[ time.strftime(time.ctime()[-4:]) ]] : 只输出日期.
[[ time.ctime() ]] : 输出当前日期 & 时间
[[ time.ctime().split()[3] ]] : 只输出时间
[[ o.type in [‘in_invoice’, ‘out_invoice’] and ‘Invoice’ or removeParentNode(‘tr’) ]] : 如果type是 ‘in_invoice’ 或‘out_invoice’ 那么输出 ‘Invoice’;如果 不是,‘tr’类型的节点会被删除.
一个有趣的标记(tag):如果想输出当前条目(entry)的创建者(create_uid)或者最后一位修改者(write_uid)你需要在你的报表类(class)中加入如下:
如果你的报表会类似输出相应的名字:
有时你希望打印遇到的特定情况。 你可以根据python的逻辑操作符"not","and","or"构造自己的判断语句。 Python中的每个对象都有自己的逻辑值(TRUE或FALSE):
注意and要比or的优先级高,表达式等价为:
如果 o.prop是 ‘draft’, 那么计算结果为:
o.prop == ‘draft’ 为 True.
True and ‘YES’ 为 ‘YES’. 因为左项为 “true” 值,和右项 and 计算后为真.
‘YES’ or ‘NO’ is ‘YES’. 左项为真, or操作会忽略右项。只计算左项值.
如果 o.prop 是‘confirm’之类其他的操作, 那么计算如下:
o.prop == ‘draft’ 为 False.
False and ‘YES’ is False. 因为左项为 “false” 值, and 操作截断并忽略右项. 只计算左项.
False or ‘NO’ is ‘NO’. 因为左项为 “false” 值, or 计算右项.
可以使用更复杂的的结构. 可以参照python 手册章节 Python’s boolean operators .
python 函数 “filter” 可以… filter: 尝试如下:
repeatIn(filter( lambda l: l.product_id.type==’service’ ,o.invoice_line), ‘line’)
只输出每段中product 含有 type=’service’的行.
报表中显示二进制字段图像 (待查)
[[ setTag(‘para’,’image’,{‘width’:’100.0’,’height’:’80.0’}) ]] o.image or setTag(‘image’,’para’)
SXW2RML
Open Report 手册
关于
The OpenERP 的报表引擎.
Open Report 是一个模块,可让您从OpenOffice的模板文件(sxw)和任何关系数据库中渲染出高质量报表。 它可以用来作为OpenERP模块或作为独立的程序.
SXW 转 RML 代码的安装,适用于Windows用户
为了使用python代码‘tiny_sxw2rml.py’,你需要安装如下包:
Python (http://www.python.org)
ReportLab (http://www.reportlab.org)/(Installation/(Installation))
Libxml for Python (http://users.skynet.be/sbi/libxml-python)
SXW 转 RML 代码的安装,适用于linux(开源)用户
tiny_sxw2rml.py 可以在OpenERP 模块 base_report_designer 中找到:
server/bin/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py
确认 normalized_oo2rml.xsl 和 tiny_sxw2rml 在一起,否则你会遇到如下错误:
- failed to load external entity normalized_oo2rml.xsl
使用 tiny_sxw2rml
当你做好必要的准备,打算编辑您自己的报表模板(template)时,使用如下命令:
tiny_sxw2rml.py template.sxw > template.rml
注释: tiny_sxw2rml.py 帮助 建议你使用”-o OUTPUT”指定输出文件,但貌似0.9.3版本不支持
OpenERP Server PDF 输出
Server PDF 输出
关于
To generate the pdf from the rml file, OpenERP needs a rml parser.
解释器
语法解释器可以在模块中添加。例如如下代码:
import time
from report import report_sxw
class order(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(order, self).__init__(cr, uid, name, context)
self.localcontext.update({
'time': time,
})
report_sxw.report_sxw('report.sale.order', 'sale.order',
'addons/sale/report/order.rml', parser=order, header=True)
解释器继承自 report_sxw.rml_parse 对象 并且增加了localcontext变量和函数 time, 因此在报表中可以调用.
report_sxw.report_sxw 实例生成之后,需要如下参数:
报表的名字
report关联的object名字
rml文件的路径
默认的rml解释器(默认为rml_parse)
a boolean to add or not the company header on the report (default True)
xml 定义
To be visible from the client, the report must be declared in an xml file (generally: “module_name”_report.xml) that must be put in the __terp__.py file
下面是销售订单报表的例子:
<?xml version="1.0"?>
<openerp>
<data>
<report
id="report_sale_order"
string="Print Order"
model="sale.order"
name="sale.order"
rml="sale/report/order.rml"
auto="False"/>
header="False"/>
</data>
</openerp>
参数如下:
id: OpenERP中的报表id,类似openerp中的其他xml标记(tag)
string: Client 端按钮显示的文字
model: 报表中用到的object
name: 除了第一个 “report 之后显示的名字”
rml: rml 文件路径
auto: boolean值指定server是/否生成默认的解释器
header: 是否允许页眉(report header)。 如果需要编辑, 遵循如下方式: Administration -> Users -> Company’s structure -> Companies. 选择并编辑您的公司: 其中 “Header/Footer” 标签 允许你编辑相应的 header/footer.