zoukankan      html  css  js  c++  java
  • Odoo 12开发之报表和服务端 QWeb

    Odoo 12开发之报表和服务端 QWeb

    前言

    Odoo内置的QWeb引擎是报表的默认引擎.
    使用 QWeb 模板设计的报表可生成 HTML 文件并被转化成 PDF
    

    一·安装wkhtmltopdf模块

    odoo 利用 whktmltopdf 将渲染的HTML页面转换成PDF文档
    
    # 版本依赖参考 https://github.com/wkhtmltopdf/wkhtmltopdf/releases
    
    # 安装步骤:
    	# 1.检查安装版本
        	wkhtmltopdf --version
        # 2.卸载不符合的版本
        	sudo apt-get remove --purge wkhtmltopdf
        # 3.下载wkhtmltopdf    
    		wget "https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.bionic_amd64.deb" -O /tmp/wkhtml.deb
        # 4. 安装
        	sudo dpkg -i /tmp/wkhtml.deb
        # 5. 解决缺少依赖
        	sudo apt-get -f install
        # 6. 再次检查版本信息
        	$ wkhtmltopdf --version
    		wkhtmltopdf 0.12.5 (with patched qt)
    

    二·创建业务报表

    报表模样:

    Odoo 12开发之报表和服务端 QWeb

    ### 模块中报表代码
    # 1. 在当前模块的根目录下创建reports文件夹,
    #  2. 在reports文件夹下创建library_book_report.xml数据文件
        <?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>	
    # 3. 将library_book_report.xml 数据文件加载到 __manifest__.py文件的data下
    
    # 4. 查看当前报表 Settings > Technical > Actions >Reports
    ### 注意:
    	report 标签表示是一个报表
    

    三·QWeb 报表模板

    ### 报表遵循一个基本框架
    <template id="report_library_book_template">
        <t t-call="web.html_container">
            <t t-call="web.external_layout">
                <div class="page">
                    <!-- Report header content -->
                    <t t-foreach="docs" t-as="o">
                        <!-- Report row content -->
                    </t>
                    <!-- Report footer content -->
                </div>
            </t>
        </t>
    </template>
    
    # 1. 最重要的元素是 t-call 标准报表结构
    # 2. web.html_container模板进行支持HTML文档的基本设置
    # 3. web.external_layout模板使用相应公司的相关设置处理报表头部和底部
    

    四·在报表中展示数据

    # 报表中QWeb模板在服务端进行渲染. 使用Python QWeb来实现.
    # 注意区别
        # QWeb表达式是有python语法运行,不是JavaScript. 
        # 对于简单的表达式没有区别,对于复杂的预算则可能存在差别.
        ### 表达式的上下文不同,其中报表可使用的变量:
        	# docs  打印记录的可迭代集合
        	# doc_ids 打进记录的ID列表
        	# doc_model 指定记录的模型.
        	# time 是对python时间库的引用
        	# user 是运行报表的用户记录
        	# res_company 是当前用户的公司记录
            
    ### odoo报表采用bootstrap样式       
    
    #### 添加表格表头
    <!-- Report header content -->
    <div class="container">
        <!-- 表头 header一栏  -->
        <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">
                <!-- Report row content -->
            </div>
        </t>
        <!-- Report footer content -->
    </div>
    
    ### 循环数据 , 在 t-foreach 标签取出数据
    	# docs指定可迭代的集合 t-as 作为别名
    	# t-options属性添加额外的选项,widget键的json字典. 有时候需要渲染出地址,默认widget为contact,类似与地图图标
    
    <!-- Report row content -->
    <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">
        <!-- Render authors -->
    </div>
    

    五·渲染图片

    # 渲染作者头像图片 t-options的widget为image
    
    <!-- Render authors -->
    <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>
    

    六·报表汇总

    # 报表中需要进行汇总 ,借助python表达式来计算集合元素的数量. 可以使用sum函数,以及推导式
    # 在 <t t-foreach>标签闭合后,添加最后一行用于汇总
    
    # t-esc  执行python表达式   t-set 定义累加变量,  t-value 可以设置值(python表达式和t-set变量进行计算)
    
    <!-- Report footer content -->
    <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>
    

    七·定义纸张样式

    # 自定义纸张的样式 在报表xml数据最上方添加如下代码
    # 查看 Settings > Technical > Reporting > Paper Format菜单
    # 在 report 标签属性种,paperfomat属性可以用来实现编辑报表的操作
    
    <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>
    

    八·在报表中启用语言翻译

    # 在报表种启用翻译时, 需要使用 t-lang属性的 <t t-call>元素在模板中调用翻译方法.
    # t-lang传入语言代码来运行,如es,en_US.
    
    <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 创建报表

    # 写原生 SQL 查询来创建我们所需的数据集,将结果通过特殊的模型进行暴露,然后基于这一数据集来生成报表
    # 目的是:在QWeb模板中不易于处理的数据转换或累加
    
    ###  自定义 报表查询语句,
    # 将 reports 加入到 __init__.py, 和reports的__init__.py
    # 在reports/library_book_report.py
    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)
            """)
            
    
    # 添加安全访问规则 security/ir.model.access.csv
    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">
                        <!-- Report page content -->
                        <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"
              />
    
  • 相关阅读:
    Task10 文本预处理
    Task09 批量归一化
    Task06 Basic of CNN
    Task05 梯度消失和梯度爆炸
    Task 04 过拟合,欠拟合及其解决方案
    机器学习 Task 03 多层感知机
    机器学习 task2 softmax与分类模型
    异步与闭包与fetch
    baidu API
    my own JSON
  • 原文地址:https://www.cnblogs.com/dengz/p/13091450.html
Copyright © 2011-2022 走看看