跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(Flatly)
  • 不使用皮肤
折叠

Odoo 中文社区

  1. 主页
  2. 版块
  3. Odoo 开发与实施交流
  4. 实现Web Client上的html报表直接打印

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

已定时 已固定 已锁定 已移动 Odoo 开发与实施交流
5 帖子 3 发布者 6.8k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • D 离线
    D 离线
    d_yang
    写于 最后由 编辑
    #1

    读了一下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 条回复 最后回复
    0
    • mrshellyM 离线
      mrshellyM 离线
      mrshelly
      写于 最后由 编辑
      #2

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

      1 条回复 最后回复
      0
      • JoshuaJ 离线
        JoshuaJ 离线
        Joshua 管理员
        写于 最后由 编辑
        #3

        好文!感谢lz的分享

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

        1 条回复 最后回复
        0
        • D 离线
          D 离线
          d_yang
          写于 最后由 编辑
          #4

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

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

          1 条回复 最后回复
          0

          • 登录

          • 没有帐号? 注册

          • 登录或注册以进行搜索。
          • 第一个帖子
            最后一个帖子
          0
          • 版块
          • 标签
          • 热门
          • 用户
          • 群组