SpringBoot使用 easyexcel进行Excel数据的导入导出

16 篇文章 1 订阅
3 篇文章 0 订阅


前言

项目开发中,我们经常会遇到使用Excel实现导入导出的需求,推荐一款性能比较好的Excel导入导出工具EasyExcel,简单记录一下使用的步骤,希望对大家有所帮助!

提示:以下是本篇文章正文内容,下面案例可供参考

一、EasyExcel简介

EasyExcel是一款阿里开源的Excel导入导出工具,具有处理快速、占用内存小、使用方便的特点,在Github上已有22k+Star,可见其非常流行。
EasyExcel读取75M(46W行25列)的Excel,仅需使用64M内存,耗时20s,极速模式还可以更快!
在这里插入图片描述
官方网站:https://yuque.com/easyexcel
github地址:https://github.com/alibaba/easyexcel

二、使用步骤

EasyExcel和EasyPoi的使用非常类似,都是通过注解来控制导入导出。接下来我们以用户信息的导入导出为例,分别实现下简单的单表导入导出

1.引入库

我这里选择的easyexcel版本是2.2.6

代码如下:

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

2.创建用户信息对象,自定义转换器

EasyExcel的核心注解:
@ExcelProperty:核心注解,value属性可用来设置表头名称,converter属性可以用来设置类型转换器;
@ColumnWidth:用于设置表格列的宽度;
@DateTimeFormat:用于设置日期转换格式

首先创建一个用户信息对象ExportUserInfoDTO ,封装需要导出的用户信息
代码如下:

/**
 * @Description : Excel导出用户信息对象
 * @Author : 冰雪伯爵
 * @Date : 2022/1/9
 * <p>
 * EasyExcel的核心注解:
 * @ExcelProperty:核心注解,value属性可用来设置表头名称,converter属性可以用来设置类型转换器;
 * @ColumnWidth:用于设置表格列的宽度;
 * @DateTimeFormat:用于设置日期转换格式
 **/
@Data
public class ExportUserInfoDTO {

    @ExcelProperty("ID")
    @ColumnWidth(20)
    private Long id;

    @ExcelProperty("用户名")
    @ColumnWidth(20)
    private String username;

    @ExcelProperty("邮箱")
    @ColumnWidth(20)
    private String email;

    @ExcelProperty("手机号")
    @ColumnWidth(20)
    private String mobile;

    @ExcelProperty(value = "账号状态", converter = StatusConverter.class)
    @ColumnWidth(20)
    private Integer status;

    @ExcelProperty("备注")
    @ColumnWidth(20)
    private String remark;

    @ExcelProperty("创建时间")
    @ColumnWidth(20)
    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
    private Date createTime;
}

然后自定义状态转换器,在EasyExcel中,如果想要实现枚举类型到字符串的转换,比如Status属性中,0->正常,1->停用,2->删除,需要自定义转换器,下面为自定义的StatusConverter代码实现;

代码如下:

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

/**
 * @Description : 自定义转换器 状态
 * @Author : 冰雪伯爵
 * @Date : 2022/1/9
 * <p>
 * 在EasyExcel中,如果你想实现枚举类型到字符串的转换(比如Status属性中,0->正常,1->停用,2->删除),需要自定义转换器
 **/

public class StatusConverter implements Converter<Integer> {

    @Override
    public Class supportJavaTypeKey() {
        //对象属性类型(即:0,1,2... 对应的数据类型)
        return Integer.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        //CellData属性类型
        return CellDataTypeEnum.STRING;
    }

    /**
     * CellData转对象属性
     *
     * @param cellData
     * @param excelContentProperty
     * @param globalConfiguration
     * @return
     * @throws Exception
     * 正常->0,停用->1,删除->2
     */
    @Override
    public Integer convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        String value = cellData.getStringValue();
        if (StringUtils.isEmpty(value)) {
            return null;
        }
        if ("正常".equals(value)) {
            return 0;
        } else if ("停用".equals(value)) {
            return 1;
        } else if ("删除".equals(value)) {
            return 2;
        } else {
            return null;
        }
    }

    /**
     * 对象属性转CellData
     *
     * @param value
     * @param excelContentProperty
     * @param globalConfiguration
     * @return
     * @throws Exception
     *  0->正常,1->停用,2->删除
     */
    @Override
    public CellData convertToExcelData(Integer value, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        if (value== null) {
            return new CellData<>("");
        }
        if (value == 0) {
            return new CellData<>("正常");
        } else if (value == 1) {
            return new CellData<>("停用");
        } else if (value == 2) {
            return new CellData<>("删除");
        } else {
            return new CellData<>("");
        }
    }
}

3.在Controller中实现接口

最后在Controller中添加导入导出,用于导出用户信息列表到Excel,还需给响应头设置下载excel的属性,具体代码如下;
另外测试代码功能,建议直接用浏览器或者用postman,如果使用swagger 会导致各种莫名其妙的问题
代码如下:

/**
 * @Description : EasyExcel导入导出Controller
 * @Author : 冰雪伯爵
 * @Date : 2022/1/9
 **/

@Api(value = "EasyExcel导入导出Controller", tags = "EasyExcel导入导出Controller")
@RestController
@RequestMapping("/easyExcel")
public class EasyExcelController {

    private static final Logger log = LoggerFactory.getLogger(EasyExcelController.class);

    @Autowired
    private SysUserService userService;

	/**
     * 【导出下载方式一】
     * @param response
     */
    @ApiOperation("导出用户信息列表Excel")
    @RequestMapping(value = "/exportList", method = RequestMethod.GET)
    public void exportList(HttpServletResponse response) {
        log.info("easyExcel,导出用户信息列表Excel---------->>>>>start ");
        List<ExportUserInfoDTO> userList = userService.exportList();
        try {
            setExcelRespProp(response, "用户信息表");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream())
                    .head(ExportUserInfoDTO.class)
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet("用户信息sheet")
                    .doWrite(userList);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出用户信息列表Excel 失败")
        }
        log.info("easyExcel,导出用户信息列表Excel---------->>>>>end ");
    }

    /**
     * 【导出下载方式二】
     * 文件下载并且失败的时候返回json(默认失败了会返回一个有部分数据的Excel)
     * 使用swagger 会导致各种问题,请直接用浏览器或者用postman
     *
     * @param response
     * @throws IOException
     */
    @ApiOperation("文件下载并且失败的时候返回json")
    @RequestMapping(value = "/downloadFailedUsingJson", method = RequestMethod.GET)
    public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
        List<ExportUserInfoDTO> userList = userService.exportList();
        try {
            setExcelRespProp(response, "用户信息表");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), ExportUserInfoDTO.class)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("模板")
                    .doWrite(userList);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }

    @ApiOperation("从Excel导入用户信息列表")
    @RequestMapping(value = "/importList", method = RequestMethod.POST)
    @ResponseBody
    public RestResponceBody importList(@RequestPart("file") MultipartFile file) {
        log.info("easyExcel,导入用户信息列表Excel---------->>>>>start ");
        try {
            List<ExportUserInfoDTO> userList = EasyExcel.read(file.getInputStream())
                    .head(ExportUserInfoDTO.class)
                    .sheet()
                    .doReadSync();
            log.info("easyExcel,导入用户信息列表Excel---------->>>>>end ");
            return new RestResponceBody<>(userList);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("导入用户信息列表Excel 失败")
        }
    }

    /**
     * 设置excel下载响应头属性
     *
     * @param response
     * @param rawFileName 文件名
     * @throws UnsupportedEncodingException
     */
    private void setExcelRespProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        //这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }
}

4.运行项目,测试导入导出

1、运行项目,使用postman测试接口,测试导出下载文件
在这里插入图片描述
下载完成后,查看导出下载好的Excel文件
在这里插入图片描述
2、运行项目,使用postman测试接口,测试导入Excel文件
在这里插入图片描述

至此,使用EasyExcel导入导出功能已完成


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值