每次我们导出excel的时候 ,如果数据量很大,导出花费的时间会很长,页面却有没人任何反应,这个时候用户会认为系统有问题,要么关了页面,要么狂点导出。感知太差了~甚至用户误操作会导致服务器崩溃。 所以我么我们需要通过进度条方式告知客户导出的进度。 以下为java poi +Easyui 实现导出excel进度条思路,通过在导出过程中循环请求后台确认时候导出完毕来控制进度条显示。
后台 新增一个通用获取是否导出完毕方法: session中存入一个exportedFlag
/**
*
* @Function: OsTaskAction::isExport
* @Description: 是否导出完毕
* @version: v1.0.0
* @author: luanhy
* @date: 12月5日 下午4:32:32
*
* Modification History:
* Date Author Version Description
*-------------------------------------------------------------
*/
public void isExport(){
Object exportedFlag = super.getSession().getAttribute("exportedFlag");
if(exportedFlag == null){
logger.info("已经导完");
super.writeWithUtf8("true");
}else{
logger.info("还未导完");
super.writeWithUtf8("false");
}
}
后台 导出excel方法:只需在在导出前设置session中 exportedFlag任意值,导出后清空exportedFlag即可,清空设置exportedFlag 大家可以对所有导出请求进行封装设置。
/**
* 普通导出
*/
public void exportExcel1(){
super.getSession().setAttribute("exportedFlag", "false");
//导出excel方法略过
super.getSession().removeAttribute("exportedFlag");
}
附录 super Action调用到的方法:
public HttpSession getSession() {
return ServletActionContext.getRequest().getSession();
}
public void writeWithUtf8(String str){
try {
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
this.write(str);
} catch (Exception e) {
logger.error(e,e);
}
}
super Action漏了一方法
/**
* 输出响应
*
* @param str
* @throws Exception
*/
public void write(String str) throws Exception {
HttpServletResponse response = this.getResponse();
response.getWriter().write(str);
response.getWriter().flush();
response.getWriter().close();
前台,导出js方法: 1.导出前显示进度条, 2 开始导出 3.通过setInterval 方法循环请求后台获取exportedFlag, 一旦后台返回true(导出完毕),则关闭进度条并提示。
/**
* 导出excel(带进度条)
* @param exportExcelUrl
* @param scanTime 检测是否导出完毕请求间隔 单位毫秒
* @param interval 进度条更新间隔(每次更新进度10%) 单位毫秒 导出时间越长 请设置越大 200 对应2秒导出时间
*/
function exportExcWithprogress(isExportUrl,exportExcelUrl,scanTime,interval){
if(scanTime<1000 || scanTime == undefined){
scanTime = 1000;
}
$.messager.progress({
title:'导出中,请等待...',
msg:'导出进度:',
interval: interval
});
$.messager.progress('bar').progressbar({
onChange: function(value){
if(value == 100){
$.messager.show({
title:'导出完毕',
msg:'导出完毕,请保存!',
timeout:2000,
showType:'fade',
style:{
top:'45%'
}
});
$.messager.progress('close');
}
}
});
location.href = exportExcelUrl;
var timer = setInterval(function(){
$.ajax({
url: isExportUrl+'?id='+Math.random(),
success: function(data){
console.log(data);
if(data == "true"){
$.messager.progress('bar').progressbar('setValue','100');
clearInterval(timer);
}
},
error:function(e){
console.log(e.responseText);
}
});
}, scanTime);
}
参数 scanTime: 可以根据服务器压力和估计的导出时间调整。 interval: 如果导出需要大约time= 10秒 设置interval 比 time*100 稍大即可,不确定导出时间可以设置的大些,效果是进度条仍然会自动关闭,只是可能从20%突然跳到100%。
调用例子如下: 这里输入代码
function exportExcel(){
var isExportUrl = "task/isExport.do";
var exportExcelUrl = "task/exportExcel.do";
exportExcWithprogress(isExportUrl, exportExcelUrl, undefined ,500);
}