第一步,引入EasyExcel坐标
<!-- easyexcel 这里我使用的是2.1.6稳定版本 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
第一个功能,编写导入excel到数据库接口代码
1.实体类,主要使用@ExcelProperty注解,推荐使用name属性,直接名称匹配
package com.xx.devicemanagement.lighting.domain;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 照明设备管理对象 device_lighting
*
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@ApiModel("照明设备管理实体类")
public class DeviceLighting implements Serializable {
private static final long serialVersionUID=1L;
@ExcelIgnore
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "id")
/** id */
private String id;
/** 设备编号 */
@ExcelProperty(value = "设备编号")
@ApiModelProperty(value = "设备编号")
private String equipmentNumber;
/** 设备名称 */
@ExcelProperty(value = "设备名称")
@ApiModelProperty(value = "设备名称")
private String equipmentName;
/** 铭牌码 */
@ExcelProperty(value = "铭牌码")
@ApiModelProperty(value = "铭牌码")
private String pmCode;
/** 设备终端 */
@ExcelProperty(value = "设备终端")
@ApiModelProperty(value = "设备终端")
private String lightingType;
/** 照明数量 */
@ExcelProperty(value = "照明数量")
@ApiModelProperty(value = "照明数量")
private Long lightingNumber;
/** 场景ID */
@ExcelProperty(value = "场景ID")
@ApiModelProperty(value = "场景ID")
private String sceneId;
/** 创建时间 */
@ExcelIgnore
private Date createTime;
/** 更新时间 */
@ExcelIgnore
private Date updateTime;
/** 创建人 */
@ExcelIgnore
private String createBy;
/** 更新人 */
@ExcelIgnore
private String updateBy;
/** 楼栋字典值(1:综合楼,2:病房楼...) */
@ExcelProperty(value = "楼栋")
@ApiModelProperty(value = "楼栋字典值")
private String buildingCode;
/** 楼层字典值(1:1F,2:2F,3:3F,4:4F.....) */
@ExcelProperty(value = "楼层")
@ApiModelProperty(value = "楼层字典值(1:1F,2:2F,3:3F,4:4F.....)")
private String floorCode;
/** 区域字典值(1:A区域,2:B区域,3:C区域........) */
@ExcelProperty(value = "区域")
@ApiModelProperty(value = "区域字典值(1:A区域,2:B区域,3:C区域........)")
private String regionCode;
/**
* 开始时间
*/
@ApiModelProperty(value = "开始时间")
@TableField(exist = false)
@ExcelIgnore
private Date startTime;
/**
* 结束时间
*/
@ApiModelProperty(value = "结束时间")
@TableField(exist = false)
@ExcelIgnore
private Date endTime;
/**
* 当前页
*/
@ApiModelProperty(value = "当前页")
@TableField(exist = false)
@ExcelIgnore
private Integer pageNum;
/**
* 每页显示条数
*/
@ApiModelProperty(value = "每页显示条数")
@TableField(exist = false)
@ExcelIgnore
private Integer pageSize;
}
2.接口层:
/**
* 导入照明设备管理的excel列表
*/
@ApiOperation("导入照明设备管理的excle列表")
@PostMapping("/uploadExcel")
public void uploadExcel(MultipartFile file) {
EasyExcelUtils<DeviceLighting> easyExcelUtils = new EasyExcelUtils<>();
easyExcelUtils.importExcel(file, DeviceLighting.class, new DeviceLightingListeners(deviceLightingService));
}
3.监听器(easyexcel是在监听器层完成excel数据读取):
package com.xx.devicemanagement.lighting.listeners;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.xr.devicemanagement.lighting.domain.DeviceLighting;
import com.xr.devicemanagement.lighting.service.IDeviceLightingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* 照明设备管理Controller
*/
public class DeviceLightingListeners extends AnalysisEventListener<DeviceLighting> {
private static final Logger logger =
LoggerFactory.getLogger(DeviceLightingListeners.class);
/**
* 每隔200条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 200;
List<DeviceLighting> list = new ArrayList<>();
/**
* 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
*/
private IDeviceLightingService deviceLightingService;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*/
public DeviceLightingListeners(IDeviceLightingService deviceLightingService) {
this.deviceLightingService = deviceLightingService;
}
/**
* 这个每一条数据解析都会来调用
*/
@Override
public void invoke(DeviceLighting deviceLighting, AnalysisContext analysisContext) {
logger.info("invoke方法被调用");
logger.info("解析到一条数据:{}", JSON.toJSONString(deviceLighting));
list.add(deviceLighting);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
list.clear();
}
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("doAfterAllAnalysed方法 被调用");
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
logger.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
logger.info("{}条数据,开始存储数据库!", list.size());
deviceLightingService.saveList(list);
logger.info("存储数据库成功!");
}
}
4.service接口层:
/**
* 批量插入excel文件的内容
* @param list
* @return
*/
public int saveList(List<DeviceLighting> list);
5.service接口实现:
/**
* excel导入
*
* @param list
* @return
*/
@Override
public int saveList(List<DeviceLighting> list) {
deviceLightingMapper.saveList(list);
}
return 0;
}
6.数据库mapper接口和sql实现:
//接口方法定义
/**
* 导入excel
* @param list
* @return
*/
public int saveList(List<DeviceLighting> list);
//mybatis的xmlsql实现
<insert id="saveList">
insert into device_lighting values
<foreach item="item" index="index" collection="list" separator=",">
( #{item.id}, #{item.equipmentNumber}, #{item.equipmentName}, #{item.pmCode}, #{item.lightingType}, #{item.lightingNumber}, #{item.sceneId}, #{item.createTime}, #{item.updateTime}, #{item.createBy}, #{item.updateBy}, #{item.buildingCode}, #{item.floorCode}, #{item.regionCode})
</foreach>
</insert>