一、在下载大文件时,页面会进入假死状态,于是加上一个进度条以标识后台程序正在运行。
目前,做的进度条并不是实时的,并不会根据程序执行的进度正确显示。
目前是将进度条定时加载到90%,然后停止,等待后台执行完成时,修改标志位以隐藏进度条。
二、实现代码
进度条 js使用的是:EXT
核心思路:使用 cookie 标识后台操作执行完成。
1、js+ajax 使用
这种方式比较简单,直接看代码。
function fun_Login() { ProcessBarExt_Init("登录");//初始化进度条对象 ProcessBarExt_Run();//进度条对象 开始加载 $.ajax({ type: "POST", dataTye: "json", url: "/pages/Login.ashx", data: { type: 1}, success: function (result) { if (result == "1") { alert("执行成功"); } else{ alert("执行失败"); } ProcessBarExt_Hide(); }, error: function () { alert("执行出错"); ProcessBarExt_Hide(); } }); }
2、aspx 下载文件
这个比较麻烦,经大佬指点 外加调试才实现。
前言,之前做过类似的功能,所以先将 下载文件方法中的curContext.Response.End(); 代码删除掉了。否则,HTTP请求会结束,不会再执行后面的代码。
想到过得思路:
(1)使用cookie,设置一个cookie以标识后台程序是否执行完成。此方法为最终方案。
一个隐藏域,保存每次点击下载时随机生成的cookie名称,变量ExportEndSignCookieName保存,
后台执行完操作时,根据添加一个cookie,name即为前台随机生成的保存到隐藏域中的值,value为"complete",
前台,使用js的定时器循环获取cookie的值,
如果cookie的值为后台设定的"complete",则隐藏进度条、删除js定时器、删除当前cookie。
js代码
<!--导出文件时 随机生成的cookie名称--> <asp:HiddenField ID="hid_ExportEndSignCookieName" runat="server" ClientIDMode="Static" /> <script type="text/javascript"> var tExportCookie;//定时器-查看后台是否执行完成 var ExportEndSignCookieName="";//随机生成的cookie名称-查看后台是否执行完成 //导出Excel,添加进度条 function lbtnExport_click(){ if(confirm('是否导出所查询的数据?')){ ExportEndSignCookieName=Math.random();//生成随机的cookie名称 $("#hid_ExportEndSignCookieName").val(ExportEndSignCookieName);//cookie名称赋值给隐藏域 ProcessBarExt_Init("导出Excel");//初始化进度条对象 ProcessBarExt_Run();//进度条对象 开始加载 tExportCookie = window.setInterval(fun_ExportEndSign,20);//定时循环,查看导出操作是否完成 return true; } else{ return false; } } //查看导出是否结束,complete function fun_ExportEndSign(){ if(checkExportEndSign(ExportEndSignCookieName)){ ProcessBarExt_Hide();//进度条隐藏 window.clearInterval(tExportCookie); //删除定时器 delCookie(ExportEndSignCookieName);//删除cookie } } </script>
后台代码
/// <summary> /// 导出方法 /// </summary> private void ExportExcelByProc() { string tempWhere = "本次查询"; SqlParameter[] sqlParameters = { new SqlParameter("@StartIndex",1), new SqlParameter("@EndIndex",int.MaxValue) }; DataSet ds = ExecuteStoredProcedureByDSNameEx("PersonInfo_List", "Business",sqlParameters); if (ds != null && ds.Tables != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { string sheetname = "个人建档管理表"; string[] colsCols = { "sNo"}; string[] colsNames = { "档案编号"}; BF.Web.App_Code.ExcelHelper.ExportHasWhereToWeb(sheetname + ExportExcelRule() + ".xls", ds.Tables[0], sheetname, sheetname, tempWhere, colsCols, colsNames); string shid_ExportCookieName = hid_ExportEndSignCookieName.Value; HttpCookie cookie = HttpContext.Current.Request.Cookies[shid_ExportCookieName]; if (cookie == null) { cookie = new HttpCookie(shid_ExportCookieName); } cookie.Value = "complete"; HttpContext.Current.Response.AppendCookie(cookie); } else { Messages("当前无查询结果,请重新查询!"); } }
此方法,可以解决需求。
(2)在后台注册js,去调用前台的js
string ExtMsg = @"Ext.MessageBox.show({title: '系统提示',msg: '" + msg + "',buttons: {ok:'确 定'},icon: 'ext-mb-info'});";
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "click", ExtMsg, true);
在 下载文件方法的最后面curContext.Response.BinaryWrite(); 加上了上面的代码,
但是,当HTTP请求执行了下载文件的操作后,就结束了,并没有执行js的方法。
此方法,未实现需求。
(3)使用 Hidden做标志位,前台js进行监视,当隐藏域 触发 change事件时,去执行进度条的隐藏操作。
但调试时,当后台代码执行完成后(也执行了隐藏域的赋值),但是前台的js监视,却捕获不到change事件。
是不是这个赋值,将页面进行了刷新,或是这个赋值操作根本没有提交,反正没有起到作用。
此方法,未实现需求。
(4)使用iframe进行下载,监视iframe的加载完毕,然后进行进度条的隐藏。
此方法,将隐藏进度条的操作全部放到了js中,但是需要创建一个新的页面。
此方法,未进行测试,不知道效果如何。
三、公共代码
js设置cookie
/****************************获取和设置cookie 开始***********************************/ //获取cookie function getCookie(name) { var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); //正则匹配 if (arr = document.cookie.match(reg)) { return unescape(arr[2]); } else { return null; } } //设置自定义过期时间cookie function setCookie(name, value, time) { var msec = getMsec(time); //获取毫秒 var exp = new Date(); exp.setTime(exp.getTime() + msec * 1); document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString(); } //将字符串时间转换为毫秒,1秒=1000毫秒 function getMsec(DateStr) { var timeNum = str.substring(0, str.length - 1) * 1; //时间数量 var timeStr = str.substring(str.length - 1, str.length); //时间单位前缀,如h表示小时 if (timeStr == "s") //20s表示20秒 { return timeNum * 1000; } else if (timeStr == "h") //12h表示12小时 { return timeNum * 60 * 60 * 1000; } else if (timeStr == "d") { return timeNum * 24 * 60 * 60 * 1000; //30d表示30天 } } //删除cookie function delCookie(name) { var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval = getCookie(name); if (cval != null) { document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString(); } } //检查cookie function checkCookie() { username = getCookie('username') if (username != null && username != "") { alert('Welcome again ' + username + '!') } else { username = prompt('Please enter your name:', "") if (username != null && username != "") { setCookie('username', username, 365) } } } /*扩展使用*/ //查看导出结束标志位,是否为指定的值 function checkExportEndSign(ExportEndSignCookieName) { var ExportCookieValue = getCookie(ExportEndSignCookieName);//获取cookie的值 if (ExportCookieValue != "" && ExportCookieValue != null && ExportCookieValue != undefined && ExportCookieValue == "complete") { return true; } else { return false; } } /****************************获取和设置cookie 结束***********************************/
C#后台添加cookie
string shid_ExportCookieName = hid_ExportEndSignCookieName.Value; HttpCookie cookie = HttpContext.Current.Request.Cookies[shid_ExportCookieName]; if (cookie == null) { cookie = new HttpCookie(shid_ExportCookieName); } cookie.Value = "complete"; HttpContext.Current.Response.AppendCookie(cookie);
需要的js和css
<link href="/script/ext3.4/resources/css/ext-all.css" rel="stylesheet" type="text/css" /> <script src="/script/ext3.4/adapter/ext/ext-base.js" type="text/javascript"></script> <script src="/script/ext3.4/ext-all.js" type="text/javascript"></script>
ext的进度条,初始化、运行、隐藏
<script type="text/javascript"> /*进度条 相关js*/ //声明需要使用的对象 var progressBarExt;//ext进度条对象 var progressBarExt_isEnd;//ext进度条是否结束(操作执行完成,将标志位置1,进度条循环递增不会再执行) //进度条对象-初始化 function ProcessBarExt_Init(bar_title) { progressBarExt = Ext.Msg.show({ title: bar_title, msg: "数据过大,需要等待一段时间!", progress: true, width: 300 }); progressBarExt_isEnd = 0;//初始化为0,未结束 progressBarExt.updateProgress(0, "0%");//初始化为0%,刚开始 Ext.onReady(ProcessBarExt_Run); } //进度条对象-开始执行 function ProcessBarExt_Run() { var count = 0; var bartext = ""; var curnum = 0; Ext.TaskMgr.start({ run: function () { count++; if (count < 10 && progressBarExt_isEnd == 0) { curnum = count / 10; bartext = curnum * 100 + "%"; progressBarExt.updateProgress(curnum, bartext); } }, interval: 500 }) } //进度条对象-进度到100%且隐藏 function ProcessBarExt_Hide() { progressBarExt_isEnd = 1; progressBarExt.updateProgress(10, "100%"); setTimeout(function () { progressBarExt.hide(); }, 500); } </script>