You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel下载完成后如何隐藏jQuery Spinner?附代码求助

解决下载Excel后jQuery Spinner无法自动隐藏的问题

问题背景

你现在碰到的情况是:用户点击JSP页面里的Download提交按钮时,jQuery Spinner能正常显示,但当Servlet生成完Excel文件触发浏览器下载后,Spinner就一直停留在页面上不会自动隐藏,对吧?

问题原因

这是因为同步表单提交的特性导致的:当你点击submit按钮提交表单时,浏览器会发起同步请求,此时页面的JS线程会被阻塞,而且浏览器处理文件下载的过程并不会触发页面的任何“完成”回调——因为下载是浏览器的独立行为,不会刷新当前页面,所以你的JS代码没有机会去隐藏Spinner。

解决方案

这里给你两种可行的方案,你可以根据自己的项目情况选择:

方案一:改用AJAX请求+Blob处理下载(推荐)

这种方法通过AJAX异步请求Servlet,拿到Excel文件的二进制数据后,前端手动触发下载,这样就能监听请求的完成事件,在下载完成后隐藏Spinner。

1. 修改JSP中的按钮(把submit改成普通button)

<tr>
  <td>
    <br />
    <br />
    <input type="submit" value="Search" name="action" />
    <input type="hidden" id="download_token_value_id" />
    <!-- 把submit改成button,避免默认表单提交 -->
    <input type="button" value="Download" name="action" class="spinner" />
  </td>
</tr>
<center>
  <div id="fontSpinner" style="color: blue; display: none;" class="fa fa-spinner fa-pulse fa-3x fa-fw">
  </div>
</center>

2. 修改JS代码,用AJAX处理请求和下载

$('.spinner').click(function() {
  $("#fontSpinner").css("display", "block"); // 显示Spinner

  // 发起AJAX请求
  $.ajax({
    url: "你的Servlet实际路径", // 替换成你的Servlet路径
    type: "POST", // 或GET,根据你的Servlet配置调整
    data: $("form").serialize(), // 序列化表单数据,保证参数和原提交一致
    xhrFields: {
      responseType: 'blob' // 指定响应类型为二进制Blob
    },
    success: function(blob, status, xhr) {
      // 从响应头获取文件名(如果Servlet设置了自定义头)
      const fileName = decodeURIComponent(xhr.getResponseHeader('X-File-Name')) || "导出数据.xlsx";
      // 创建下载链接
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      // 清理临时资源
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
      
      // 下载完成后隐藏Spinner
      $("#fontSpinner").css("display", "none");
    },
    error: function() {
      // 请求失败也要隐藏Spinner,避免一直显示
      $("#fontSpinner").css("display", "none");
      alert("下载失败,请重试!");
    }
  });
});

3. (可选)修改Servlet添加自定义文件名头

如果想让前端动态获取文件名,可以在Servlet里添加:

response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("UTF-8");
String excelFileName = "导出数据.xlsx";
response.setHeader("Content-Disposition", "attachment; filename=\"" + excelFileName + "\"");
// 添加自定义头,方便前端获取文件名
response.setHeader("X-File-Name", URLEncoder.encode(excelFileName, "UTF-8"));

// 生成Excel文件的代码...
ServletOutputStream out = response.getOutputStream();
workbook.write(out);
workbook.close();
out.flush();
out.close();

方案二:用Cookie轮询实现(适合不想改AJAX的场景)

如果你的项目不适合改用AJAX,可以让Servlet在完成Excel输出后设置一个Cookie,前端用定时器轮询这个Cookie,一旦检测到就隐藏Spinner并清除Cookie。

1. 修改Servlet代码,添加Cookie

// 生成并输出Excel的代码...
workbook.write(out);
workbook.close();
out.flush();
out.close();

// 添加Cookie标记下载完成
Cookie downloadComplete = new Cookie("download_complete", "true");
downloadComplete.setPath("/"); // 路径要和项目一致
downloadComplete.setMaxAge(10); // 10秒后自动过期
response.addCookie(downloadComplete);

2. 修改JS代码,添加轮询逻辑

$('.spinner').click(function() {
  $("#fontSpinner").css("display", "block"); // 显示Spinner

  // 启动定时器每500毫秒检查一次Cookie
  const checkCookieInterval = setInterval(function() {
    const cookies = document.cookie.split(';');
    let isDownloadDone = false;
    // 遍历Cookie查找标记
    for(let cookie of cookies) {
      const [name, value] = cookie.trim().split('=');
      if(name === 'download_complete' && value === 'true') {
        isDownloadDone = true;
        break;
      }
    }

    if(isDownloadDone) {
      // 隐藏Spinner
      $("#fontSpinner").css("display", "none");
      // 清除Cookie
      document.cookie = "download_complete=; path=/; max-age=0";
      // 停止轮询
      clearInterval(checkCookieInterval);
    }
  }, 500);
});

注意事项

  • 方案一中,要确保表单的所有参数都通过$("form").serialize()正确传递,否则可能导致生成的Excel数据不符合预期。
  • 方案二中,Cookie的路径要和你的项目根路径一致,否则前端可能无法获取到Cookie。
  • 两种方案都要处理请求失败的情况,避免Spinner一直停留在页面上。

内容的提问来源于stack exchange,提问作者Saroj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:33:59