Spring Boot 中使用EasyExcel实现导入导出
作者:mmseoamin日期:2024-04-01

1.前言

在实际开发中,处理 Excel 文件是一个常见的需求。EasyExcel 是一个基于 Java 的开源库,提供了简单易用的 API,可以方便地读取和写入 Excel 文件。本文将介绍如何在SpringBoot中使用 EasyExcel 实现 Excel 导入功能;

1.1 首先 在 POM.XML文件中导入依赖


        
            com.alibaba
            easyexcel
            2.2.3
        

 2.导出功能

controller层

/**
     * 导出
     * @author whj
     * @date 2023/12/6 17:48
     * @param
     * @return
     */
    @PostMapping("/exportInspectionPlan")
    @ApiOperation(value = "导出",notes = "导出")
    public void exportInspectionPlan(HttpServletRequest request, HttpServletResponse response,@RequestBody DataFromVo dataFromVo){
        log.info("执行了post请求");
        log.info("参数:"+dataFromVo);
        siteInspectPlanHomeService.exportInspectionPlan(request,response,dataFromVo);
    }

2.1  创建实体类:在使用 EasyExcel 进行导出时,我们需要创建一个与 Excel 数据结构相匹配的实体类。实体类的字段应与 Excel 文件的列对应。使用 @ExcelProperty 注解来标识字段与 Excel 列的映射关系,以及一些其他注解来设置字段的属性。

/**
 * @Author whj
 * @Description: 导出信息对象
 * @Date 2023/12/6 9:26
 */
@Data
@HeadRowHeight(value = 30) // 头部行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 20) // 列宽
@HeadFontStyle(fontName = "宋体", fontHeightInPoints = 11)
public class ExportPlanInformationVo  implements Serializable {
    @ApiModelProperty("名称")
    @ExcelProperty(value = "名称")
    private String planName;
    @ApiModelProperty("类型")
    @Dict(code = "inspectionType", fieldName = "inspectionTypeName")
    @ExcelProperty(value = "类型")
    private String inspectionType;
    @ApiModelProperty("主题名称")
    @ExcelProperty(value = "主题")
    private String themeName;
    @ApiModelProperty("计划起止时间")
    @ExcelProperty(value = "计划起止时间")
    private String startEndTime;
    /**
     * @descriptions 年度
     */
    @ApiModelProperty("年度")
    @ExcelProperty(value = "年度")
    private String inspectionYear;
    /**
     * @descriptions 单位数量
     */
    @ApiModelProperty("单位数量")
    @ExcelProperty(value = "单位数量")
    private String orgNoCount;
    /**
     * @descriptions 用户数
     */
    @ApiModelProperty("户数")
    @ExcelProperty(value = "户数")
    private String taskNum;
    /**
     * @descriptions 已完成户数
     */
    @ApiModelProperty("已完成户数")
    @ExcelProperty(value = "已完成户数")
    private String completedNumber;
    /**
     * @descriptions 完成率
     */
    @ApiModelProperty("完成率")
    @ExcelProperty(value = "完成率")
    private String inspectionCompletionRate ;
    /**
     * @descriptions 超期状态
     */
    @ApiModelProperty("超期状态")
    @ExcelProperty(value = "超期状态")
    private String isItOverdue;
    /**
     * @descriptions 计划状态
     */
    @ApiModelProperty("状态")
    @ExcelProperty(value = "状态")
    @Dict(code = "planStatus", fieldName = "planStatusName")
    private String planStatus;
    /**
     * @descriptions 创建时间
     */
    @ApiModelProperty("创建时间")
    @ExcelProperty(value = "创建时间")
    private String createTime;
    @ApiModelProperty("结束日期")
    @ExcelIgnore
    private String endTime;

注意:1. 如果不想某个字段在excel中出现  可以加  @ExcelIgnore注解

(默认所有字段都会和excel去匹配,加了这个注解会忽略该字段)

2.@ExcelIgnoreUnannotated​

默认不管加不加ExcelProperty的注解的所有字段都会参与读写,加了ExcelIgnoreUnannotated注解以后,不加ExcelProperty注解的字段就不会参与

3.@DateTimeFormat​

日期转换,用String去接收excel日期格式的数据会调用这个注解;

2.2.Service层

========================== 重点来了!!!!===============================

 @Override
    public void exportInspectionPlan(HttpServletRequest request, HttpServletResponse response, DataFromVo dataFromVo) {
         //以上需要根据自己的业务去做数据处理   这里就不做展示
        try{
            //给文件命名
            String fileName = "现场巡视计划报表";
            // 设置响应头
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            // 设置防止中文名乱码
            fileName = URLEncoder.encode(fileName, "utf-8");
            // 文件下载方式(附件下载还是在当前浏览器打开)
            response.setHeader("Content-disposition", "attachment;filename=" +
                    fileName + ".xlsx");
            //向excel表格写入数据
            EasyExcel.write(response.getOutputStream(),ExportPlanInformationVo.class)
                    .sheet("现场巡视计划报表")
                    .doWrite(planVos);
        }catch (Exception e){
            log.error("出现错误 {}",e);
        }
    }

至此  一个简单的导出就结束了

 3.导入功能

EasyExcel的导入功能通常是将Excel文件中的数据导入到程序中,例如Java应用程序。导入过程如下:

  1. 首先,您需要准备一个包含要导入数据的Excel文件。
  2. 在Java应用程序中,使用EasyExcel提供的API创建一个ExcelReader对象,该对象表示要读取的Excel文件。
  3. 配置ExcelReader对象,包括指定要读取的文件路径、工作表名称等。
  4. 使用EasyExcel提供的方法从Excel文件中读取数据。您可以逐行读取数据,也可以使用批量读取的方法来提高性能。
  5. 将读取的数据处理并存储在程序中,例如将其存储在数据库、内存中的数据结构或其他数据存储中。
  6. 完成数据读取后,关闭ExcelReader对象,以确保所有数据都被正确读取并处理。

通过这种方式,您可以使用EasyExcel将Excel文件中的数据导入到Java应用程序中,以便进行进一步的处理或使用。导入功能在数据处理、数据迁移等场景中非常有用。

3.1  controller层

/**
     * 导入
     *
     * @param file
     * @return void
     * @Author xxx
     * @Date 2023/12/1 10:28
     */
    @PostMapping("/importPatrolUser")
    @ApiOperation(httpMethod = "POST", value = "导入")
    public ImportInfoVo importPatrolUser(@RequestBody MultipartFile file) {
       return patrolConfigService.importPatrolUser(file);
    }

3.2  Service层

 @Override
    public ImportInfoVo importPatrolUser(MultipartFile file) {
        ImportInfoVo importInfoVo = new ImportInfoVo();
        importInfoVo.setFailNum("0");
        importInfoVo.setWinNum("0");
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            log.info("文件检查出错");
        }
        List importPatrolUserError = new ArrayList<>();
        List importPatrolUserDtos = EasyExcel.read(inputStream, ImportPatrolUserDto.class, new EmployeeReadListener())
                    .sheet(0)
                    .head(ImportPatrolUserDto.class)
                    .headRowNumber(3)
                    .doReadSync();
        if (CollectionUtils.isEmpty(importPatrolUserDtos)){
            throw HzwqServiceException.build(ResultEnum.EXCEPTIONZY, "未获取到模板导入数据");
        }
//------根据自己业务进行处理,这里不做展示
        importInfoVo.setWinNum(cconsInfoVos.size()+"");
        importInfoVo.setCconsInfoList(cconsInfoVos);
        importInfoVo.setImportPatrolUserErrorList(importPatrolUserError);
        importInfoVo.setFailNum(importPatrolUserError.size()+"");
        importInfoVo.setSumNum(importPatrolUserDtos.size()+"");
        return importInfoVo;
    }

4.下载模板功能

/**
     * 下载模板
     *
     * @param request
     * @param response
     * @return void
     * @Author xxx
     * @Date 2023/12/5 15:45
     */
    @GetMapping(value="/download")
    public void download(HttpServletRequest request, HttpServletResponse response) {
    fileUtil.downloadExcel(request,response);
    }

这里封装了一个工具类  可做参考

/**
 * @Description: 文件工具
 * @Author  xxx
 * @Date 2023/12/5 15:46
 */
@Component
public  class  FileUtil {
    @Autowired
    ResourceLoader resourceLoader;
    //下载模板
    @SneakyThrows
    public  void downloadExcel(HttpServletRequest request, HttpServletResponse response){
        String fileName = "用户模板.xlsx";
        response.reset();
        response.setContentType("application/force-download");
        // 支持中文名称文件,需要对header进行单独设置,不然下载的文件名会出现乱码或者无法显示的情况
        String filename = URLEncoder.encode(fileName,"UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + filename);
        org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:用户模板.xlsx");
        InputStream is = resource.getInputStream();
        ServletOutputStream outputStream;
        byte[] array;
        try {
            outputStream = response.getOutputStream();
            array = IOUtils.toByteArray(is);
            outputStream.write(array);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            return;
        }
    }
}

至此所有内容结束  

==============================%&whj&%===================================