rails+extjs中excel导出

网上有extjs的grid直接导出为excel的控件,但是不满足需求,因为grid一般是分页的,而excel导出的时候肯定是全部数据

 

导 出excel这个过程的输入是 列配置信息(列头,字段名,宽度,顺序)

输出时excel文件

生成grid数据和导出 excel的数据要能重用

 

所以把列头信息作为参数传递到服务器端

params = Ext.apply({},this.findParentByType('form').getForm().getValues(),store.baseParams);

var cm = grid.getColumnModel() ;
for (var i = 0; i < cm.getColumnCount(); i++) {
    if (cm.getDataIndex(i)){
        var fld = grid.store.recordType.prototype.fields.get(cm.getDataIndex(i));
        var column_type = 'String';
        switch(fld.type) {
            case "int":
                column_type="int";
                break;
            case "float":
                column_type="float";
                break;
            case "date":
                column_type="date";
                break;
        };
        params['columns['+i+'][hidden]']= cm.isHidden(i);
        params['columns['+i+'][column_width]'] = cm.getColumnWidth(i);
        params['columns['+i+'][column_header]']= cm.getColumnHeader(i);
        params['columns['+i+'][column_type]']  = column_type;
        params['columns['+i+'][data_index]']  = cm.getDataIndex(i);
    }
}
openPostWindow('/car_info/export_to_excel','_blank',params); //注意这行 

 

最后在新窗口打开链接不是用window.open,因为get方式传输数据量有限制,在ie中可能会报错,要用post方式

openPostWindow代码如下:

function openPostWindow(url,name,data){ 
    var tempForm = document.createElement("form"); 
    tempForm.id="tempForm1"; 
    tempForm.method="post"; 
    tempForm.action=url; 
    tempForm.target=name; 
    for(var p in data){ 
        var hideInput = document.createElement("input"); 
        hideInput.type="hidden"; 
        hideInput.name= p;
        hideInput.value= data[p];
        tempForm.appendChild(hideInput);  
    }    
    var request_forgery_protection_token_hideInput = document.createElement("input"); 
    request_forgery_protection_token_hideInput.type="hidden"; 
    request_forgery_protection_token_hideInput.name= "authenticity_token";
    request_forgery_protection_token_hideInput.value= Ext.Ajax.extraParams.authenticity_token;
    tempForm.appendChild(request_forgery_protection_token_hideInput);  

    if(tempForm.attachEvent){
        tempForm.attachEvent("onsubmit",function(){openWindow(name);});
    } else {
        tempForm.addEventListener("submit",function(){openWindow(name);},false); 
    }
    document.body.appendChild(tempForm); 
    if (tempForm.fireEvent) {
        tempForm.fireEvent('onsubmit');
        tempForm.submit();
    } else if (document.createEvent) {
        var ev = document.createEvent('HTMLEvents');
        ev.initEvent('submit', false, true);
        tempForm.dispatchEvent(ev);
    }
    
    document.body.removeChild(tempForm);
    return false;
}

 在firefox和ie中测试通过

 

 

服务器端代码如下

 

    query_params = params
    query_params.delete(:limit)
    query_params.delete(:start)
    result = listdata(query_params)
    
    xls_report = StringIO.new  
    book = Spreadsheet::Workbook.new  
    sheet1 = book.create_worksheet :name => "WORKSHEET_NAME"  

    sheet1.row(0).default_format = Spreadsheet::Format.new :color => :black, :weight => :bold, :size => 10  
    
    keys = params[:columns].keys.compact.collect{|key| key.to_i}.sort.collect{|key| key.to_s}
      
    sheet1.row(0).concat(keys.collect{|key| params[:columns][key][:column_header]})
    row_num = 1
    result[:rows].each do |row|
      sheet1.row(row_num).concat keys.collect{|key| row[params[:columns][key][:data_index]]}
      row_num = row_num + 1
    end
    keys.each_with_index  do |key,index| 
      sheet1.column(index).width = params[:columns][key][:column_width].to_f/10
    end

    book.write xls_report  

    send_data(xls_report.string,
      :filename => 'FILENAME.xls',
      :type => 'application/vnd.ms-excel',
      :disposition => 'inline')

 首先删除limit和start两个参数,然后调用listdata这个取数据的方法(这个方法一般写在model中,这里为了简单写在controller中作为private方法),然后把数据写入到excel流中,最后发送excel流

 

这样excel导出完成,excel和grid从同一来源取数据

并且如果在界面上调整了列的顺序或者宽度,导出的excel会随着变化

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值