EasyExcel基础使用

目录

1.EasyExcel

2.EasyExcel写操作

3.EasyExcel完成写操作-web

4.EasyExcel完成读操作


1.EasyExcel

EasyExcel是一个基于java的简单、省内存的读写Excel的开源项目,在尽可能节约内存的情况下支持读写百M的Excel。

网站:

通过java代码完成对Excel的读写操作。所谓的读写理解为上传和下载。

2.EasyExcel写操作

所谓的写操作就是把java中的类对象写入到Excel表格中。

实现步骤:

  1. 引入相关依赖

             <dependency>
                 <groupId>com.alibaba</groupId>
                 <artifactId>easyexcel</artifactId>
                 <version>3.2.0</version>
             </dependency>
  2. 封装相应对象

    @Data
     @AllArgsConstructor
     @NoArgsConstructor
     public class DemoData {
         @ExcelProperty("姓名")//value 表头
         private String name;
         @ExcelProperty("年龄")
         private Integer age;
         @ExcelProperty("家庭住址")
         private String address;
         /**
          * 忽略这个字段
          */
         @ExcelIgnore
         private String ignore;
     ​
     }
  3. 通过EasyExcel完成写操作

@Test
     public void simpleWrite() {
         String filename = "E:\\ideaProject\\code\\SpringBoot\\SpringBoot_EasyExcel\\easy-write.xlsx";
         ArrayList<DemoData> list = new ArrayList<>();
         list.add(new DemoData("萧炎", 40, "斗气大陆","01"));
         list.add(new DemoData("唐三", 40, "斗罗大陆","02"));
         list.add(new DemoData("林动", 40, "东玄域","03"));
         list.add(new DemoData("姬动", 40, "五行大陆","04"));
 ​
         EasyExcel.write(filename, DemoData.class).sheet("奇异玄幻").doWrite(list);
     }

3.EasyExcel完成写操作-web

@GetMapping("download")
     public void download(HttpServletResponse response) throws IOException {
         // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
         try {
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setCharacterEncoding("utf-8");
             double random = Math.random()*100+100;
             // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
             String fileName = URLEncoder.encode("测试"+random, "UTF-8").replaceAll("\\+", "%20");
             response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
             ArrayList<DemoData> list = new ArrayList<>();
             list.add(new DemoData("萧炎", 40, "斗气大陆","01"));
             list.add(new DemoData("唐三", 40, "斗罗大陆","02"));
             list.add(new DemoData("林动", 40, "东玄域","03"));
             list.add(new DemoData("姬动", 40, "五行大陆","04"));
             // 这里需要设置不关闭流
             EasyExcel.write(response.getOutputStream(), DemoData.class).autoCloseStream(Boolean.FALSE).sheet("模板")
                     .doWrite(list);
         } catch (Exception e) {
             // 重置response
             response.reset();
             response.setContentType("application/json");
             response.setCharacterEncoding("utf-8");
             Map<String, String> map = MapUtils.newHashMap();
             map.put("status", "failure");
             map.put("message", "下载文件失败" + e.getMessage());
             response.getWriter().println(JSON.toJSONString(map));
         }
     }
 =========================================封装成工具类===============================================================
     @GetMapping("download")
     public void download(HttpServletResponse response) throws IOException {
             ArrayList<DemoData> list = new ArrayList<>();
             list.add(new DemoData("萧炎", 40, "斗气大陆","01"));
             list.add(new DemoData("唐三", 40, "斗罗大陆","02"));
             list.add(new DemoData("林动", 40, "东玄域","03"));
             list.add(new DemoData("姬动", 40, "五行大陆","04"));
             upload(response,"时代在召唤",list,DemoData.class);
     }
     public void upload(HttpServletResponse response,String title,List<?> data,Class clazz){
          // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
         try {
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setCharacterEncoding("utf-8");
             // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
             String fileName = URLEncoder.encode(title, "UTF-8").replaceAll("\\+", "%20");
             response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
             
             // 这里需要设置不关闭流
             EasyExcel.write(response.getOutputStream(), clazz).autoCloseStream(Boolean.FALSE).sheet("模板")
                     .doWrite(data);
         } catch (Exception e) {
             // 重置response
             response.reset();
             response.setContentType("application/json");
             response.setCharacterEncoding("utf-8");
             Map<String, String> map = MapUtils.newHashMap();
             map.put("status", "failure");
             map.put("message", "下载文件失败" + e.getMessage());
             response.getWriter().println(JSON.toJSONString(map));
         }
     }

4.EasyExcel完成读操作

import com.alibaba.excel.context.AnalysisContext;
 import com.alibaba.excel.read.listener.ReadListener;
 import com.alibaba.excel.util.ListUtils;
 import com.alibaba.fastjson.JSON;
 import com.funian.mapper.DemoMapper;
 import com.funian.domain.DemoData;
 import lombok.extern.slf4j.Slf4j;
 ​
 import java.util.List;
 ​
 // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
 @Slf4j
 public class DemoDataListener implements ReadListener<DemoData> {
 ​
     /**
      * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
      */
     private static final int BATCH_COUNT = 100;
     /**
      * 缓存的数据
      */
     private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
     /**
      * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
      */
     private DemoMapper demoMapper;
 ​
     public DemoDataListener() {
         // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
 ​
     }
 ​
     /**
      * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
      *
      * @param demoMapper
      */
     public DemoDataListener(DemoMapper demoMapper) {
         this.demoMapper = demoMapper;
     }
 ​
     /**
      * 这个每一条数据解析都会来调用
      *
      * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
      * @param context
      */
     @Override
     public void invoke(DemoData data, AnalysisContext context) {
         log.info("解析到一条数据:{}", JSON.toJSONString(data));
         cachedDataList.add(data);
         // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
         if (cachedDataList.size() >= BATCH_COUNT) {
             saveData();
             // 存储完成清理 list
             cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
         }
     }
 ​
     /**
      * 所有数据解析完成了 都会来调用
      *
      * @param context
      */
     @Override
     public void doAfterAllAnalysed(AnalysisContext context) {
         // 这里也要保存数据,确保最后遗留的数据也存储到数据库
         saveData();
         //log.info("所有数据解析完成!");
     }
 ​
     /**
      * 加上存储数据库
      */
     private void saveData() {
         log.info("{}条数据,开始存储数据库!", cachedDataList.size());
         demoMapper.save(cachedDataList);
         log.info("存储数据库成功!");
     }
 }
     /**
      * 文件上传
      * <p>
      * 1. 创建excel对应的实体对象 参照{@link DemoData}
      * <p>
      * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
      * <p>
      * 3. 直接读即可
      */
     @Autowired
     private DemoMapper demoMapper;
     @PostMapping("upload")
     @ResponseBody
     public String upload(MultipartFile file) throws IOException {
         EasyExcel.read(file.getInputStream(), DemoData.class, new DemoDataListener(demoMapper)).sheet().doRead();
         return "success";
     }
 @Mapper
 public interface DemoMapper {
     public void save(List<DemoData> list);
         // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
 }
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.funian.mapper.DemoMapper">
 ​
     <resultMap id="BaseResultMap" type="com.funian.domain.DemoData">
         <result property="name" column="name" jdbcType="VARCHAR"/>
         <result property="age" column="age" jdbcType="INTEGER"/>
         <result property="address" column="address" jdbcType="VARCHAR"/>
     </resultMap>
 ​
     <sql id="Base_Column_List">
         name,age,address
     </sql>
     <insert id="save" parameterType="list">
         insert into demodata(name,age,address)
             values
                 <foreach collection="list" item="data" index="index"
                            separator=",">
                     (
                         #{data.name},
                         #{data.age},
                         #{data.address}
                     )
                 </foreach>
     </insert>
 </mapper>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值