odoo集成康虎云报表

2019-07-10  本文已影响0人  grey_27

康虎云报表解决了浏览器不能直接调用打印机打印报表的痛点,但是个人感觉康虎软件工作室给出的文档不算特别详细,其中开发遇到各种问题,还是需要去官方QQ群讨教,十分感谢石头哥给我的指导及免费开放的如此优秀的软件.本文记录一下自己在odoo中集成康虎云报表的过程.

项目目录

- addons
  - cfprint   # 康虎云报表官方模块
    ...
  - my_cfprint   # 个人集成模块
    - data
      - template_data.xml  # 模板数据,直接写入省去安装模块后再上传模板
    - models
      - __init__.py
      - cf_template.py  # 继承康虎云模板模型增加字段
    - views
      - cf_template_view.xml  # 继承康虎云模板模型增加字段
    - report
      - button.xml  # 按钮视图
      - sell_delivery_report.xml  # 继承report模板改为康虎云报表
    - __init__.py
    - __manifest__.py
<?xml version="1.0"?>
<openerp>
    <data>
        <!--销售发货单打印按钮-->
        <report
            id="report_sale_order"
            string="直接打印"
            model="sell.delivery"
            report_type="qweb-html"
            <!--指定调用的report.xml文件-->
            file="my_cfprint.sell_delivery_report"  
            name="my_cfprint.sell_delivery_report"
        />

    </data>
</openerp>

这样就可以在对应模型的视图上选择打印菜单即可出现按钮
form视图在中间



tree勾选记录后打印


image.png
<?xml version="1.0"?>
<odoo>
    <data>

        <!-- id要与上面申明的一致-->
        <template id="sell_delivery_report">
             <!--这个可以看作html的根节点,所有页面内容都需要放在这里面-->
            <t t-call="report.html_container">
                
                <!-- 在页面上显示一个提示 -->
                <h3 style="width:100%; padding-top: 50px;">
                    <!--docs便是所有记录,使用判断语句进行输出-->
                    <t t-if="len(docs) &gt;= 0">正在打印,请稍候...</t>
                    <t t-if="len(docs) &lt; 1">没有可打印的记录!</t>
                </h3>
            </t>
            <script type="text/javascript">
            <!--JS代码...-->
            </script>
        </template>

    </data>
</odoo>

使用QWEB渲染引擎自己定义一个模板,因为我们只需要通过这个报表界面运行康虎的JS代码,将数据传给伺服机从而进行打印,所以报表可以随便简单点设计,重要的是里面的js代码

 /* 打印伺服机的ip地址 */
var cfprint_addr = "127.0.0.1";
 /* 打印完成后关闭窗口的延时时长(毫秒), -1则表示不关闭 */
var _delay_close = 1000;    
/* 接下来要生成json了,json结构的外框架如下 */
var _data = {
"template": "base64:<t t-esc="cf_template(user.env, 'report_sell_delivery')" />",
 "Copies": 3, /*打印份数,支持指定打印份数。*/
 "Duplex": 1, /*可选。是否双面打印,0:默认,不双面,1:垂直,2:水平,3:单面打印(simplex)。*/
 "Tables":[]
                  }

这是康虎云JS里定义的两个变量名,所以名字不可以更改,其中_data里的template是设置报表模板,有多种设置方式,这种将模板上传到模型数据库种再调用个人感觉是最方便的,这样不用要求伺服机本地要有模板文件,而是通过odoo将模板数据一同传输.这里的'report_sell_delivery'只要设置为你自己的模板ID就可以了

image.png

最后参数里的"Tables"就是我们要填入的数据,数据为json格式

var _tableCompany = {
    "Name": "Company",
    "Cols":[
        { "type": "str", "size": 4, "name": "id", "required": false },
        { "type": "str", "size": 255, "name": "text", "required": false },
        { "type": "str", "size": 20, "name": "currdate", "required": false },
    ],
    "Data":[
        {
            "id": "<t t-esc="res_company.id" />",
            "text": "<t t-esc="res_company.name"/><t t-esc="res_company.rml_header1"/><t t-esc="res_company.phone"/> ",
            "currdate": "<t t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>",
        }
    ]
}

name 为表名,cols为字段定义,data为每条数据明细

<t t-foreach="docs" t-as="doc">
        var data = {
                    "delivery_id": "<t t-esc="doc.id"/>",
                    "name": "<t t-esc="doc.name"/>",
        }
          <!--循环生成记录然后存入data中-->
        _tableCompany.Data.push(data)
</t>

最后将数据集放入_data的Tables中

_data["Tables"].push(_tableCompany);
/*  可以放入多个表的JSON格式 */ 
_data["Tables"].push(XXXXXX);

/* 最后把json结构转成字符串 */
var _reportData = JSON.stringify(_data);
/* 在浏览器控制台上打印一下json,以便于排错 */
console.log(_reportData);

cfprint.log("连接已断开,正在重新连接。");
        // 在这增加连接失败提示
        alert("未连接到打印服务器,请检查打印机并打开康虎云打印");
        if(_delay_close>0)
                    //改为延时后退回打印前界面
                    setTimeout(function(){window.history.back(-1);}, _delay_close); 

另一个方面,康虎云打印要在js中指定伺服器打印地址(因为知道地址后js才能和伺服机进行通信),如果打印机都在本机那就好说了可以写死为127.0.0.1,而在常规使用中一般是一个局域网内一台电脑连接打印机,而其他机器都是远程打印的,所以我在模型中添加了一个ip字段,用于存储连接了打印机电脑的ip地址.

class OdooModel(models.Model):
    _inherit = "cf.template"

    ip = fields.Char(u"伺服机ip地址", default="127.0.0.1")

之后我们在js配置中将cfprint_addr改为i从模型中取值,这样就避免了多次改动代码,可以通过模板中的ip地址手动选择伺服机的ip地址

 var cfprint_addr = "<t t-esc="user.env['cf.template'].search([('templ_id', '=', 'report_sell_delivery')], limit=1).ip" />";
image.png
上一篇 下一篇

猜你喜欢

热点阅读