业务背景
系统中存在大量的统计业务。统计查询条件基本都是根据时间和多个条件的组合进行分页查询,并返回查询结果 统计导出功能导出的是符合条件的所有数据,不仅是当前页面展示的分页数据,所以导出功能需放在服务端完成 统计业务较多,统计结果返回数据没有添加对应的视图类,而是直接返回的map数组序列化成的json 返回的excel数据,除了字段相关的header,header行之前还有一些特殊说明,直接调用excel的api写excel的头会比较麻烦
集成easyexcel
pom中添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
实现无存储下载
思路
- 统计结果随时间的变化较大,先在服务端生成excel,作为缓存再导出意义不是太大,所以选择直接用easyexcel的API生成文件流写出去,而不在服务端存储
- 考虑到每个excel的文件头会有些特殊情况,并且没有添加对应的类来映射excel的行,所以直接采用模板的方式,准备好excel头的模板
- 在springboot项目的resources目录下,新建excel_template目录,将模板放到该目录下
- easyexcel读取模板有三种方式,一个是文件路径,一个是文件,一个是输入流。web项目打成jar包后文件目录和在idea里面开发的文件目录会发生变化,用路径或是文件的方式来作为参数要做不少的处理,试了几种都没有成功,最后采用输入流的方式来做处理
- 用输入流作为模板参数,要注意模板文件名的后缀需要为xlsx,不是xls,不然会报错
实现
package com.wind.test_web.common.commonUtil;
import com.alibaba.excel.EasyExcel;
import org.springframework.core.io.ClassPathResource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
public class ExcelUtil {
private static final String EXCEL_TEMPLATE_DIR = "excel_template/";;
public static void noModelDownloadWithTemplate(
HttpServletResponse response,
String fileName,
List<List<Object>> data) throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName);
EasyExcel.write(response.getOutputStream())
.needHead(Boolean.FALSE)
.withTemplate(getExcelTemplateInputStream(fileName))
.sheet()
.doWrite(data);
}
public static InputStream getExcelTemplateInputStream(String templateName) throws IOException {
return new ClassPathResource(EXCEL_TEMPLATE_DIR + templateName).getInputStream();
}
}
参考 官方文档
|