网上有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会随着变化
ExtJS Grid 导出 Excel 实现
本文介绍了一种使用 ExtJS Grid 实现数据导出到 Excel 的方法,包括客户端 JavaScript 代码与服务器端 Ruby on Rails 代码,确保导出的 Excel 文件能够完整展示网格数据,并且可以自定义列顺序和宽度。
3668

被折叠的 条评论
为什么被折叠?



