一、问题出现

最近项目中需要实现一个Excel文件导出功能,于是乎,就选择使用了EasyExcel组件来进行Excel文件的导入与导出。

二、代码实现

EasyExcel实现文件的导入,最主要的是需要一个Listener,全部流程如下:

1、依赖导入:

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

2、继承AnalysisEventListener,实现一个Listener,也就是一个Excel读取解析器,在该解析器中可以对每一行的数据进行处理、表头进行处理、以及数据读取完后的最终处理。

/**
 * excel读取解析器
 */
public class ExcelListener<T> extends AnalysisEventListener<T> {

    /**
     * 自定义用户暂时存储data
     */
    private final List<T> list = new ArrayList<>();

    /**
     * 用于存储错误提示
     */
    private final Map<String, String> message = new HashMap<>();

    /**
     * 此处进行表头检验
     * @param o 读取后的数据对象
     * @param analysisContext 内容
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 在此处可以进行表头的校验,headMap对应的就是表头的数据
        // 在此处有个很奇怪的地方,就是当用户导入的文件没有任何表头的时候,也就是表头这一行为空
        // 表头检验则不会进行这个函数,且数据导入成功,所以这个地方要确认清楚
        // 最后我是在拿到所有数据,包括表头,再取第一行为表头进行校验
    }

    /**
     * 每解析一行都会回调invoke()方法
     * @param o 读取后的数据对象
     * @param analysisContext 内容
     */
    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        list.add(t);
    }

    /**
     * 读取结束之后分析数据
     * @param analysisContext 分析上下文
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 当执行到该方法时,Excel表的数据都已经读取完毕了,你可以在这里对数据进行特定处理、或者是表头的格式、位置进行校验
    }

    /**
     * 返回数据
     * @return 返回读取的列表对象
     */
    public List<T> getList(){
        return list;
    }

    /**
     * 返回表头校验数据
     * @return 返回读取的列表对象
     */
    public Map<String, String> getMessage() {
        return message;
    }

3、controller实现,接收Excel表格

/**
 * 文件上下传Controller类
 */
@Slf4j
@Controller
public class FileController {

    @Resource
    private FileService fileService;

    /**
     * 文件上传
     */
    @PostMapping("/upload")
    @ResponseBody
    public Boolean upload(MultipartFile file){
        if(file == null){
            return false;
        }
        try{
            fileService.handleExcel(file);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

}

4、service实现,处理Excel数据

/**
 * fileservice类
 */
public interface FileService {
    /**
     * 处理上传的Excel文件
     * @return 返回处理结果,没有异常返回ture,否则返回false
     */
    Boolean handleExcel(MultipartFile file);
}
/**
 *FileService实现类
 */
@Service
public class FileServiceImpl implements FileService {

   /**
     * 处理上传的Excel文件
     * @param file Excel文件
     * @return 返回处理结果,没有异常返回ture,否则返回false
     */
    public Boolean handleExcel(MultipartFile file){
        // ExcelListener用于EasyExcel读取每一条数据
        ExcelListener excelListener = new ExcelListener();
        try{
            // 此处rowNumber设置为-1是为了将表头也读取到list列表总
            EasyExcel.read(file.getInputStream(), excelListener).sheet(0).headRowNumber(-1).autoTrim(true).doRead();
            // 获取到Excel行数据,数据包含表头
            List<Object> list = excelListener.getList();

            // 在此处拿到第一行数据,进行表头格式检验
            
           //  对你的数据进行你要处理,新增或修改
            return true
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }
    }

}

至此,通过EasyExcel导入功能Excel功能实现。