springboot中使用EasyExcel实现Excel 导入导出

本文介绍了EasyExcel,一个用于Java的高效Excel操作工具,支持读写、数据转换和内存优化。文章详细讲解了如何在项目中添加依赖、创建导出实体类、使用注解处理数据和格式、以及控制器类的实现和前端导入功能。

一、EasyExcel的介绍

EasyExcel 是一款基于 Java 的简单易用的 Excel 文件操作工具。它提供了丰富的 API,可以方便地读取、写入和操作 Excel 文件,支持常见的 Excel 操作,如读取/写入单元格数据、合并单元格、设置样式、处理大数据量等。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

1、在pom.xml引入依赖

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

2、创建导出实体类跟表头

**
 * 用户 Excel 导出 VO
 */
@Data
public class UserExcelVO {

    @ExcelProperty("用户编号")
    private Long id;

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

    @ExcelProperty("用户昵称")
    private String nickname;

    @ExcelProperty("用户邮箱")
    private String email;

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

    @ExcelProperty(value = "用户性别", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.USER_SEX)
    private Integer sex;

    @ExcelProperty(value = "帐号状态", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.COMMON_STATUS)
    private Integer status;

    @ExcelProperty("最后登录IP")
    private String loginIp;

    @ExcelProperty("最后登录时间")
    private LocalDateTime loginDate;

    @ExcelProperty("部门名称")
    private String deptName;

    @ExcelProperty("部门负责人")
    private String deptLeaderNickname;

}

① 每个字段上的 @ExcelProperty (opens new window)注解,声明 Excel Head 头部的名字
② 每个字段的值,就是它对应的 Excel Row 行的数据值
③ @ExcelProperty 注解的 converter 属性是 DictConvert 转换器,通过它将 status = 1 转换成“开启”列,status = 0 转换成”禁用”列,注解 @DictFormat (opens new window)为对应的字典数据的类型。
更多《EasyExcel 中的注解 》

3、ExcelUtils类 写入以及读取

public class ExcelUtils {

    /**
     * 将列表以 Excel 响应给前端
     *
     * @param response 响应
     * @param filename 文件名
     * @param sheetName Excel sheet 名
     * @param head Excel head 头
     * @param data 数据列表哦
     * @param <T> 泛型,保证 head 和 data 类型的一致性
     * @throws IOException 写入失败的情况
     */
    public static <T> void write(HttpServletResponse response, String filename, String sheetName,
                                 Class<T> head, List<T> data) throws IOException {
        // 输出 Excel
        EasyExcel.write(response.getOutputStream(), head)
                .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
                .sheet(sheetName).doWrite(data);
        // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
    }
    public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
       return EasyExcel.read(file.getInputStream(), head, null)
                .autoCloseStream(false)  // 不要自动关闭,交给 Servlet 自己处理
                .doReadAllSync();
    }
 }
 

4、Controller类实现

    @GetMapping("/export")
    @Operation(summary = "导出用户")
    @OperateLog(type = EXPORT)
    public void exportUserList(@Validated UserExportReqVO reqVO,
                               HttpServletResponse response) throws IOException {
        // 获得用户列表
        List<UserDO> users = userService.getUserList(reqVO);
        UserExcelVO excelVO = UserConvert.INSTANCE.convert02(user);
        // 输出
        ExcelUtils.write(response, "用户数据.xls", "用户列表", UserExcelVO.class, excelVO );
    }

    
    /**
     * 客户信息导入
     */
   @PostMapping("ImportExcel")
    public  R<Object>  importExcel(MultipartFile file, HttpServletRequest request) throws IOException {
        if (file.isEmpty()) {
            throw new RRException("excel文件内容为空!");
        }

        String userId = AuthContext.getLoginId().toString();
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取3000条数据 然后返回过来 直接调用使用数据就行
        List<CustomerManageEntity> vos = com.sxbctv.tone.business.utils.ExcelUtils.read(file, CustomerManageEntity.class);
        customerManageService.importExcel(vos,userId);

        return R.ok();
    }


     /**
     * 客户信息模板导出
     * @param response
     * @param request
     * @throws IOException
     */
    @GetMapping("/exportDownload")
    @ApiOperation("新增客户信息导出")
    public void downloadExcel(HttpServletResponse response, HttpServletRequest request)throws IOException {
        //获取输入流,原始模板位置
        InputStream bis = getClass().getResourceAsStream("/excel/客户信息导入模板.xlsx");

        //假如以中文名下载的话,设置下载文件名称
        String filename = "客户信息模板.xlsx";
        //转码,免得文件名中文乱码
        filename = URLEncoder.encode(filename,"UTF-8");
        //设置文件下载头
        response.addHeader("Content-Disposition", "attachment;filename=" + filename);
        //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
        response.setContentType("multipart/form-data");
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        int len = 0;
        while((len = bis.read()) != -1){
            out.write(len);
            out.flush();
        }
        out.close();
    }

5、前端导入实现

<el-upload style="display: inline-block;padding-left: 10px;" ref="upload" class="upload-demo" :action="actionUrl" :show-file-list="false"
          :limit="1" :on-success="uploadSucess" accept=".xlsx,.xls">
   <el-button type="primary">excel导入</el-button>
</el-upload>

data() {
    return {
      actionUrl: this.$http.adornUrl("/business/customer/manage/ImportExcel?" + "&token=" + this.$cookie.get('localhostx-tone-token'))
    }
  },

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值