1. 基本依赖
<!-- EasyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
2. 创建相对应的 Util 工具类
(1)EasyExcel 读写工具类
package com.bfy.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.handler.WriteHandler;
import com.bfy.entity.Score;
import com.bfy.entity.building.ImportBuilding;
import org.apache.poi.ss.formula.functions.T;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author jwhappy
* @date 2020/4/22
*/
public class EasyExcelUtil {
private EasyExcelUtil() {
}
/**
* 同步无模型读(默认读取sheet0,从第2行开始读)
*
* @param filePath
* @return
*/
public static List<Map<Integer, String>> syncRead(String filePath) {
return EasyExcelFactory.read(filePath).sheet().doReadSync();
}
/**
* 同步无模型读(默认表头占一行,从第2行开始读)
*
* @param filePath
* @param sheetNo sheet页号,从0开始
* @return
*/
public static List<Map<Integer, String>> syncRead(String filePath, Integer sheetNo) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).doReadSync();
}
/**
* 同步无模型读(指定sheet和表头占的行数)
*
* @param inputStream
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return List<Map < colNum, cellValue>>
*/
public static List<Map<Integer, String>> syncRead(InputStream inputStream, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
}
/**
* 同步无模型读(指定sheet和表头占的行数)
*
* @param file
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return List<Map < colNum, cellValue>>
*/
public static List<Map<Integer, String>> syncRead(File file, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
}
/**
* 同步无模型读(指定sheet和表头占的行数)
*
* @param filePath
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return List<Map < colNum, cellValue>>
*/
public static List<Map<Integer, String>> syncRead(String filePath, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).doReadSync();
}
/**
* 同步按模型读(默认读取sheet0,从第2行开始读)
*
* @param filePath
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @return
*/
public static List<T> syncReadModel(String filePath, Class clazz) {
return EasyExcelFactory.read(filePath).sheet().head(clazz).doReadSync();
}
/**
* 同步按模型读(默认读取sheet0,从第2行开始读)
*
* @param inputStream
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @return
*/
public static List<T> syncReadModel(InputStream inputStream, Class clazz) {
return EasyExcelFactory.read(inputStream).sheet().head(clazz).doReadSync();
}
/**
* 同步按模型读(默认表头占一行,从第2行开始读)
*
* @param filePath
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @return
*/
public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).head(clazz).doReadSync();
}
/**
* 同步按模型读(指定sheet和表头占的行数)
*
* @param inputStream
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static List<T> syncReadModel(InputStream inputStream, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
/**
* 同步按模型读(指定sheet和表头占的行数)
*
* @param file
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static List<T> syncReadModel(File file, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
/**
* 同步按模型读(指定sheet和表头占的行数)
*
* @param filePath
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
/**
* 异步无模型读(默认读取sheet0,从第2行开始读)
*
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param filePath 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener) {
EasyExcelFactory.read(filePath, excelListener).sheet().doRead();
}
/**
* 异步无模型读(默认表头占一行,从第2行开始读)
*
* @param filePath 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param sheetNo sheet页号,从0开始
* @return
*/
public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener, Integer sheetNo) {
EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).doRead();
}
/**
* 异步无模型读(指定sheet和表头占的行数)
*
* @param inputStream
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static void asyncRead(InputStream inputStream, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(inputStream, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 异步无模型读(指定sheet和表头占的行数)
*
* @param file
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static void asyncRead(File file, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(file, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 异步无模型读(指定sheet和表头占的行数)
*
* @param filePath
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
* @return
*/
public static void asyncRead(String filePath, AnalysisEventListener<T> excelListener, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(filePath, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 异步按模型读取(默认读取sheet0,从第2行开始读)
*
* @param filePath
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
*/
public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz) {
EasyExcelFactory.read(filePath, clazz, excelListener).sheet().doRead();
}
/**
* 异步按模型读取(默认表头占一行,从第2行开始读)
*
* @param filePath
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
*/
public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo) {
EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).doRead();
}
/**
* 异步按模型读取
*
* @param inputStream
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
*/
public static void asyncReadModel(InputStream inputStream, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(inputStream, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 异步按模型读取
*
* @param file
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
*/
public static void asyncReadModel(File file, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(file, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 异步按模型读取
*
* @param filePath
* @param excelListener 监听器,在监听器中可以处理行数据LinkedHashMap,表头数据,异常处理等
* @param clazz 模型的类类型(excel数据会按该类型转换成对象)
* @param sheetNo sheet页号,从0开始
* @param headRowNum 表头占的行数,从0开始(如果要连表头一起读出来则传0)
*/
public static void asyncReadModel(String filePath, AnalysisEventListener<T> excelListener, Class clazz, Integer sheetNo, Integer headRowNum) {
EasyExcelFactory.read(filePath, clazz, excelListener).sheet(sheetNo).headRowNumber(headRowNum).doRead();
}
/**
* 无模板写文件
*
* @param filePath
* @param head 表头数据
* @param data 表内容数据
*/
public static void write(String filePath, List<List<String>> head, List<List<Object>> data) {
EasyExcel.write(filePath).head(head).sheet().doWrite(data);
}
/**
* 无模板写文件
*
* @param filePath
* @param head 表头数据
* @param data 表内容数据
* @param sheetNo sheet页号,从0开始
* @param sheetName sheet名称
*/
public static void write(String filePath, List<List<String>> head, List<List<Object>> data, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath).head(head).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 根据excel模板文件写入文件
*
* @param filePath
* @param templateFileName
* @param headClazz
* @param data
*/
public static void writeTemplate(String filePath, String templateFileName, Class headClazz, List data) {
EasyExcel.write(filePath, headClazz).withTemplate(templateFileName).sheet().doWrite(data);
}
/**
* 根据excel模板文件写入文件
*
* @param filePath
* @param templateFileName
* @param data
*/
public static void writeTemplate(String filePath, String templateFileName, List data) {
EasyExcel.write(filePath).withTemplate(templateFileName).sheet().doWrite(data);
}
/**
* 按模板写文件
*
* @param filePath
* @param headClazz 表头模板
* @param data 数据
*/
public static void write(String filePath, Class headClazz, List data) {
EasyExcel.write(filePath, headClazz).sheet().doWrite(data);
}
/**
* 按模板写文件
*
* @param filePath
* @param headClazz 表头模板
* @param data 数据
* @param sheetNo sheet页号,从0开始
* @param sheetName sheet名称
*/
public static void write(String filePath, Class headClazz, List data, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 按模板写文件
*
* @param filePath
* @param headClazz 表头模板
* @param data 数据
* @param writeHandler 自定义的处理器,比如设置table样式,设置超链接、单元格下拉框等等功能都可以通过这个实现(需要注册多个则自己通过链式去调用)
* @param sheetNo sheet页号,从0开始
* @param sheetName sheet名称
*/
public static void write(String filePath, Class headClazz, List data, WriteHandler writeHandler, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).registerWriteHandler(writeHandler).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 按模板写文件(包含某些字段)
*
* @param filePath
* @param headClazz 表头模板
* @param data 数据
* @param includeCols 过滤包含的字段,根据字段名称过滤
* @param sheetNo sheet页号,从0开始
* @param sheetName sheet名称
*/
public static void writeInclude(String filePath, Class headClazz, List data, Set<String> includeCols, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).includeColumnFiledNames(includeCols).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 按模板写文件(排除某些字段)
*
* @param filePath
* @param headClazz 表头模板
* @param data 数据
* @param excludeCols 过滤排除的字段,根据字段名称过滤
* @param sheetNo sheet页号,从0开始
* @param sheetName sheet名称
*/
public static void writeExclude(String filePath, Class headClazz, List data, Set<String> excludeCols, Integer sheetNo, String sheetName) {
EasyExcel.write(filePath, headClazz).excludeColumnFiledNames(excludeCols).sheet(sheetNo, sheetName).doWrite(data);
}
/**
* 多个sheet页的数据链式写入
* ExcelUtil.writeWithSheets(outputStream)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param outputStream
* @return
*/
public static EasyExcelWriterFactory writeWithSheets(OutputStream outputStream) {
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(outputStream);
return excelWriter;
}
/**
* 多个sheet页的数据链式写入
* ExcelUtil.writeWithSheets(file)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param file
* @return
*/
public static EasyExcelWriterFactory writeWithSheets(File file) {
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(file);
return excelWriter;
}
/**
* 多个sheet页的数据链式写入
* ExcelUtil.writeWithSheets(filePath)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param filePath
* @return
*/
public static EasyExcelWriterFactory writeWithSheets(String filePath) {
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(filePath);
return excelWriter;
}
/**
* 多个sheet页的数据链式写入(失败了会返回一个有部分数据的Excel)
* ExcelUtil.writeWithSheets(response, exportFileName)
* .writeModel(ExcelModel.class, excelModelList, "sheetName1")
* .write(headData, data,"sheetName2")
* .finish();
*
* @param response
* @param exportFileName 导出的文件名称
* @return
*/
public static EasyExcelWriterFactory writeWithSheetsWeb(HttpServletResponse response, String exportFileName) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
String fileName = URLEncoder.encode(exportFileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcelWriterFactory excelWriter = new EasyExcelWriterFactory(response.getOutputStream());
return excelWriter;
}
/**
*
* @param inputStream 文件输入流
* @param importBuildingDataListener 导入数据监听器
* @param importBuildingClass 导入数据模型
* @param a 读取的 shett 页
* @param b 表头占的行数
*/
public static void asyncReadModel(InputStream inputStream, ImportBuildingDataListener importBuildingDataListener, Class<ImportBuilding> importBuildingClass, Integer a, Integer b) {
EasyExcelFactory.read(inputStream, importBuildingClass, importBuildingDataListener).sheet(a).headRowNumber(b).doRead();
}
}
(2)导入数据监听器
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.bfy.dao.building.BuildingDao;
import com.bfy.entity.building.Building;
import com.bfy.entity.building.ImportBuilding;
import com.bfy.services.building.buildingImpl.BuildingServiceImpl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ImportBuildingDataListener extends AnalysisEventListener<ImportBuilding> {
//要添加的源数据
private List<ImportBuilding> impScorelist = new ArrayList<ImportBuilding>();
//校验合法的数据
private List<ImportBuilding> impVaildScoreList = new ArrayList<ImportBuilding>();
//学校id
private Long schoolId;
//校验异常的集合
private List<String> impErrorScoreList = new ArrayList<String>();
//用于校验楼房名称的集合
private Map<String, Long> buildingNameIdMap = new HashMap<String, Long>();
private RedisUtil redisUtil;
//返回值的Key
private String redisDataUUID = null;
public ImportBuildingDataListener() {
}
/**
* 每次创建Listener的时候需要把spring管理的类传进来
*/
public ImportBuildingDataListener(String redisDataUUID, RedisUtil redisUtil, BuildingDao buildingDao, Long schoolId) {
this.schoolId = schoolId;
this.redisUtil = redisUtil;
this.redisDataUUID = redisDataUUID;
List<Building> buildingDtoList = buildingDao.queryBuildingNameBySchoolId(schoolId);
for (Building building : buildingDtoList) {
buildingNameIdMap.put(building.getBuildingName(),building.getBuildingId());
}
}
@Override
public void invoke(ImportBuilding t, AnalysisContext analysisContext) {
impScorelist.add(t);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
for(int i = 0;i<impScorelist.size();i++){
//判断导入文件中的班级是否存在
if (impScorelist.get(i).getBuildingName() == null || buildingNameIdMap.containsKey(impScorelist.get(i).getBuildingName())) {
impErrorScoreList.add("第"+(i+1)+"行该楼房名称已存在");
continue;
}
impScorelist.get(i).setSchoolId(this.schoolId);
impVaildScoreList.add(impScorelist.get(i));
}
//注意此处使用了lambda语法,java8以上支持
InsertConsumer.insertData(impVaildScoreList,ImportBuildingDataListener::add);
Map redisMap = new HashMap<>();
redisMap.put("successData",impVaildScoreList.size());
redisMap.put("failData",impErrorScoreList);
redisUtil.hmset(this.redisDataUUID,redisMap);
//清理集合中元素,释放内存
impErrorScoreList.clear();
impVaildScoreList.clear();
impScorelist.clear();
buildingNameIdMap.clear();
}
//由于是静态方法,要借用应用上下文工具类获取到相对应的Dao或Servie才能跨越调用方法
private static void add(List<ImportBuilding> list){
ApplicationContextUtil.getApplicationContext().getBean(BuildingServiceImpl.class).insertList(list);
}
}
(3)并行流快速插入数据类
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* 功能:利用并行流快速插入数据
*
* @author Keats
* @date 2020/7/1 9:25
*/
public class InsertConsumer {
/**
* 每个长 SQL 插入的行数,可以根据数据库性能调整
*/
private final static int SIZE = 1000;
/**
* 如果需要调整并发数目,修改下面方法的第二个参数即可
*/
static {
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "4");
}
/**
* 插入方法
*
* @param list 插入数据集合
* @param consumer 消费型方法,直接使用 dao::method 方法引用的方式
* @param <T> 插入的数据类型
*/
public static <T> void insertData(List<T> list,Consumer<List<T>> consumer) {
if (list == null || list.size() < 1) {
return;
}
List<List<T>> streamList = new ArrayList<>();
for (int i = 0; i < list.size(); i += SIZE) {
int j = Math.min((i + SIZE), list.size());
List<T> subList = list.subList(i, j);
streamList.add(subList);
}
// 并行流使用的并发数是 CPU 核心数,不能局部更改。全局更改影响较大,斟酌
streamList.parallelStream().forEach(consumer);
}
}
(4)ApplicationContextUtil
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class ApplicationContextUtil {
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext ac)
throws BeansException {
applicationContext = ac;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 根据Class类型在IOC容器中获取对象
* @param clazz Class类型
* @return 对象
*/
public static <T> List<T> getBeanByType(Class<T> clazz) {
List<T> list = new ArrayList<T>();
/* 获取接口的所有实例名 */
String[] beanNames = applicationContext.getBeanNamesForType(clazz);
log.debug("getBeanByType beanNames : " + beanNames == null ? "" : Arrays.toString(beanNames));
if (beanNames == null || beanNames.length == 0) {
return list;
}
T t = null;
for (String beanName : beanNames) {
t = (T)applicationContext.getBean(beanName);
list.add(t);
}
return list;
}
}
(5)在主启动类中赋值 ApplicationContext 到工具类中
public static void main(String[] args) {
ApplicationContext app = SpringApplication.run(SchoolServerApplication.class, args);
//用于构建应用上下文工具类,以方便在静态方法中调用被SpringIOC容器类管理的类的方法如:在EasyExcel监听器类中的静态方法调用Dao方法或Service方法
ApplicationContextUtil.setApplicationContext(app);
}
3. Controller 层调用
(1)导入数据模型类
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ImportBuilding {
// index:读取的例下标
@ExcelProperty(value = "楼房名称",index = 0)
private String buildingName;
@ExcelProperty(value = "楼房类型(男宿舍填0,女宿舍填1)",index = 1)
private Integer buildingType;
@ExcelProperty(value = "楼层数量",index = 2)
private Integer numberOfFloors;
@ExcelProperty(value = "单层房间数量",index = 3)
private Integer numberOfSingle;
@ExcelProperty(value = "单房间床位数量",index = 4)
private Integer numberOfBeds;
private Long schoolId;
private Integer addType;
private Long buildingId;
}
(2)使用方式
@PostMapping("/fileupload")
public Msg fileupload(@RequestParam("file") MultipartFile file, @RequestParam Map<String, String> map) {
try {
Long schoolId = Long.parseLong(map.get("schoolId"));
if (schoolId != null) {
LocalDateTime localDateTime = LocalDateTime.now();//获取本地时间
String random = String.valueOf(Math.random() * (10000));//获取随机数
// 生成唯一标识符,用于存储和删除在Redis中的导入返回结果
String redisDataUUID = EncryptionUtil.getMD5(localDateTime + random);
EasyExcelUtil.asyncReadModel(file.getInputStream(), new ImportBuildingDataListener(redisDataUUID, redisUtil, buildingDao,schoolId), ImportBuilding.class, 0, 1);
// 获取返回值并封装返回对象
Msg res = Msg.success(redisUtil.hmget(redisDataUUID), "录入数据返回值");
// 删除Redis中的返回结果
redisUtil.del(redisDataUUID);
return res;
} else {
return Msg.fail();
}
} catch (Exception e) {
e.printStackTrace();
return Msg.fail();
}
}