之前也做过关于Excel的导出案例,此次也是在其基础上进行改造升级:
https://www.bilibili.com/video/BV1kf4y1i761?p=5
但是之前的导出存在这么几个问题:
今天使用异步导出来解决上述问题。
从上面的图中可以看出,整个下载是异步的,用户不需要在页面等待,每次导出我们都生成一个记录和一个文件,用户可以多次下载。
/**
* Excel列表数据
*
* @author 小道仙97
* @date 2021/8/8
*/
public class ExcelList {
/**
* id
*/
private String id;
/**
* 文件名
*/
private String name;
/**
* 下载行数
*/
private Integer rows;
/**
* 下载耗时
*/
private Long takeUpTime;
/**
* 下载地址
*/
private String downloadUrl;
}
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* Excel导出
*
* @author 小道仙97
* @date 2021-08-08
*/
@RestController
public class ExportExcelController {
@Autowired
private ExportExcel exportExcel;
// 模仿下载列表
public static List<ExcelList> list = new ArrayList<>(10);
/**
* Excel 导出
* @throws Exception
*/
@GetMapping("/excel/export")
public void export() {
Long startTime = System.currentTimeMillis();
String name = "Excel异步导出测试" + UUID.randomUUID().toString() + ".xlsx";
String id = UUID.randomUUID().toString();
ExcelList excelList = new ExcelList();
excelList.setId(id);
excelList.setName(name);
list.add(excelList);
// 异步导出
exportExcel.asyncExportExcel(id,name,startTime);
}
/**
* 获取导出列表 - 模拟
*/
@GetMapping("/excel/list")
public List<ExcelList> list() {
return list;
}
/**
* 文件下载
*/
@GetMapping("/excel/downLoad")
public void downLoad(HttpServletResponse response,@RequestParam String url) {
FileUtils.download(url, response);
}
}
ExportExcel
注:使用异步注解@Async
需要先在启动类上开启 @EnableAsync
import org.springframework.scheduling.annotation.Async;
public interface ExportExcel {
/**
* 异步导出
* @param id 唯一记录Id
* @param name 文件名称
* @param startTime 下载开始时间
*/
@Async
void asyncExportExcel(String id,String name,Long startTime);
}
TestExportExcelImpl
@Service
public class TestExportExcelImpl implements ExportExcel {
@Override
public void asyncExportExcel(String id,String name,Long startTime) {
// 模拟查询数据过程
String[] header = new String[]{"姓名","年纪"};
String[] keys = new String[]{"name","age"};
List<Map<String, Object>> content = new ArrayList<>();
Map<String, Object> map1 = new HashMap<>();
map1.put("name","小道仙");
map1.put("age","23");
content.add(map1);
Map<String, Object> map2 = new HashMap<>();
map2.put("name","小道仙97");
map2.put("age","97");
content.add(map2);
try {
// 获取Excel导出文件流
ByteArrayOutputStream os = new ByteArrayOutputStream();
ExcelUtils.exportExcel(header,keys,content,"first",os);
byte[] content1 = os.toByteArray();
InputStream inputStream = new ByteArrayInputStream(content1);
// 上传文件 返回下载地址
String url = FileUtils.uploadInputStream(inputStream, name);
/**
* 找到当前数据并封装结果集
*
* 其实这里很简单并无这么复杂,实际情况我们只需要一个 update 语句就可以搞定
*/
for (ExcelList item : ExportExcelController.list) {
if (item.getId().equals(id)) {
item.setRows(content.size());
item.setDownloadUrl(url);
item.setTakeUpTime(System.currentTimeMillis() - startTime);
break;
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
下面的演示的前提都是在启动了项目的基础上
因为没有做任何的返回值,所以是空返回,这里也可以自定义任何提示返回。
http://127.0.0.1:8888/excel/export
http://127.0.0.1:8888/excel/list
返回结果如下:
[
{
"id": "d3cb3551-cb33-445e-8e60-9534197f6647",
"name": "Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx",
"rows": 2,
"takeUpTime": 5,
"downloadUrl": "2021/8/8/Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx"
}
]
http://127.0.0.1:8888/excel/downLoad?url=2021/8/8/Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx
视频看讲解地址:https://www.bilibili.com/video/BV1kf4y1i761
关注微信公众号回复:xdxFrameSimple 获取源码。