Java实现点击导出excel页面遮罩屏蔽,下载完成后解除遮罩

一、问题场景

  最近在做数据统计功能,需求是导出大数据量的excel,时间间隔较长,大概需要十秒左右,点击导出后,页面没有做任何处理,用户也不知道是否正在导出;如果没有做交互上的限制,用户可以一直点击导出按钮,这样势必会造成服务器瘫痪。

二、尝试过程

  花了一天尝试了两种方案:

  2.1 纯前端添加遮罩

    单纯的前端是无法监听文件是否下载完成的,主要试了两种方案:

      1.由于导出是用form表单提交的,并将form的target设置到一个隐藏iframe来达到不刷新页面而导出。本来想利用隐藏iframe的onload事件来判断是否导出成功的,但是调试发现导出成功后不会触发,所以该条路无法走通了。

      2.用ajax来做导出,但是该方法无法实现自动下载导出文件,这条路也就无法走通了。

    本来想监听浏览器点击下载链接到弹出窗口完成的状态,查阅资料发现这些都是浏览器包办了的,没有任何方法可以获取到状态,可能浏览器是出于安全考虑,所以没有提供。

  2.2 前后端联动

    主体思路是这样:

    前端点击导出按钮加载事件并添加遮罩效果,设置定时器监听ajax从后端返回是否导出完成状态,后端状态设置初始session状态值,在导出事件后改变该session值,最后通过ajax返回前端。前端接收到状态值,如果已导出完成,解除遮罩;如不是,则继续定时监听直到返回导出完成为止。

    该方案可行。

三、具体方案

前端js代码:

//点击导出事件
        function startexport(){
            $("#divload").show();//打开加载中遮罩
            listenEnd();
        }
        
        function listenEnd() {//定时监听             
            var loop = setInterval(function() {
                if ($("#txtendflag").val() == "1") {
                    clearInterval(loop);//停止定时任务
                    $("#divload").hide();//关闭加载中遮罩
                } else {
                    getendflag();                 
                }
            }, 1000);//单位毫秒  注意:如果导出页面很慢时,建议循环时间段稍长一点
        }

        function getendflag() {//请求session标记位             
              $.ajax({
                        type : 'post',
                        url : 'ajcxtjlistaction.action?cmd=getendflag',
                        dataType : 'json',
                        success : function(data) {    
                            $("#txtendflag").val(data.custom.flag);        
                        },
                        error : function(error) {
                            console.log('接口不通' + error);
                        }
                    })  
        }

后端Java代码:

public void export() {
        request.getSession().removeAttribute("endflag");//每次导入前,清除结束标记
/******导出开始******/

//@#$%#^^^&&&&&&$$%$%$%##$@^^^$
/******导出结束*******/ request.getSession().setAttribute("endflag", "1");//设置结束标记 } //获取结束标记 public Object getendflag() { Object flag = request.getSession().getAttribute("endflag"); //获取结束标记*/ JSONObject obj = new JSONObject(); obj.put("flag", flag);//返回状态值 return obj; }

 

posted @ 2019-04-26 10:47  edisoner  阅读(2747)  评论(1编辑  收藏  举报