1. 程式人生 > >實現Web Client上的html報表直接列印

實現Web Client上的html報表直接列印

讀了一下openerp新版本的程式碼,的確有不少的改進。尤其是web client,基本上是推倒重寫的。
看官方的論壇上很多人在問如何在web client上實現報表的直接列印,想想現在的列印的確是不方便,總是把檔案下載下來,然後開啟檔案列印。
html的報表容易想到,因為可以直接在web client開啟一個新視窗,用js進行列印。於是就改改openerp程式碼,實現一個簡單的html報表的。供大家參考。
時間倉促,勿笑話。


(我用的web client是embedded模式)
OE新版(6.1)的web client的整個結構和以前都不一樣了,所以要先研究報表的controller.
在Reports類裡,看到:
('Content-Disposition', 'attachment; filename="%s.%s"' % (action['report_name'], report_struct['format']))

這樣的http header的定義。這是要直接下載。修改先:


header_list = [
                 ('Content-Type', report_mimetype),
                 ('Content-Length', len(report))]
        
        if report_struct['format'] not in ['html']:
            header_list.append(('Content-Disposition', 'attachment; filename="%s.%s"' % (action['report_name'], report_struct['format'])))
        
        return req.make_response(report,
             headers=header_list,
             cookies={'fileToken': int(token)})


沒什麼好說的。


改完,重啟服務,測試。發現點選報表按鈕後,瀏覽器無任何反映,也沒有開啟新視窗。
看來6.1的確是不一樣。
跟蹤程式碼,發現報表這個action在web client的處理函式名為ir_actions_report_xml。
內部又呼叫:
self.session.get_file({
                    url: '/web/report',
                    data: {action: JSON.stringify(action)},
                    complete: $.unblockUI,
                    success: function(){
                        if (!self.dialog && on_closed) {
                            on_closed();
                        }
                        self.dialog_stop();
                    },
                    error: session.webclient.crashmanager.on_rpc_error
                })



看名字就知道,這貨肯定把所有的報表下載下來,而不是開啟新視窗。考慮修改。


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



get_file函式通過jquery呼叫了服務端的report view.我們也需要做同樣的事情:


在core.js裡:


    /**
     *Open an html report.
     *未處理error
    **/
    open_report_page: function(options) {
        var token = new Date().getTime();
        params = options.data;
        params['session_id'] = this.session_id;
        params['token'] = token;
        $.post(options.url, params, function(data){
            report_window=window.open('','','width=100,height=100');


            report_window.document.write(data);
            report_window.focus();
            options.complete();
            if (options.success) { options.success(); }
        });
    },




ok, 可以在報表模板裡寫任何js東西,包括列印的程式碼。
我並不是用js程式碼直接列印,是通過Lodop控制元件,推薦大家使用。
可以直接列印,套打,匯出excel。。。。




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