Java实现文件导出过程中的提示功能

Posted Do_GH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实现文件导出过程中的提示功能相关的知识,希望对你有一定的参考价值。

目的

在实现文件导出时,若文件过大导出时间过长,此时就需要有提示框提示用户当前导出的状态,在导出功能结束后有相应的提示。

实现(方案一)

在文件导出的过程中向浏览器添加Cookie,在前端定时检测Cookie状态,若检测到指定的Cookie值,即表示导出完成并关闭定时器。

原理

JavaEE中的Cookie操作

创建Cookie

可以通过Cookie的构造函数直接创建Cookie,例如:

Cookie cookie = new Cookie("CookieName", "CookieValue");

该构造方法包含两个参数,第一个参数为Cookie的名称,Cookie的名称一旦被创建则不允许对其修改,第二个参数为Cookie的值,如果需要修改该值,可以调用Cookie的setValue()方法进行修改。

创建Cookie时可以通过setPath(String url)方法设置该Cookie的存放路径。Cookie对指定目录的所有页面及其目录下的子目录中的页面都是可以访问的。每个Cookie的路径都应符合Servlet的访问路径。

getPath()方法获取Cookie的路径。

修改Cookie

首先可以通过HttpServletRequest类中的Cookie[] getCookies()方法获取所有的Cookie。通过Cookie的名称找到需要修改的Cookie值,再对该Cookie使用setValue(String newValue)方法对该Cookie的值进行修改。示例:

// 获取该请求的所有Cookie
Cookie[] cookies = request.getCookies();

for (int i = 0; i < cookies.length; i++) {
	if ("CookieName".equals(cookies[i].getValue())) {
		cookies[i].setValue("newValue");
	}
}

销毁Cookie

Cookie未提供直接的删除方法,但是可以通过设置Cookie的存活时间来销毁一个Cookie。每一个Cookie都有其对应的存活时间,未单独设置时默认值为-1,当设置存活时间为负数时,该Cookie不能长久储存当浏览器退出时该Cookie会自动销毁。当设置为0时该Cookie则会马上被销毁。示例:

Cookie cookie = new Cookie("CookieName", "CookieValue");
cookie.setMaxAge(0);

response.addCookie(cookie);

发送Cookie

创建好的Cookie可以随HttpServletResponse响应发送回前端页面,可以调取HttpServletResponse的addCookie(Cookie cookie)方法,将Cookie添加到响应中。示例:

Cookie cookie = new Cookie("CookieName", "CookieValue");
cookie.setPath("/");
response.addCookie(cookie);

JS中的Cookie操作

document.cookie

在JS中可以使用document.cookie读取和新增Cookie,它作为Cookie的getter和setter方法。

// 创建Cookie
document.cookie = "key=value;max-age=60*60*1;path=/;";

// 修改Cookie
document.cookie = "key=newValue";

// 销毁Cookie
document.cookie = "key=newValue;expires=" + new Date(0).toUTCString();

在创建或修改Cookie时,可以使用以下的属性对Cookie进行设置。

  • path=path:设置Cookie的访问路径
  • max-age=max-age-in-seconds:设置Cookie的存活时间
  • expires=date-in-GMTString-format:设置Cookie到期时间,指定确切的时间节点。

前端的Cookie同后台一样,没有直接删除Cookie的方法,也是通过设置存活时间或到期时间来强制销毁Cookie。

处于安全性考虑,每一个Cookie都应设置自己的到期时间。

示例

后台代码(Java)

// 向响应中添加导出内容
response.setContentType("application/vnd.ms-excel");
response.addHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");

OutputStream os = response.getOutputStream();
// 将需要下载的加载到输入流中
FileInputStream is = new FileInputStream();

// 添加Cookie
Cookie cookie = new Cookie("downloadExcelStatus", "finished");
cookie.setPath("/");
response.addCookie(cookie);

// 输出文件
byte[] b = new byte[1024];
int i = 0;

while ((i = is.read(b)) > 0) {
	os.write(b, 0, i);
}

前端JS

// 获取后台设置的Cookie值
var getCookie = function (cookieName) {
	var strCookie = document.cookie;
	var arrCookie = strCookie.split(";");
	for (var i = 0; i < arrCookie.length; i++) {
	    var arr = arrCookie[i].split("=");
	    if (cookieName === arr[0]) {
	        return arr[1];
	    }
	}
}

// 定时检查接口状态
var checkDownloadFlag = function () {
	// 打开提示框
    $("#showLoading").modal("show");

    var downloadFlag = setInterval(function () {
        var token = getCookie("downloadExcelStatus");
        if (token === "finished" && token) {
            clearInterval(downloadFlag);
            $("#showLoading").modal("hide");
            // 当检测到下载完成后销毁Cookie
            document.cookie = "downloadExcelStatus=wait;expires=" + new Date(0).toUTCString() + ";path=/";
        }
    }, 5000);
}

实现(方案二)

在与后台交互的过程中,使用Ajax的过程只能检测状态码,请求成功后就会调用success方法,而表单提交更加无法检测请求状态。所以想要监测请求的状态,可以使用JS的XMLHttpRequest类的onreadystatechange()方法实时监测请求的状态。

XMLHttpRequest (XHR)对象用于与服务器交互。您可以从URL检索数据,而不必进行整个页面刷新。这使得Web页面可以只更新页面的一部分,而不会干扰用户正在进行的操作。

AJAX编程中大量使用XMLHttpRequest。

AJAX相关操作

原理

XMLHttpRequest.send()

该方法用于将请求发送给服务端。如果请求类型为POST可以在send()方法中添加需要发送给后台的参数信息。send()方法的参数支持BLOBdocumentFormDataStringURLSearchParamsBufferSource等类型的数据。示例:

// 创建FormData类型数据并向其添加参数
var formData = new FormData();
formData.append("key", "value");

var xmlHttp = new XMLHttpRequest();

xmlHttp.open("post", url, true);
xmlHttp.send(formData);

XMLHttpRequest.onreadystatechange

每当readyState属性更改时调用的事件处理程序。从用户界面线程调用回调。XMLHttpRequest.onreadystatechange属性包含了当readystatechange事件被触发时要调用的事件处理程序,也就是每次XMLHttpRequest的readyState属性改变时。

该方法不能用于同步请求

当监测到请求响应状态为4时,则表示该请求已被处理完毕并前端已接收到响应文本。示例:

var xhr = new XMLHttpRequest();

xhr.open("GET", url, true);
xhr.send();

xhr.onreadstatechange = function() {
	if(xhr.readyStatus === XMLHttpRequest.DONE && xhr.status === 200) {
		console.log(xhr.requestText());
	}
}

XMLHttpRequest.responseType

XMLHttpRequest属性responseType是一个枚举字符串值,指定响应中包含的数据类型。

该属性可以设置响应返回的数据类型,可以将其设置为arraybufferblobdocumentjsontextms-stream等类型,若设置为空则与text类型相同,响应结果以text形式返回。

若想要以文件形式返回可以将响应类型设置为BLOB。示例:

var xhr = new XMLHttpRequest();

xhr.open("GET", url, true);
xhr.responseText("BLOB");
xhr.send();

escape()

escape()函数的作用是:计算一个新字符串,其中某些字符已被十六进制转义序列替换。

由于服务端向前端传递的参数都为ISO_8859_1,所以前端直接获取响应头时中文字符会直接乱码,可以通过escape()将其转换为unicode。

该方法不会转义特殊字符

decodeURIComponent()

decodeuriccomponent()函数对以前由encodeuriccomponent或类似例程创建的统一资源标识符(URI)组件进行解码。

利用该方法可将后台传递的响应头进行解析,避免中文乱码。

示例

// 打开导出提示框
$("#showLoading").modal("show");

var xmlHttp;
if (window.XMLHttpRequest) {
	xmlHttp = new XMLHttpRequest();
} else {
	xmlHttp = new ActiveXObject("Microsolf.XMLHTTP");
}

// 添加请求参数
var formData = new FormData();
formData.appent("key", "value");

xmlHttp.open("post", url, true);

// 设置响应数据类型
xmlHttp.responseType = "blob";
xmlHttp.send(formData);
xmlHttp.onreadystatechange = function () {
	console.log(xmlHttp.status);
	console.log(xmlHttp.readyState);
	if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
		// 从后台返回的响应头中获取文件名
		var name = decodeURIComponent(escape(xmlHttp.getResponseHeader("Content-disposition")));
		// 截取响应头获取文件名
		var fileName = name.substring(21, name.length);

		// 将响应文件转换为BLOB二进制流
		var blob = new Blob([this.response], {type: "application/vnd.ms-excel"});

		// 创建服务器连接,通过点击下载文件
		var fileUrl = URL.createObjectURL(blob);
		var link = document.createElement("a");
		link.href = fileUrl;
		link.download = fileName;
		link.click();

		// 关闭提示框
		$("#showLoading").modal("hide");
	}
}

以上是关于Java实现文件导出过程中的提示功能的主要内容,如果未能解决你的问题,请参考以下文章

Freemarker + xml 实现Java导出word

ASP.net MVC 代码片段问题中的 Jqgrid 实现

[搬运] 将 Visual Studio 的代码片段导出到 VS Code

java怎么实现导出数据后放到word文档中,并且可以保存到本硬盘上(类似于百度文库里面的下载功能)

jsp编写网站中,如何将数据库中的表导出到txt或者word,excel

小程序各种功能代码片段整理---持续更新