- 业务场景
- 依赖
- Excel生成工具类
- UUID生成工具类
- service接口及实现类
- controller
- 使用postman进行调试
系统导出数据较多,由前端查询后进行导出下载存在性能问题,故后端进行数据查询后生成excel,前端直接调用导出接口进行下载。考虑到通用性(不同业务场景下导出数据不同),使用反射获取传输数据的pojo属性,并匹配传入参数中需导出字段输出excel文件流。
依赖Excel生成工具类org.apache.poi poi 3.17 org.apache.poi poi-ooxml 3.17
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
@Slf4j
public class ExcelDownloadUtil {
public byte[] excelDownload(List> list, List columns, List columnHeaders) throws Exception {
// 初始化返回字节数组
byte[] fileData = new byte[0];
// 传入参数为空,直接返回空的流
if (list == null || list.size() == 0) {
log.info("传入数据列表为空");
return fileData;
}
if (columns == null || columns.size() == 0) {
log.info("传入展示字段列表为空");
return fileData;
}
if (columnHeaders == null || columnHeaders.size() == 0) {
log.info("传入表头列表为空");
return fileData;
}
// 判断传入展示字段和传入表头列表长度是否相等
if (columns.size() != columnHeaders.size()) {
log.info("传入展示字段和传入表头列表长度不同");
return fileData;
}
long startTime = System.currentTimeMillis();
// 临时文件,保存导出excel
File tempFile = File.createTempFile(UUIDGenerateUtils.generateWithoutLineUUID(), ".xlsx");
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
// 获取数据实体类属性
Class> cls = list.get(0).getClass();
Field[] fields = cls.getDeclaredFields();
// 判断excel展示字段是否在pojo中,取交集
List fieldList = new ArrayList<>();
// map excel展示字段,pojo数据类型
List
UUID生成工具类
import java.util.UUID;
public class UUIDGenerateUtils {
private UUIDGenerateUtils() {
}
public static String generateNormalUUID() {
return UUID.randomUUID().toString();
}
public static String generateWithoutLineUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
}
service接口及实现类
service接口及实现类只是多了一步,使用mapper得到查询数据结果后,调用ExcelDownloadUtil,返回数据类型为byte[]
controller需要在response中设置ContentType,使接口调用后的结果为excel文件
public Response> downloadProjectMatterAreaOrgStatistics(@ApiParam(name = "param name", value = "对结果进行excel导出", type = "json")
@Valid @RequestBody ReqVO reqVO, BindingResult bindingResult, HttpServletResponse response) {
log.info("excel导出接口开始:入参{}", ReqVO);
if (bindingResult.hasErrors()) {
return ValidUtil.validateParam(bindingResult);
}
try {
byte[] fileStream;
fileStream = iXXService.downloadXX(reqVO);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.getOutputStream().write(fileStream);
} catch (IOException e) {
log.error("excel导出失败");
e.printStackTrace();
return null;
}
log.info("excel导出接口结束");
return null;
}
使用postman进行调试
使用send and download功能调试,可直接下载接口返回都excel文件
注意
如使用mybatis-plus分页功能,默认只支持每页导出500条数据,如需导出全部数据,参数"size": -1



