Odoo 中文社区

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • Popular
    • Users
    • Groups

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

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

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

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

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

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

    Odoo 开发与实施交流
    3
    5
    6592
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      d_yang last edited by

      读了一下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报表的直接打印了。

      1 Reply Last reply Reply Quote 0
      • mrshelly
        mrshelly last edited by

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

        1 Reply Last reply Reply Quote 0
        • Joshua
          Joshua 管理员 last edited by

          好文!感谢lz的分享

          【上海先安科技】(joshua AT openerp.cn),欢迎关注公众号:openerp_cn

          1 Reply Last reply Reply Quote 0
          • D
            d_yang last edited by

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

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

            1 Reply Last reply Reply Quote 0
            • First post
              Last post