Java實現點擊導出excel頁面遮罩屏蔽,下載完成後解除遮罩

1、問題場景

  最近在作數據統計功能,需求是導出大數據量的excel,時間間隔較長,大概須要十秒左右,點擊導出後,頁面沒有作任何處理,用戶也不知道是否正在導出;若是沒有作交互上的限制,用戶能夠一直點擊導出按鈕,這樣勢必會形成服務器癱瘓。前端

2、嘗試過程

  花了一天嘗試了兩種方案:ajax

  2.1 純前端添加遮罩

    單純的前端是沒法監聽文件是否下載完成的,主要試了兩種方案:json

      1.因爲導出是用form表單提交的,並將form的target設置到一個隱藏iframe來達到不刷新頁面而導出。原本想利用隱藏iframe的onload事件來判斷是否導出成功的,可是調試發現導出成功後不會觸發,因此該條路沒法走通了。後端

      2.用ajax來作導出,可是該方法沒法實現自動下載導出文件,這條路也就沒法走通了。瀏覽器

    原本想監聽瀏覽器點擊下載連接到彈出窗口完成的狀態,查閱資料發現這些都是瀏覽器包辦了的,沒有任何方法能夠獲取到狀態,可能瀏覽器是出於安全考慮,因此沒有提供。安全

  2.2 先後端聯動

    主體思路是這樣:服務器

    前端點擊導出按鈕加載事件並添加遮罩效果,設置定時器監聽ajax從後端返回是否導出完成狀態,後端狀態設置初始session狀態值,在導出事件後改變該session值,最後經過ajax返回前端。前端接收到狀態值,若是已導出完成,解除遮罩;如不是,則繼續定時監聽直到返回導出完成爲止。session

    該方案可行。ide

3、具體方案

前端js代碼:oop

//點擊導出事件
        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;
    }
相關文章
相關標籤/搜索