zoukankan      html  css  js  c++  java
  • 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; }
  • 相关阅读:
    jquery实现短信群发功能(机试题)
    PreparedStatement与Statement区别
    java中static关键字
    java笔试01
    java基础
    sqlserver errorcode
    改变分辨率会牵连到EMF图的大小
    基础知识——各种分辨率的知识 From http://vod.sjtu.edu.cn/help/Article_Show.asp?ArticleID=308
    本地存储
    Silverlight 3 MultiThreading编程http://blog.csdn.net/zjfei/archive/2009/07/27/4384428.aspx
  • 原文地址:https://www.cnblogs.com/edisoner/p/10773007.html
Copyright © 2011-2022 走看看