This is the documentation for older versions of Odoo (formerly OpenERP).

See the new Odoo user documentation.

See the new Odoo technical documentation.

XSL:RML 报表

RML 报表不需要编程,但是需要两种简单的 XML 文件:

  • 一种文件描述导出数据 (*.xml)

  • 一种可以包含数据和表现规则的文件 (*.xsl)

/doc_static/6.0/_images/automatic-reports.png

XML模板(template)主要描述哪些域(field)的资源需要(由server)导出. XSL:RML 样式表单(style sheet)处理输出数据,就像报表(report)中的 "static text" 一样. "static text" 是指在报表中相同、不怎么变化的部分,比如表格头部的标题(title of table column).

范例

下面给出一个例子,说明生成ERP报表的不同文件.

/doc_static/6.0/_images/ids-report.png

XML 模板

<?xml version="1.0"?>

    <ids>
    <id type="fields" name="id">

        <name type="field" name="name"/>
        <ref type="field" name="ref"/>

    </id>
    </ids>

XML 数据文件 (生成的)

<?xml version="1.0"?>

    <ids>
    <id>

        <name>Tiny sprl</name>
        <ref>pnk00</ref>

    </id><id>

        <name>ASUS</name>
        <ref></ref>

    </id><id>

        <name>Agrolait</name>
        <ref></ref>

    </id><id>

        <name>Banque Plein-Aux-As</name>
        <ref></ref>

    </id><id>

        <name>China Export</name>
        <ref></ref>

    </id><id>

        <name>Ditrib PC</name>
        <ref></ref>

    </id><id>

        <name>Ecole de Commerce de Liege</name>
        <ref></ref>

    </id><id>

        <name>Elec Import</name>
        <ref></ref>

    </id><id>

        <name>Maxtor</name>
        <ref></ref>

    </id><id>

        <name>Mediapole SPRL</name>
        <ref></ref>

    </id><id>

        <name>Opensides sprl</name>
        <ref>os</ref>

    </id><id>

        <name>Tecsas sarl</name>
        <ref></ref>

    </id>
    </ids>

XSL 样式表

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:template match="/">

        <xsl:apply-templates select="ids"/>

    </xsl:template>

    <xsl:template match="ids">

        <document>

            <template pageSize="21cm,29.7cm">

                <pageTemplate>

                    <frame id="col1" x1="2cm" y1="2.4cm" width="8cm" height="26cm"/>
                    <frame id="col2" x1="11cm" y1="2.4cm" width="8cm" height="26cm"/>

                </pageTemplate>

            </template>

        <stylesheet>

            <blockTableStyle id="ids">

                <blockFont name="Helvetica-BoldOblique" size="12" start="0,0" stop="-1,0"/>
                <lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,0"/>

                <lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,-1"/>

            </blockTableStyle>

        </stylesheet>

        <story>

            <blockTable colWidths="2cm, 6cm" repeatRows="1" style="ids">

                <tr>

                    <td t="1">Ref.</td>
                    <td t="1">Name</td>

                </tr>
                <xsl:apply-templates select="id"/>

            </blockTable>

        </story>
        </document>

    </xsl:template>

    <xsl:template match="id">

        <tr>

            <td><xsl:value-of select="ref"/></td>
            <td><para><xsl:value-of select="name"/></para></td>

        </tr>

    </xsl:template>
    </xsl:stylesheet>

对应的RML文件 (生成的)

<?xml version="1.0"?>

    <document>
    ...

        <story>

            <blockTable colWidths="2cm, 6cm" repeatRows="1" style="ids">

                <tr>

                    <td t="1">Ref.</td>
                    <td t="1">Name</td>

                </tr>
                <tr>

                    <td>pnk00</td>
                    <td><para>Tiny sprl</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>ASUS</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Agrolait</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Banque Plein-Aux-As</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>China Export</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Ditrib PC</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Ecole de Commerce de Liege</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Elec Import</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Maxtor</para></td>

                </tr>
                <tr>

                    <td></td>
                    <td><para>Mediapole SPRL</para></td>

                </tr>
                <tr>

                    <td>os</td>
                    <td><para>Opensides sprl</para></td>

                </tr>
                <tr>
                <td></td>

                    <td><para>Tecsas sarl</para></td>

                </tr>

            </blockTable>

        </story>

    </document>

更多所用格式的帮助:

这些格式都是作为 XML specification. 的拓展。

XML 模板

XML 模板(template)是简单XML文件,用来描述报表所有可用的object字段(field)中哪些字段(object fields)是有用的(available).

文件格式

标签(tag)名称可以任意(但在XML中必须是有效的)。XSL文件中,你要使用到这些名称。大多数情况下,标签名(the name of tag)和引用的对象字段(object field)是一致的.

Nodes without type attribute are transferred identically into the XML destination file (the data file). Nodes with a type attribute will be parsed by the server and their content will be replaced by data coming from objects. In addition to the type attribute, nodes have other possible attributes. These attributes depend on the type of the node (each node type supports or needs different attributes). Most node types have a name attribute, which refers to the name of a field of the object on which we work.

关于object中的 "browse" 方法,报表的字段名称是可以使用一种类似面向对象语言中的notation来表示。这意为着 "(关联字段)是可以用这种类似 "bridges" (桥)的方式获得相关对象数据.

让我们试用 "account.transfer" 对象来举例。Account.transfer对象包含一个partner_id字段,这个字段是一 个指向"res.partner" 对象的 ("many to one")(多对一)的关系。我们假设要创建一个转账(transfers)的报表,,而报表中需要从partner中选择收款人。我们可以这样写以获得收 款人的名字字段:

partner_id.name

其它类型

这里是可用的字段类型的列表:

  • field: 最简单的类型。有这种类型的结点(node),server都会用已知字段(field)的名字属性替换掉node的内容.

  • fields: 这种结点(node)类型,server会在XML数据文件中生成一个和已知名字属性唯一相同的结点(?).

注释:

** 这个结点(node)类型经常使用 "id" 作为名字属性。user使用选择resource的接口创建结点(node)时,会受到影响. ** 结点(node)的语法 <node type="fields" name="field_name"> 和SQL语句 "SELECT FROM object_table WHERE id in identifier_list GROUP BY field_name" 相似,其中identifier_list 是::user (in the interface)可以通过接口选择使用的resource .

  • eval: 这个结点(node)类型计算 expr 属性中表达式(expression)的值。表达式(expression)可以是python表达式,也可以是object的字段名字.

  • zoom: 这个结点(node)类型允许 "enter" 通过relation字段使用name属性中列出的资源. 意味着子结点(child node)不用其他对象名字字段做前缀也可以使用资源字段(fields of that source)。在上面的例子中,我们可以通过以下方式获得parter的name字段:

<partner type="zoom" name="partner_id">

        <name type="field" name="name"/>

</partner>

In this precise case, there is of course no point in using this notation instead of the standard notation below:

<name type="field" name="partner_id.name"/>

zoom 类型往往用于恢复同一个object的多个字段(field).

  • function: 返回name属性中所调用函数的结果。这个函数必须是提前定义的。暂时可用的函数是today,用来返回现在日期.

  • call: calls对象name属性是方法名称,args属性是参数名称。函数的结果放进一个字典(dictionary),形如:{'name_of_variable': value, ... } 这个结果可以被子结点使用。使用call类型的结点必须有相应的value属性,以和调用方法所返回的字典键(key)匹配.

样例:

<cost type="call" name="compute_seller_costs" args="">

    <name value="name"/>
    <amount value="amount"/>

</cost>

TODO: documenter format methode appellée def compute_buyer_costs(self, cr, uid, ids, *args):

  • attachment: 提取属性name中对应id的资源,作为报表的图像(image).

范例:

<image type="attachment" name="id"/>

范例

XML 文件的例子:

<?xml version="1.0" encoding="ISO-8859-1"?>
<transfer-list>

    <transfer type="fields" name="id">

        <name type="field" name="name"/>
        <partner_id type="field" name="partner_id.name"/>
        <date type="field" name="date"/>
        <type type="field" name="type"/>
        <reference type="field" name="reference"/>
        <amount type="field" name="amount"/>
        <change type="field" name="change"/>

    </transfer>

</transfer-list>

RML 介绍

有关RML格式的更多信息, 请参照官方文档.

XSL:RML 样式表

生成报表的XSL样式表有两个可选项. 两者都可以我们自己定制, 或者,使用我们自己定制的模板(template)

可以是freestyle,也可以用 corporate_defaults + rml_template

引入 rml_template.xsl

需要的模板:

  • frames?

  • stylesheet

  • story

可选的模板:

Translations

OpenERP可以使用多种语言,因此报表必须可以翻译成多种语言。但是一个报表中,并不是所有项目都被翻译,比如动态的文本需要翻译转换,而格式 代码(format code)则不需要。一个字段如果包在XML标签(类似 t="1" ),翻译系统就会处理它。server会在报表生成过程中处理所有这样的字段.

Example (with corporate defaults):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:import href="../../custom/corporate_defaults.xsl"/>
    <xsl:import href="../../base/report/rml_template.xsl"/>
    <xsl:variable name="page_format">a4_normal</xsl:variable>
    <xsl:template match="/">

        <xsl:call-template name="rml"/>

    </xsl:template>
    <xsl:template name="stylesheet">

        </xsl:template>

    <xsl:template name="story">

        <xsl:apply-templates select="transfer-list"/>

    </xsl:template>
    <xsl:template match="transfer-list">

        <xsl:apply-templates select="transfer"/>

    </xsl:template>
    <xsl:template match="transfer">

        <setNextTemplate name="other_pages"/>
        <para>

            Document: <xsl:value-of select="name"/>

        </para><para>

            Type: <xsl:value-of select="type"/>

        </para><para>

            Reference: <xsl:value-of select="reference"/>

        </para><para>

            Partner ID: <xsl:value-of select="partner_id"/>

        </para><para>

            Date: <xsl:value-of select="date"/>

        </para><para>

            Amount: <xsl:value-of select="amount"/>

        </para>
        <xsl:if test="number(change)>0">

            <para>

                Change: <xsl:value-of select="change"/>

            </para>

        </xsl:if>
        <setNextTemplate name="first_page"/>
        <pageBreak/>

    </xsl:template>

</xsl:stylesheet>

没有公司表头( corporate header )的示例

示例 (使用默认的公司表头 corporate defaults):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">
     <xsl:import href="../../base/report/rml_template.xsl"/>
     <xsl:variable name="page_format">a4_normal</xsl:variable>

     <xsl:template match="/">
          <xsl:call-template name="rml"/>
     </xsl:template>

     <xsl:template name="stylesheet">
      </xsl:template>

      <xsl:template name="story">
           <xsl:apply-templates select="transfer-list"/>
      </xsl:template>

      <xsl:template match="transfer-list">
           <xsl:apply-templates select="transfer"/>
      </xsl:template>

      <xsl:template match="transfer">
           <setNextTemplate name="other_pages"/>

           <para>
                 Document: <xsl:value-of select="name"/>
           </para><para>
                 Type: <xsl:value-of select="type"/>
           </para><para>
                 Reference: <xsl:value-of select="reference"/>
           </para><para>
                 Partner ID: <xsl:value-of select="partner_id"/>
           </para><para>
                 Date: <xsl:value-of select="date"/>
           </para><para>
                 Amount: <xsl:value-of select="amount"/>
           </para>

           <xsl:if test="number(change)>0">
                <para>
                      Change: <xsl:value-of select="change"/>
                </para>
           </xsl:if>

           <setNextTemplate name="first_page"/>
          <pageBreak/>
     </xsl:template>
</xsl:stylesheet>

每个报表都有自己的公司表头( corporate header )

示例 (使用默认的公司表头 corporate defaults):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" :xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:import href="../../custom/corporate_defaults.xsl"/>
    <xsl:import href="../../base/report/rml_template.xsl"/>
    <xsl:variable name="page_format">a4_normal</xsl:variable>
    .....................
    </xsl:template>

</xsl:stylesheet>

条形码(Bar Codes)

RML 文件中的条形码(Barcodes)

可以在RML 文件中使用<barCode>标签生成条形码(Barcodes)。 支持以下格式:

  • codabar

  • code11

  • code128 (如果没有指定 'code' ,则默认code128码)

  • standard39

  • standard93

  • i2of5

  • extended39

  • extended93

  • msi

  • fim

  • postnet

  • ean13

  • ean8

  • usps_4state

你可以更改以下属性来生成自己的条形码(barcode):

  • 'code': 'char'

  • 'ratio':'float'

  • 'xdim':'unit'

  • 'height':'unit'

  • 'checksum':'bool'

  • 'quiet':'bool'

示例:

<barcode code="code128" xdim="28cm" ratio="2.2">`SN12345678</barcode>

如何生成一个新的报表

在 4.0.X

Administration -> Custom -> Low Level -> Base->Actions -> ir.actions.report.xml

常用标签

包含在 [[ ]] 标签中的代码是 python 代码

代码中的内容(你可以使用的变量值)和链接 OpenOffice 报表中的动态内容 描述中的相同.

Unicode 报表

OpenERP 5.0-rc3 中还是不能使用Unicode 报表的。症结在于OpenERP使用的PDF标准字体(14号字体,不嵌入文档,而是由pdf reader提供)Type1只含有Latin1字符.

解决办法有三步

  • 提供 TrueType 字体,让ReportLab可以使用他们.

  • 在报表中使用Unicode之前,在ReportLab中注册TrueType 字体.

  • 在xsl和rml模板中替换旧字体名称为TrueType.

论坛中有更详细的信息

免费的字体 TrueType fonts

that can be used for this purpose are in the DejaVu family. http://dejavu-fonts.org/wiki/index.php?title=Main_Page They can be installed

  • 在 ReportLab 字体目录,

  • 系统路径和 rl_config.py 中包含这个目录,

  • 在 OpenERP 安装子目录提供一个路径给ReportLab作为注册字体用.

在文件 server/bin/report/render/rml2pdf/__init__.py 中

import reportlab.rl_config
reportlab.rl_config.warnOnMissingFontGlyphs = 0

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import reportlab

enc = 'UTF-8'

#repeat these for all the fonts needed
pdfmetrics.registerFont(TTFont('DejaVuSans', 'DejaVuSans.ttf',enc))
pdfmetrics.registerFont(TTFont('DejaVuSans-Bold', 'DejaVuSans-Bold.ttf',enc))

from reportlab.lib.fonts import addMapping

#repeat these for all the fonts needed
addMapping('DejaVuSans', 0, 0, 'DejaVuSans') #normal
addMapping('DejaVuSans-Bold', 1, 0, 'DejaVuSans') #normal

如果是命令行引用 trml2pdf.py ,则需要做如上修改.

所有需要修改的 xsl 和 rml 文件

需要修改调整的清单:

'Times-Roman',       'DejaVuSerif.ttf'
'Times-BoldItalic',  'DejaVuSerif-BoldItalic.ttf'
'Times-Bold',        'DejaVuSerif-Bold.ttf'
'Times-Italic',      'DejaVuSerif-Italic.ttf'

'Helvetica',     'DejaVuSans.ttf'
'Helvetica-BoldItalic',  'DejaVuSans-BoldOblique.ttf'
'Helvetica-Bold',    'DejaVuSans-Bold.ttf'
'Helvetica-Italic',  'DejaVuSans-Oblique.ttf'

'Courier',           'DejaVuSansMono.ttf'
'Courier-Bold',      'DejaVuSansMono-Bold.ttf'
'Courier-BoldItalic','DejaVuSansMono-BoldOblique.ttf'
'Courier-Italic',    'DejaVuSansMono-Oblique.ttf'

'Helvetica-ExtraLight',  'DejaVuSans-ExtraLight.ttf'

'TimesCondensed-Roman',      'DejaVuSerifCondensed.ttf'
'TimesCondensed-BoldItalic', 'DejaVuSerifCondensed-BoldItalic.ttf'
'TimesCondensed-Bold',       'DejaVuSerifCondensed-Bold.ttf'
'TimesCondensed-Italic',     'DejaVuSerifCondensed-Italic.ttf'

'HelveticaCondensed',        'DejaVuSansCondensed.ttf'
'HelveticaCondensed-BoldItalic', 'DejaVuSansCondensed-BoldOblique.ttf'
'HelveticaCondensed-Bold',   'DejaVuSansCondensed-Bold.ttf'
'HelveticaCondensed-Italic', 'DejaVuSansCondensed-Oblique.ttf