• Excel 导入


    依赖

    1. <dependency>
    2. <groupId>com.alibaba</groupId>
    3. <artifactId>easyexcel</artifactId>
    4. <version>3.1.1</version>
    5. </dependency>

    service 读取excel文件的行数据

    DataExcelListener listener = new DataExcelListener();
    // headRowNumber(1):表示第一行为表头,从第二行取值
    ExcelReader excelReader = EasyExcelFactory.read( file.getInputStream() , DeviceTemplateExcel.class, listener).headRowNumber(1).build();
    excelReader.readAll();
    List data = listener.getDatas();
    excelReader.finish();
    1. @Override
    2. @Transactional(rollbackFor = Exception.class)
    3. public RP importDevice(MultipartFile file, Long productId) throws IOException {
    4. DataExcelListener<DeviceTemplateExcel> listener = new DataExcelListener<DeviceTemplateExcel>();
    5. // headRowNumber(1):表示第一行为表头,从第二行取值
    6. ExcelReader excelReader = EasyExcelFactory.read( file.getInputStream() , DeviceTemplateExcel.class, listener).headRowNumber(1).build();
    7. excelReader.readAll();
    8. List<DeviceTemplateExcel> data = listener.getDatas();
    9. excelReader.finish();
    10. if (data.size() == 3) {
    11. return RP.failure("导入失败,请检查导入文件是否正确");
    12. }
    13. Product product = productService.getById(productId);
    14. if (product == null) {
    15. throw new ServiceException("产品不存在");
    16. }
    17. List<String> deviceSnList = data.stream().map(DeviceTemplateExcel::getDeviceSn).collect(Collectors.toList());
    18. List<Device> repeatList = baseMapper.selectList(Wrappers.<Device>update().lambda().in(Device::getDeviceSn, deviceSnList));
    19. List<Device> deviceList = new ArrayList<>();
    20. //导出失败原因
    21. List<DeviceFailureExportExcel> exportExcels = new ArrayList<>();
    22. for (DeviceTemplateExcel entity : data) {
    23. if (StringUtils.isBlank(entity.getDeviceName()) || StringUtils.isBlank(entity.getDeviceSn())) {
    24. DeviceFailureExportExcel reason = new DeviceFailureExportExcel();
    25. reason.setDeviceName(entity.getDeviceName());
    26. reason.setDeviceSn(entity.getDeviceSn());
    27. reason.setFailureReason(StringUtils.isBlank(entity.getDeviceName()) ? "设备名称不能为空!" : "设备序列号不能为空!");
    28. exportExcels.add(reason);
    29. continue;
    30. }
    31. //数据库中的判重
    32. Optional<Device> deviceOpt = repeatList.stream().filter(item -> item.getDeviceSn().equals(entity.getDeviceSn())).findFirst();
    33. //还未新增的设备判重
    34. Optional<Device> deviceAddOpt = deviceList.stream().filter(item -> item.getDeviceSn().equals(entity.getDeviceSn())).findFirst();
    35. if (deviceOpt.isPresent() || deviceAddOpt.isPresent()) {
    36. DeviceFailureExportExcel reason = new DeviceFailureExportExcel();
    37. reason.setDeviceName(entity.getDeviceName());
    38. reason.setDeviceSn(entity.getDeviceSn());
    39. reason.setFailureReason("设备序列号已存在!");
    40. exportExcels.add(reason);
    41. continue;
    42. }
    43. Device device = new Device();
    44. device.setDeviceName(entity.getDeviceName());
    45. device.setDeviceSn(entity.getDeviceSn());
    46. device.setProductId(productId);
    47. device.setTenantId(AuthUtil.getTenantId());
    48. deviceList.add(device);
    49. }
    50. if (deviceList.size() > 0) {
    51. this.saveBatch(deviceList);
    52. }
    53. if (exportExcels.size() > 0) {
    54. return RP.failure("请重新处理失败的数据!");
    55. } else {
    56. return RP.failure("操作成功");
    57. }
    58. }

    监听类

    1. package com.sinenux.iot.core.exect;
    2. import com.alibaba.excel.context.AnalysisContext;
    3. import com.alibaba.excel.event.AnalysisEventListener;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. /**
    7. * 解析监听器
    8. */
    9. public class DataExcelListener<T> extends AnalysisEventListener<T> {
    10. /**
    11. * 自定义用于暂时存储data
    12. * 可以通过实例获取该值
    13. */
    14. private List<T> datas = new ArrayList<>();
    15. /**
    16. * 每解析一行都会回调invoke()方法
    17. *
    18. * @param object 读取后的数据对象
    19. * @param context 内容
    20. */
    21. @Override
    22. @SuppressWarnings("unchecked")
    23. public void invoke(Object object, AnalysisContext context) {
    24. T data = (T) object;
    25. //数据存储到list,供批量处理,或后续自己业务逻辑处理。
    26. datas.add(data);
    27. }
    28. @Override
    29. public void doAfterAllAnalysed(AnalysisContext context) {
    30. //解析结束销毁不用的资源
    31. //注意不要调用datas.clear(),否则getDatas为null
    32. }
    33. /**
    34. * 返回数据
    35. *
    36. * @return 返回读取的数据集合
    37. **/
    38. public List<T> getDatas() {
    39. return datas;
    40. }
    41. /**
    42. * 设置读取的数据集合
    43. *
    44. * @param datas 设置读取的数据集合
    45. **/
    46. public void setDatas(List<T> datas) {
    47. this.datas = datas;
    48. }
    49. }

    实体类 DeviceTemplateExcel

      注意这里 lombok的@Data注解 和EasyExcel有冲突 不能使用  @Data 要用 get set 方法

    1. package com.sinenux.iot.core.exect;
    2. import com.alibaba.excel.annotation.ExcelProperty;
    3. import java.io.Serializable;
    4. /**
    5. * 设备导入模板
    6. * 注意这里 lombok的@Data注解 和EasyExcel有冲突 不能使用 @Data 要用 get set 方法
    7. *
    8. * @author xulk
    9. */
    10. public class DeviceTemplateExcel implements Serializable {
    11. private static final long serialVersionUID = 1L;
    12. @ExcelProperty(value = "设备名称", index = 0)
    13. private String deviceName;
    14. @ExcelProperty(value = "设备序列号(不可重复)", index = 1)
    15. private String deviceSn;
    16. public String getDeviceName() {
    17. return deviceName;
    18. }
    19. public void setDeviceName(String deviceName) {
    20. this.deviceName = deviceName;
    21. }
    22. public String getDeviceSn() {
    23. return deviceSn;
    24. }
    25. public void setDeviceSn(String deviceSn) {
    26. this.deviceSn = deviceSn;
    27. }
    28. }

  • 相关阅读:
    安卓期末大作业——售票APP源码和设计报告
    Java基础系列(八)——线程池详解
    【算法】山东大学人工智能限选课实验一(八数码问题)
    获取商品评论API 返回值说明
    Linux系统使用(超详细)
    随机过程:马尔科夫过程
    IM即时通讯开发之Android内存泄漏监控
    dart系列之:集合使用最佳实践
    Linux动态Web服务器(Tomcat)
    【buildroot】buildroot使用笔记-01 | 常规使用步骤
  • 原文地址:https://blog.csdn.net/qq_36961226/article/details/139298688