网站自动采集指标,网站设计策划书3000字,在哪个网站注册域名,自己做的网站绑定域名需求#xff1a;页面点击导出#xff0c;先按照页面条件去数据库查询#xff0c;然后将查询到的数据导出。
问题#xff1a;由于查询特别耗时#xff0c;所以点击之后页面会看上去没有反应
方案1#xff1a;就在点击之后在页面增加了一个进度条#xff0c;等待后端查询…需求页面点击导出先按照页面条件去数据库查询然后将查询到的数据导出。
问题由于查询特别耗时所以点击之后页面会看上去没有反应
方案1就在点击之后在页面增加了一个进度条等待后端查询结束之后导出时进度条会显示导出进度导出结束之后进度条会消失。效果如下 方案2点击导出时前端增加一个遮罩层遮罩层中间显示正在下载导出完成后遮罩层消失好处是可以既给用户提示还可以阻止用户再次点击导出按钮。效果如下 注意点后端需要在响应头中设置ContentLength前端需要用这个更新进度
response.setContentLength(excelBytes.length); // 设置Content-Length
方案1进度条
html代码
导 出 下载进度: 0% css:
#progressContainer { width: 100%; background-color: #f3f3f3; border: 1px solid #ccc; border-radius: 5px; } #progressBar { width: 0%; height: 20px; background-color: #4caf50; border-radius: 5px; }
js代码
//进度条 $(‘#export_btn’).on(‘click’, function () { // 获取表单数据并构建FormData对象 var formData $(‘#searchForm’).serializeArray(); var form new FormData();
$.each(formData, function () { form.append(this.name, this.value); });
// 添加额外的参数 form.append(‘publishFrom’, ‘${RequestParameters.type}’);
// 创建XHR对象
var xhr new XMLHttpRequest();
xhr.open(POST, 路径/exportData, true);
xhr.responseType blob; // 设置响应类型为blob// 显示进度条
$(#progressContainer).show();
$(#progressText).show();
$(#progressBar).css(width, 0%);
$(#progressText).text(下载进度: 0%);// 设置请求头以模拟表单提交
// xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded);// 监听下载进度
xhr.onprogress function (event) {if (event.lengthComputable) {var percentComplete Math.round((event.loaded / event.total) \* 100);console.log(Loaded:, event.loaded, Total:, event.total);$(#progressBar).css(width, percentComplete %);$(#progressText).text(下载进度: percentComplete %);} else {console.log(无法计算进度);}
};// 下载完成后处理
xhr.onload function () {if (xhr.status 200) {// 隐藏进度条$(#progressContainer).hide();$(#progressText).hide();// 创建下载链接并触发下载var blob xhr.response;var downloadUrl URL.createObjectURL(blob);var a document.createElement(a);a.href downloadUrl;// 从响应头中获取文件名var disposition xhr.getResponseHeader(Content-Disposition);var fileName 下载文件.xlsx;if (disposition disposition.indexOf(filename\*utf-8) ! -1) {var filenameRegex /filename\*utf-8(.)/;var matches filenameRegex.exec(disposition);if (matches ! null matches\[1\]) {fileName decodeURIComponent(matches\[1\]);}}a.download fileName;document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(downloadUrl);} else {alert(下载失败请重试。);$(#progressContainer).hide();$(#progressText).hide();}
};// 发送请求
xhr.send(form);});
后端代码,使用easyExcel导出
//数据查询 List sellList this.search();
// 将Excel写入ByteArrayOutputStream try (ByteArrayOutputStream baos new ByteArrayOutputStream()) { // 使用EasyExcel将数据写入ByteArrayOutputStream EasyExcel.write(baos, Sell.class) .sheet(“列表”) .doWrite(sellList);
// 获取Excel字节数组
byte\[\] excelBytes baos.toByteArray();// 设置响应头
response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet);
response.setCharacterEncoding(utf-8);
String fileName URLEncoder.encode(列表导出\_Sell, UTF-8).replaceAll(\\, %20);
response.setHeader(Content-Disposition, attachment;filename\*utf-8 fileName .xlsx);
response.setHeader(Cache-Control, max-age0);
response.setContentLength(excelBytes.length); // 设置Content-Length// 将Excel字节数组写入响应
try (OutputStream out response.getOutputStream()) {out.write(excelBytes);out.flush();
}} catch (IOException e) { e.printStackTrace(); }
方案2遮罩层
html代码 正在导出中... css
.loading-mask { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999; display: flex; justify-content: center; align-items: center; }
.loading-content { text-align: center; color: #fff; }
.spinner { border: 8px solid rgba(255, 255, 255, 0.3); border-top: 8px solid #fff; border-radius: 50%; width: 60px; height: 60px; animation: spin 1s linear infinite; margin: 0 auto 20px; }
keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
button:disabled { opacity: 0.6; cursor: not-allowed; }
js代码阻止了有遮罩层时用户仍然可以通过键盘或其他方式触发多次点击
$(document).ready(function () { // 确保DOM加载完成后执行 $(‘#export_btn’).on(‘click’, function (e) { e.preventDefault(); // 阻止默认表单提交行为 var $exportBtn $(this);// 禁用导出按钮防止重复点击$exportBtn.prop(disabled, true);// 显示遮罩层$(#loadingMask).show();// 获取表单数据并构建FormData对象var formData $(#searchForm).serializeArray();var form new FormData();$.each(formData, function () {form.append(this.name, this.value);});// 添加额外的参数form.append(publishFrom, ${RequestParameters.type});// 创建XHR对象var xhr new XMLHttpRequest();xhr.open(POST, 路径/exportData, true);xhr.responseType blob; // 设置响应类型为blob// 监听下载完成后处理xhr.onload function () {$(#loadingMask).hide(); // 隐藏遮罩层$exportBtn.prop(disabled, false); // 启用导出按钮if (xhr.status 200) {// 创建下载链接并触发下载var blob xhr.response;var downloadUrl URL.createObjectURL(blob);var a document.createElement(a);a.href downloadUrl;// 从响应头中获取文件名var disposition xhr.getResponseHeader(Content-Disposition);var fileName 下载文件.xlsx;if (disposition disposition.indexOf(filename\*utf-8) ! -1) { // 修改修正单引号字符var filenameRegex /filename\*utf-8(.)/;var matches filenameRegex.exec(disposition);if (matches ! null matches\[1\]) {fileName decodeURIComponent(matches\[1\]);}}a.download fileName;document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(downloadUrl);} else {alert(下载失败请重试。);}};// 监听网络错误xhr.onerror function () {$(#loadingMask).hide(); // 隐藏遮罩层$exportBtn.prop(disabled, false); // 启用导出按钮alert(网络错误请检查您的连接。);};xhr.send(form);
});});
后端代码和方案1一致