Odoo中文社区可以通过以下两个域名访问:shine-it.net , odoo.net.cn

由于系统升迁的原因,本论坛部分较早期的内容存在格式和链接损坏失效的问题,并非本论坛系统本身的缺陷,望谅解

本社区没有维护任何QQ群讨论组,任何与本社区同名的QQ群讨论组的言论与本社区无关!

开发人员可以登录gitter讨论组: http://gitter.im/odoo-china/Talk, 需要github账号

如果您登录系统碰到问题,请在微信公众号留言:

实现Web Client上的html报表直接打印



  • 读了一下openerp新版本的代码,的确有不少的改进。尤其是web client,基本上是推倒重写的。
    看官方的论坛上很多人在问如何在web client上实现报表的直接打印,想想现在的打印的确是不方便,总是把文件下载下来,然后打开文件打印。
    html的报表容易想到,因为可以直接在web client打开一个新窗口,用js进行打印。于是就改改openerp代码,实现一个简单的html报表的。供大家参考。
    时间仓促,勿笑话。

    (我用的web client是embedded模式)
    OE新版(6.1)的web client的整个结构和以前都不一样了,所以要先研究报表的controller.
    在Reports类里,看到:

    <br />(&#039;Content-Disposition&#039;, &#039;attachment; filename=&quot;%s.%s&quot;&#039; % (action&#91;&#039;report_name&#039;], report_struct&#91;&#039;format&#039;]))<br />
    


    这样的http header的定义。这是要直接下载。修改先:

    <br />&nbsp; &nbsp; &nbsp; &nbsp; header_list = [<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  (&#039;Content-Type&#039;, report_mimetype),<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  (&#039;Content-Length&#039;, len(report))]<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; if report_struct&#91;&#039;format&#039;] not in &#91;&#039;html&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header_list.append((&#039;Content-Disposition&#039;, &#039;attachment; filename=&quot;%s.%s&quot;&#039; % (action&#91;&#039;report_name&#039;], report_struct&#91;&#039;format&#039;])))<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; return req.make_response(report,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  headers=header_list,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  cookies={&#039;fileToken&#039;: int(token)})<br /><br />
    


    没什么好说的。

    改完,重启服务,测试。发现点击报表按钮后,浏览器无任何反映,也没有打开新窗口。
    看来6.1的确是不一样。
    跟踪代码,发现报表这个action在web client的处理函数名为ir_actions_report_xml。
    内部又调用:

    self.session.get_file({<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: &#039;/web/report&#039;,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: {action: JSON.stringify(action)},<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; complete: $.unblockUI,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: function(){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!self.dialog &amp;&amp; on_closed) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on_closed();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.dialog_stop();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error: session.webclient.crashmanager.on_rpc_error<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })
    



    看名字就知道,这货肯定把所有的报表下载下来,而不是打开新窗口。考虑修改。

    <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; post_data = {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: &#039;/web/report&#039;,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: {action: JSON.stringify(action)},<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; complete: $.unblockUI,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: function(){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!self.dialog &amp;&amp; on_closed) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on_closed();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.dialog_stop();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error: session.webclient.crashmanager.on_rpc_error<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(action.report_type == &#039;mako2html&#039;){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.session.open_report_page(post_data)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.session.get_file(post_data)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
    



    get_file函数通过jquery调用了服务端的report view.我们也需要做同样的事情:

    在core.js里:

    <br />&nbsp; &nbsp; /**<br />&nbsp; &nbsp;  *Open an html report.<br />&nbsp; &nbsp;  *未处理error<br />&nbsp; &nbsp; **/<br />&nbsp; &nbsp; open_report_page: function(options) {<br />&nbsp; &nbsp; &nbsp; &nbsp; var token = new Date().getTime();<br />&nbsp; &nbsp; &nbsp; &nbsp; params = options.data;<br />&nbsp; &nbsp; &nbsp; &nbsp; params&#91;&#039;session_id&#039;] = this.session_id;<br />&nbsp; &nbsp; &nbsp; &nbsp; params&#91;&#039;token&#039;] = token;<br />&nbsp; &nbsp; &nbsp; &nbsp; $.post(options.url, params, function(data){<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; report_window=window.open(&#039;&#039;,&#039;&#039;,&#039;width=100,height=100&#039;);<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; report_window.document.write(data);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; report_window.focus();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.complete();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (options.success) { options.success(); }<br />&nbsp; &nbsp; &nbsp; &nbsp; });<br />&nbsp; &nbsp; },<br />
    



    ok, 可以在报表模板里写任何js东西,包括打印的代码。
    我并不是用js代码直接打印,是通过Lodop控件,推荐大家使用。
    可以直接打印,套打,导出excel。。。。


    至此,就可以完成html报表的直接打印了。



  • 组织学习一下 web 的源码就更棒了....


  • 管理员

    好文!感谢lz的分享



  • [quote author=Joshua link=topic=2860.msg9638#msg9638 date=1333120570]
    好文!感谢lz的分享
    [/quote]

    看来web可能会长期作为一个模块作为存在。
    而现在看,web模块的精华,在一大堆的js文件里。唉,难搞。


Log in to reply