目的

采用SpringBoot+MybatisPlus+easyexcel进行操作,主要实现Excel文件导入读取并存储到数据库,及数据库数据导出为Excel数据表。

依赖导入

<!--easyexcel,推荐使用2.0 以上版本,功能更加完善-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.0.5</version>
        </dependency>

Excel表格数据导入

1.定义数据接收模型

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class DeviceExcel {

    @ExcelProperty("设备名称")
    private String deviceName;

    @ExcelProperty("设备编码")
    private String deviceCode;

    @ExcelProperty("设备类型")
    private String deviceType;

    @ExcelProperty("MAC地址")
    private String deviceMac;

    @ExcelProperty("视频地址")
    private String videoUrl;

}

2.制定要导入数据的Excel模板

模板样式 备注:表格的标题名称必须与接收模型的字段注解@ExcelProperty("标题名称")内容保持一致。

3.定义一个数据监听层

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.cdaxxt.business.device.service.IDeviceService;
import lombok.NoArgsConstructor;

import java.util.List;

@NoArgsConstructor
public class DeviceDataListener implements ReadListener<DeviceExcel> {

    /** 每隔100条存储数据库,然后清理list ,方便内存回收 */
    private static final int BATCH_COUNT = 100;

    /** 缓存的数据 */
    private List<DeviceExcel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    private IDeviceService deviceService;

    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param deviceService
     */
    public DeviceDataListener(IDeviceService deviceService) {
        this.deviceService = deviceService;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(DeviceExcel data, AnalysisContext context) {
        cachedDataList.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
		// TODO 需要自己定义接口及实现
        deviceService.saveImportDevice(cachedDataList);
    }

}

4.controller层导入数据表格

@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
   try {
            EasyExcel.read(file.getInputStream(), DeviceExcel.class, new DeviceDataListener(this))
                    .sheet().doRead();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(TipEnum.DATA_SHEET_IMPORT_ERROR);
        }
        return "success";
    }

数据导出为Excel表格

1.创建要导出数据的模型

import com.alibaba.excel.annotation.ExcelProperty;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    public class DeviceExcel {
    
        @ExcelProperty("设备名称")
        private String deviceName;
    
        @ExcelProperty("设备编码")
        private String deviceCode;
    
        @ExcelProperty("设备类型")
        private String deviceType;
    
        @ExcelProperty("MAC地址")
        private String deviceMac;
    
        @ExcelProperty("视频地址")
        private String videoUrl;
    
    }

2.导出数据表格

public void deviceExport(HttpServletResponse response) {
        try {
            //1、设定响应类型
            response.setContentType("application/vnd.ms-excel");
            //2、设定附件的打开方法为:下载,并指定文件名称
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("设备信息表.xlsx", "utf-8"));
            //3、、创建工作簿
            ExcelWriterBuilder writeWork = EasyExcel.write(response.getOutputStream(), DeviceExcel.class);
            //4、创建表格
            ExcelWriterSheetBuilder sheet = writeWork.sheet();
            //5、调用业务层获取数据
            List<DeviceExcel> deviceExcels = this.selectDeviceExcel();
            //6、写入数据到表格中
            sheet.doWrite(deviceExcels);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
	
	private List<DeviceExcel> selectDeviceExcel() {
		// TODO 查询要导出的数据内容
	}

备注:要导出的表格标题在导出的数据模型@ExcelProperty("表格标题")定义。