----------------------------
step 1、把报表类型由原来的qweb-pdf改成qweb-html:
<?xml version="1.0" encoding="utf-8"?> <odoo> <data> <report id="action_report_saleorder_cfreport" string="Quotation / Order [CFReport]" model="sale.order" report_type="qweb-html" file="cfreport_demo.report_saleorder" name="cfreport_demo.report_saleorder" print_report_name="(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name)" /> </data> </odoo> 注意: 以上报表定义中,除了report_type必须定义为“qweb-html”之外,其他与QWeb报表的定义方式完全相同。 对于Odoo原有报表,也可以通过修改report_type并对模板做少量修改,把QWeb报表改造成康虎云报表
step 2、设计报表模板:
注意:下面的示例代码中已经做了详细注解,请仔细阅读注解。
<?xml version="1.0" encoding="utf-8"?> <odoo> <data> <!-- 订单/询价单 开始 --> <template id="report_saleorder"> <t t-call="<span style="color: red;"> cfprint.html_container </span>"> <!-- 这里调用 cfprint.html_container ,以便于引入康虎云报表JavaScript基础库--> <t t-if="len(docs)>0"></t> <div t-if="len(docs) < 0"><h2 style="text-align: center;">没有可打印的数据,请返回。</h2></div> <div t-if="len(docs) >= 0"><h2 style="text-align: center;">正在打印,请稍候...</h2></div> <!--必须先安装cfprint模块,以引入基础类库--> <script type="text/javascript"> var cfprint_addr = "127.0.0.1"; //打印服务器监听地址 var _delay_close = -1; //打印完成后关闭窗口的延时时长(毫秒), -1则表示不关闭 /******************************* 康虎云报表与ODOO集成时,模板调用方法 **********************************/ /*下面是三种模板处理方法,请任选一种*/ /*方法1: 从数据库中获取打印模板(调用简短方法):*/ //var _data = {"template": "base64:<t t-esc="get_cf_template(user.env, '12345')" />", "ver": 4, "Copies": 1, "Duplex": 0, "Tables":[]}; /*方法2: 从数据库中获取打印模板(直接查询法):*/ //var _data = {"template": "base64: < t t-esc="user.env['cf.template'].search([('templ_id', '=', '12345')], limit=1).template" />", "ver": 4, "Copies": 1, "Duplex": 0, "Tables":[]}; /*方法3:打印模板在客户端*/ var _data = {"template": "report_saleorder.fr3", "ver": 4, "Copies": 1, "Duplex": 0, "Tables":[]}; /*******************************************************************************************************/ /* Odoo中的LOGO是以Base64保存的,所以只需要把Base64中的换行去掉,然后赋值给字段即可。 为了减少数据传输量,把LOGO单独放一张表,而不是放在循环中与主表记录一起生成多次。 */ <t t-set="company_logo" t-value="res_company.logo.replace('\n','').encode('utf-8')"/> //生成公司信息 var _tableLogo = { "Name": "Logo", "Cols":[ { "type": "str", "size": 4, "name": "id", "required": false }, { "type": "blob", "size": 0, "name": "logo", "required": false }, { "type": "str", "size": 50, "name": "user_name1", "required": false }, { "type": "str", "size": 50, "name": "user_name2", "required": false }, { "type": "str", "size": 20, "name": "currdate", "required": false }, ], "Data":[ { "id": "1", "logo": "base64/png:<t t-esc="res_company.logo.replace('\n','').encode('utf-8')"/>", "user_name1": "<t t-esc="user.name" />", "user_name2": "<t t-esc="request.env.user.name" />", "currdate": "<t t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>:<t t-esc="datetime.datetime.now().strftime('%Y-%m-%d %H:%M')"/> ", /*<t t-usertime="%Y-%m-%d %H:%M:%S" />*/ } ] } //生成表结构 var _tableOrder = { "Name": "Order", "Cols":[ { "type": "str", "size": 4, "name": "logo_id", "required": false }, { "type": "str", "size": 30, "name": "id", "required": false }, { "type": "str", "size": 255, "name": "inv_address", "required": false }, { "type": "str", "size": 255, "name": "inv_name", "required": false }, { "type": "str", "size": 30, "name": "inv_phone", "required": false }, { "type": "str", "size": 30, "name": "inv_fax", "required": false }, { "type": "str", "size": 255, "name": "partner_address", "required": false }, { "type": "str", "size": 255, "name": "partner_name", "required": false }, { "type": "str", "size": 30, "name": "partner_vat", "required": false }, { "type": "str", "size": 20, "name": "order_name", "required": false }, { "type": "str", "size": 20, "name": "client_order_ref", "required": false }, { "type": "str", "size": 30, "name": "date_order", "required": false }, { "type": "str", "size": 30, "name": "salesperson", "required": false }, { "type": "str", "size": 30, "name": "payment_term_id", "required": false }, { "type": "float", "size": 0, "name": "amount_untaxed", "required": false }, { "type": "float", "size": 0, "name": "amount_total", "required": false }, { "type": "str", "size": 100, "name": "note", "required": false }, { "type": "str", "size": 100, "name": "payment_term_note", "required": false }, { "type": "str", "size": 100, "name": "fiscal_position_note", "required": false }, { "type": "str", "size": 10, "name": "state", "required": false }, /*订单状态,draft 或 sent 表示询价单,其他表示订单*/ ], "Data":[ ] }; var _tableOrderLines = { "Name": "OrderLines", "Cols":[ { "type": "str", "size": 30, "name": "order_id", "required": false }, { "type": "str", "size": 30, "name": "line_name", "required": false }, { "type": "float", "size": 0, "name": "product_uom_qty", "required": false }, { "type": "str", "size": 10, "name": "product_uom", "required": false }, { "type": "float", "size": 0, "name": "price_unit", "required": false }, { "type": "float", "size": 0, "name": "discount", "required": false }, { "type": "str", "size": 50, "name": "tax_description", "required": false }, { "type": "str", "size": 50, "name": "tax_name", "required": false }, { "type": "float", "size": 0, "name": "price_subtotal", "required": false }, { "type": "float", "size": 0, "name": "price_total", "required": false }, { "type": "float", "size": 0, "name": "subtotal", "required": false } ], "Data":[ ] }; /*生成主表数据*/ <t t-foreach="docs" t-as="doc"> <t t-set="doc" t-value="doc.with_context({'lang':doc.partner_id.lang})" /> _tableOrder.Data.push( { "id": "<t t-esc="doc.id"/>", "logo_id": "1", "inv_address": "<span t-field="doc.partner_invoice_id" t-field-options='{"widget": "contact", "fields": ["address"], "no_marker": true, "no_tag_br": true, "data_type": "raw"}'/>", "inv_name": "<t t-esc="doc.partner_invoice_id.name"/>", "inv_phone": "<t t-esc="doc.partner_invoice_id.phone"/>", "inv_fax": "", "partner_address": "<span t-field="doc.partner_id" t-field-options='{"widget": "contact", "fields": ["address"], "no_marker": true, "no_tag_br": true, "data_type": "raw"}' />", "partner_name": "<t t-esc="doc.partner_id.name"/>", "partner_vat": "<t t-esc="doc.partner_id.vat"/>", "order_name": "<t t-esc="doc.name"/>", "client_order_ref": "<t t-if="doc.client_order_ref"><t t-esc="doc.client_order_ref"/></t>", "date_order": "<t t-if="doc.date_order"><t t-esc="doc.date_order"/></t>", "salesperson": "<t t-if="doc.user_id.name"><t t-esc="doc.user_id.name"/></t>", "payment_term_id": "<t t-if="doc.payment_term_id"><t t-esc="doc.payment_term_id"/></t>", "amount_untaxed": "<t t-esc="doc.amount_untaxed"/>", "amount_total": "<t t-esc="doc.amount_total"/>", "note": "<t t-esc="doc.note"/>", "payment_term_note": "<t t-if="doc.payment_term_id.note"><t t-esc="doc.payment_term_id.note"/></t>", "fiscal_position_note": "<t t-if="doc.fiscal_position_id and doc.fiscal_position_id.note"><t t-esc="doc.fiscal_position_id.note"/></t>" }); /*生成从表数据*/ <t t-foreach="doc.order_lines_layouted()" t-as="page"> <t t-foreach="page" t-as="layout_category"> <t t-foreach="layout_category['lines']" t-as="l"> <!-- 求合计金额 --> <t t-if="(layout_category_size > 1 or page_size > 1) and layout_category['subtotal']" groups="sale.group_sale_layout"> <t t-set="subtotal" t-value="sum(line.price_subtotal for line in layout_category['lines'])"/> </t> <t t-set="line_name" t-value="l.name.replace('\n','').encode('utf-8')"/> _tableOrderLines.Data.push( { "order_id": "<t t-esc="doc.id"/>", //主从表关联字段,对应order表的id "line_name": "<t t-esc="line_name"/>", "product_uom_qty": "<t t-esc="l.product_uom_qty"/>", "product_uom": "<t t-esc="l.product_uom"/>", "price_unit": <t t-esc="l.price_unit"/>, "discount": <t t-esc="l.discount"/>, "tax_description": "<t t-esc="l.tax_id.description"/>", "tax_name": "<t t-esc="l.tax_id.name"/>", "price_subtotal": "<t t-esc="l.price_subtotal"/>", "price_total": "<t t-esc="l.price_total"/>", "subtotal": "<t t-esc="subtotal"/>", }); </t> </t> </t> </t> /*数据合并到总的数据对象*/ _data["Tables"].push(_tableLogo); _data["Tables"].push(_tableOrder); _data["Tables"].push(_tableOrderLines); var _reportData = JSON.stringify(_data); //转成json字符串 console.log(_reportData); //生成数据之后,在cfprint_ext.js中会自动调用进行打印 </script> </t> <!-- End of cfprint.html_container --> </template> <!-- End of report_saleorder --> <!-- 订单/询价单 结束--> </data> </odoo>
step 3、本例的打印模板
本例的模板在该模块下的 templates/report_saleorder.fr3 。 把report_saleorder.fr3复制到康虎云报表的cfprint.exe 目录下/templates文件夹中即可。