java EasyExcel 导入

EasyExcel官网:https://www.yuque.com/easyexcel/doc/easyexcel

一、POM依赖

官网最新版本是3.0.5
在这里插入图片描述
我自己项目中的版本

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.7</version>
</dependency>

二、实现

1、controller

@Transactional
@PreAuthorize(value = "system:addCase:excel")
@SysOperationLog(title = "案例导入",businessType = BusinessType.IMPORT)
@ApiOperation(value = "案例导入")
@PostMapping("/excel")
public Result excelWarehousing(List<MultipartFile> files, HttpServletRequest request) {
    
    
    //批量导入案例
    sysCaseService.saveSubject(files, sysCaseService);
    return Result.ok();
}

2、SysCaseService

/**
 * 批量插入到sql语句中
 * @param sysCaseExcelEntity
 * @return
 */
Boolean insertListData(List<SysCaseExcelEntity> sysCaseExcelEntity);

3、SysCaseServiceImpl
3-1、RRException是我这边项目的自定义异常

/**
 * 案例导入excel
 *
 * @param fileList
 * @param sysCaseService
 */
@Override
public void saveSubject(List<MultipartFile> fileList, SysCaseService sysCaseService) {
    
    
    if (fileList.isEmpty()) {
    
    
        throw new RRException("文件异常,请重新选择");
    }
    for (int i = 0; i < fileList.size(); i++) {
    
    
        MultipartFile multipartFile = fileList.get(i);
        String fileName = multipartFile.getOriginalFilename();
        //判断文件类型
        if (StringUtils.isNotBlank(fileName)) {
    
    
            if (!fileName.endsWith(ExcelTypeEnum.XLS.getValue()) && !fileName.endsWith(ExcelTypeEnum.XLSX.getValue())) {
    
    
                throw new RRException("文件格式错误,请重新选择 xlsx 或 xls 格式文件");
            }
            try {
    
    
                //有个很重要的点 UserExcelListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
                EasyExcel.read(multipartFile.getInputStream(),
                        SysCaseExcelEntity.class,
                        new SysCaseServiceImportExcelListener(sysCaseService)).sheet().doRead();
            } catch (Exception e) {
    
    
                e.printStackTrace();
                throw new RRException(e.getMessage());
            }
        }
    }
}

4、接收excel数据的实体类
4-1、@ExcelProperty对应excel的表头的名称

package com.xmtdxt.pc.api.sys.excelListener.excelEntity;

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

import java.io.Serializable;

/**
 * 案例导入 数据实体
 * @author LunarYouI
 * @create 2022-03-23 11:47
 */
@Data
public class SysCaseExcelEntity implements Serializable {
    
    

    @ExcelProperty("案例名称")
    private String name;

    @ExcelProperty("案例报价")
    private String startingPrice;

    @ExcelProperty("订单报价")
    private String orderPrice;

    @ExcelProperty("案例类型")
    private String caseType;

    @ExcelProperty("选择日期")
    private String caseDate;

    @ExcelProperty("选择场地")
    private String site;

    @ExcelProperty("选择地址")
    private String address;

    @ExcelProperty("新郎")
    private String protagonistName1;

    @ExcelProperty("新娘")
    private String protagonistName2;

    @ExcelProperty("全部风格(多个逗号分隔)")
    private String style;

    @ExcelProperty("全部颜色(多个逗号分隔)")
    private String color;

    @ExcelProperty("案例描述")
    private String description;

}

5、SysCaseServiceImportExcelListener,核心代码;
5-1:onException方法进行异常转换;重写了AnalysisEventListener下的方法
5-2:invoke方法下的if条件是我这边用来筛选数据的自定义异常,假设excel中有名字长度大于6,那么代码就终止了。

package com.xmtdxt.pc.api.sys.excelListener.excelListener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.xmtdxt.common.exception.RRException;
import com.xmtdxt.pc.api.sys.excelListener.excelEntity.SysCaseExcelEntity;
import com.xmtdxt.pc.api.sys.service.SysCaseService;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户导入excel文件
 * 参考代码
 * @author LunarYouI
 * @create 2022-03-23 11:50
 * 每解析一行会回调invoke()方法。
 * 整个excel解析结束会执行doAfterAllAnalysed()方法
 * 参考:https://www.yuque.com/easyexcel/doc/easyexcel
 */
public class SysCaseServiceImportExcelListener extends AnalysisEventListener<SysCaseExcelEntity> {
    
    
    SysCaseService sysCaseService;

    public SysCaseServiceImportExcelListener(SysCaseService sysCaseService) {
    
    
        this.sysCaseService = sysCaseService;
    }

    /**
     * 用于暂时存储数据
     */
    private List<SysCaseExcelEntity> datas = new ArrayList<>(3000);

    /**
     * 每隔3000条存储数据库,然后清理list,方便内存回收 具体条数按实际情况确定
     */
    private static final int BATCH_COUNT = 3000;

    /**
     * 记录行数 第一行为表头
     */
    int row = 1;

    /**
     * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
     *
     * @param exception
     * @param context
     * @throws Exception ExcelAnalysisException
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
    
    
        System.out.println("解析失败===" + exception.getMessage());

        //如果是某一个单元格的转换异常 能获取到具体行号,如果要获取头的信息 配合invokeHeadMap使用
        if (exception instanceof ExcelDataConvertException) {
    
    
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            throw new RRException("第 " + excelDataConvertException.getRowIndex() + " 行,第 " + excelDataConvertException.getColumnIndex() + " 列解析异常");
        }
        //若不抛异常 则会继续解析下一行
        throw exception;
    }

    @Override
    public void invoke(SysCaseExcelEntity sysCaseExcelEntity, AnalysisContext analysisContext) {
    
    
        //第一行为表头
        row++;
        if (sysCaseExcelEntity.getName().length() > 6) {
    
    
            throw new RRException("第 " + row + " 行:用户名:" + sysCaseExcelEntity.getName() + " 格式错误,字数大于6个");
        }
        datas.add(sysCaseExcelEntity);
        if (datas.size() >= BATCH_COUNT) {
    
    
            saveData();
            datas.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
    
        saveData();
        //解析结束销毁不用的资源
        datas.clear();
    }

    /**
     * 存储数据库 具体逻辑处理 ================================================================================
     */

    private void saveData() {
    
    
        //循环遍历打印出了数据就证明导入数据成功了!
        if (datas != null && datas.size() > 0) {
    
    
            for (SysCaseExcelEntity data : datas) {
    
    
                System.out.println("数据-----------------"+data);
            }
        }
        //然后就可以实现将数据存储到数据库中了!
        sysCaseService.insertListData(datas);
    }
}

在这里插入图片描述
在这里插入图片描述
假设名字大于 6
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46100517/article/details/123704938