关于 EasyExcel 导出下载文件需要知道的那些事
Part 1. 前言
好记性不如烂笔头,本着自己已经在开发过程中花费了大把时间去检索“为什么不行”以及“该怎么办”的检索过程,故在这里进行整理和归纳,也将所参考的文章罗列在Part 0
中,部分解决方式也经过了校验,方便大家在遇到相同问题时可以方便在茫茫的 cv 博客中找到真正能解决问题的好文(滑稽.jpg
讲讲我为什么会遇到这个问题,首先业务测使用的文件下载工具采用的是 EasyExcel
,这里放上 EasyExcel
的文档方便大家检索使用,我采用的是最简单的写的方式,需要明确一点,写 excel 和 web 端下载 excel 的区别:
Part 2. EasyExcel 写文件
在最简单的写 excel 中,EasyExcel
所需要的条件即文件名/文件路径、表头数据、sheet 名以及写入的数据,以官网示例为例如下:
// WriteTest.java
EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
private List<DemoData> data() {
List<DemoData> list = new ArrayList<DemoData>();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setString("字符串" + i);
data.setDate(new Date());
data.setDoubleData(0.56);
list.add(data);
}
return list;
}
// DemoData.java
import lombok.Data;
@Data
public class DemoData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
}
需要注意的是,这里说的是文件名或文件路径,当 fileName
具体到文件路径时,excel 文件写后即写在该路径下,若 fileName
为文件名时,会写在该项目的根目录下
以上两种方式的写 excel ,都并不是 web 端下载的方式(即浏览器下载文件的形式)来得到的,这是我最开始误会的地方
Part 3. EasyExcel web 端写文件
在实现 web 端的写文件之前,这里需要先明确一下自己 web 页面写文件的方式是哪一种,我这里的业务采用的是 jQuery
的 Ajax 的 Post
请求方式,过程里访问接口一直都能够正常访问,但就是没有执行 web 端的文件下载,接口返回的尽是些乱码,于是我就踏上了不断检索的道路,很庆幸检索到和我遇到相同问题的道友,并进一步验证了他的说法,下面就来谈谈为什么可以访问接口但是返回乱码且不执行 web 端下载的问题:
首先 jQuery
所封装的 ajax 它所能接收的数据类型需要明确一下,从下图文档中可以看到,dataType
在预期的接受类型中,并不包含有二进制流数据 blob
,所以直接通过 $.ajax
的方式是无法满足预期需求
网上有提供通过更新 xhr
的方式改变 $.ajax
的 responseType
的解决方案,我验证了下似乎没有预期效果,因为不接受 blob 类型直接进 error
的回调函数中,报错信息如下:
DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's '' is '' or 'text' (was 'blob').
这边也就不再多余的赘述,如果有成功的验证,欢迎留言指正我的误解,谢谢大家,下面介绍能够正常使用的两种方式
-
通过
form
表单的形式进行提交var url = 'xxxxxxxxxxxx'; var form = document.createElement('form'); var xxx = document.createElement('input'); form.setAttribute('style', 'display:none'); form.setAttribute('target', ''); form.setAttribute('method', 'post'); form.setAttribute('action', url); xxx.type = 'hidden'; xxx.name = 'xxx'; xxx.value = param ? param : ''; form.appendChild(xxx); // ... document.body.appendChild(form); form.appendChild(xxx); // ... form.submit(); form.remove();
-
通过原生
js
实现ajax
的方式,即原生的XMLHttpRequest
对象发出HTTP
请求,对接收的数据先进行createObjectURL
的包装,再通过以<a>
标签下载链接的方式触发 web 端下载该文件var params = {xxx:xxx}; var url = 'xxxxxxxxxxxx'; var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); // 也可以使用POST方式,根据接口 xhr.responseType = 'blob'; // 返回类型blob xhr.onload = function () { if (this.status === 200) { var blob = this.response; const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = 'xxx.xlsx'; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); } }; // 发送ajax请求 xhr.send(params);
Part 0. Reference
- EasyExcel 使用说明 - 如何使用 EasyExcel
- web页面实现文件下载的几种方法 - 阐述 web 端文件下载方式
- EasyExcel实现下载Excel(解决无法从浏览器下载问题) - jQuery 的 ajax 无法接收二进制流
- Handle file download from ajax post
- Receiving binary data using JavaScript typed arrays - 二进制文件流
- jQuery.ajax() API 文档 - ajax API 文档
- 关于javascript:使用jQuery的ajax方法将图片检索为blob
- AJAX 之 XHR, jQuery, Fetch 的对比