何小豆儿在此 发表于 2024-7-24 07:01:06

EasyExcel相关

1. easyexcel–100M

EasyExcel是一个基于Java的使用简单、节省内存的读写Excel的开源项目。在尽大概节省内存的环境下支持读写百M的Excel。
节省内存的原因:在剖析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个剖析
EasyExcel接纳一行一行的剖析模式,并将一行的剖析结果以观察者的模式通知处理惩罚
   通过Java代码完成对Excel的读写操作。所谓的读写理解为上传和下载
github地点:https://github.com/alibaba/easyexcel
官方文档:https://www.yuque.com/easyexcel/doc
2. easyexcel写操作

   所谓的写操作,就是把Java中的类对象写入到excel表格中
https://i-blog.csdnimg.cn/direct/95c2cec3ebbd42919e45d97666530bc1.png#pic_center
实现步调

[*]引入依靠
<dependency>
            <groupId>repMaven.com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.0.5</version>
      </dependency>

[*] 封装相应的对象,创建与表格对应的实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExcelDemo {
    @ExcelProperty(value = "姓名")//标记excel的表头内容
    public String name;
    @ExcelProperty(value = "年龄")
    public Integer age;
    @ExcelProperty(value = "性别")
    public String sex;
    @ExcelIgnore//写入excel表格时忽略该属性
    public String address;
}

[*]@ExcelProperty:标志excel的表头内容
[*]@ExcelIgnore:在写入excel表格时忽略该属性
   
[*] 通过easyexcel完成写入操作
public class WriteExcel {
    public static void main(String[] args) {
      //fileName:表示excel写入的路径以及名称
      String fileName="D:\\idea\\easyexcel_demo1\\writer.xlsx";
      //这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板,然后文件流会自动关闭
      //如果这里使用03,则 传入 excelType 参数即可
      List<ExcelDemo> list=new ArrayList<>();
      list.add(new ExcelDemo("章三",18,"男","郑州"));
      list.add(new ExcelDemo("李斯",19,"男","郑州"));
      list.add(new ExcelDemo("汪芜",20,"女","郑州"));
      list.add(new ExcelDemo("码字",25,"男","郑州"));
      EasyExcel.write(fileName,ExcelDemo.class).sheet("第一次完成写操作").doWrite(list);
    }
}

[*]预备文件路径
[*]写出文件
   
3. easyexcel写操作——web模式【导出】

导出:必要将数据库内里的文件以附件的形式下载到本地电脑,必要参数为response对象,返回值类型为void


[*]实例
@Controller
public class ExcelController {
    @GetMapping("download")
    public void download(HttpServletResponse response) throws IOException {
      // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
      response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
      response.setCharacterEncoding("utf-8");
      // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
      String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
      response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

      List<ExcelDemo> list=new ArrayList<>();
      list.add(new ExcelDemo("章三",18,"男","郑州"));
      list.add(new ExcelDemo("李斯",19,"男","郑州"));
      list.add(new ExcelDemo("汪芜",20,"女","郑州"));
      list.add(new ExcelDemo("码字",25,"男","郑州"));
      EasyExcel.write(response.getOutputStream(), ExcelDemo.class).sheet("模板").doWrite(list);
    }
}
也可以在controllre层仅进行调用操作,将逻辑交由service去做,即:


[*]controller
    @ApiOperation("导出")
    @GetMapping("/download")
    public void exportData(HttpServletResponse response){
      dictService.exportData(response);
    }


[*]service
@Override
    public void exportData(HttpServletResponse response) {
      try {
            //设置相关参数
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("数据字典", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
            //获取文件
            List<Dict> list = this.baseMapper.selectList(null);
            //转换文件
            ArrayList<DictEeVo> dictEeVos = new ArrayList<>();
            for (Dict dict : list) {
                DictEeVo dictEeVo = new DictEeVo();
                //转换
                BeanUtils.copyProperties(dict, dictEeVo);
                //添加
                dictEeVos.add(dictEeVo);
            }
            //写出
            EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("数据字典").doWrite(dictEeVos);
          } catch (Exception e) {
            e.printStackTrace();
      }
    }
测试
测试仅需答应项目,然后在前端页面写入现实的url地点即可,也可以添加按钮的点击事件进行测试
4. easyexcel读操作



[*]流程
https://i-blog.csdnimg.cn/direct/2b50ecb447a441e2a5b6094af2ad3b8f.png#pic_center


[*]实现步调

[*] 引入fastjson依靠
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
      </dependency>
       com.alibaba.fastjson.JSON是阿里巴巴开源的一个高性能数据交换格式库,它是基于Java语言的JSON剖析和生成工具。Fastjson旨在提供一种快速、便捷的方式来序列化和反序列化Java对象到JSON字符串,以及将JSON字符串转换回Java对象。它支持大数据量的处理惩罚,而且具有优秀的性能,通常比尺度的Java自带的java.util.JSONObject和org.json.JSONObject更快。
    使用Fastjson的好处包括:

[*]高效:通过字节码操作,使得JSON剖析和生成的速度非常快。
[*]易用:API设计简洁明了,易于理解和上手。
[*]功能丰富:支持复杂数据结构的处理惩罚,如日期、数组、聚集等。
    在Java项目中,你可以通过Maven或Gradle添加fastjson依靠来使用它,然后通过JSONObject、JSONArray或其他类来进行JSON相关的操作。
   
[*] 创建监听器
package com.zmq.excel;

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 lombok.extern.slf4j.Slf4j;

import java.util.List;

// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class DemoDataListener implements ReadListener<ExcelDemo> {

    /**
   * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
   */
    private static final int BATCH_COUNT = 100;
    /**
   * 缓存的数据
   */
    private List<ExcelDemo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    /**
   * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
   */
    private DemoDAO demoDAO;

    public DemoDataListener() {
      // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
      demoDAO = new DemoDAO();
    }

    /**
   * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
   *
   * @param demoDAO
   */
    public DemoDataListener(DemoDAO demoDAO) {
      this.demoDAO = demoDAO;
    }

    /**
   * 这个每一条数据解析都会来调用
   *
   * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
   * @param context
   */
    //一行一行的去读取里面的数据
    @Override
    public void invoke(ExcelDemo 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());
      demoDAO.save(cachedDataList);
      log.info("存储数据库成功!");
    }
}
       进行读操作时就会触发监听器,基本不必要改动
[*] dao
package com.zmq.excel;

import java.util.List;

/**
* 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。
**/
public class DemoDAO {
    public void save(List<ExcelDemo> list) {
      // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
    }
}
       dao中填写必要的操作
[*] 读取
public class ReadExcel {
    public static void main(String[] args) {
      /**
         * 指定列的下标或者列名
         *
         * <p>1. 创建excel对应的实体对象,并使用{@link ExcelProperty}注解. 参照{@link IndexOrNameData}
         * <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link IndexOrNameDataListener}
         * <p>3. 直接读即可
         */

      //fileName:表示excel读取的路径以及名称
      String fileName="D:\\idea\\easyexcel_demo1\\writer.xlsx";
      // 这里默认读取第一个sheet
      //new DemoDataListener():监听器
      EasyExcel.read(fileName, ExcelDemo.class, new DemoDataListener()).sheet().doRead();
    }
}

5. easyexcel文件上传-web【导入】

导入:必要将本地文件插入到数据库,参数:multiparefile,返回值:“成功或失败”
   使用excel进行导入必要剖析器的共同,使用监听器对读取的文件进行操作
剖析器:用来读取文件,并将数据插入到数据库

[*] 参加文件上传的依靠
<dependency>
            <groupId>repMaven.commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
      </dependency>
       commons-fileupload是一个开源库,专为Java应用程序设计,用于处理惩罚文件上传功能。它简化了处理惩罚HTTP哀求中的multipart/form-data格式,这种格式通常用于用户通过Web表单上传文件到服务器。该库提供了一组工具类和处理惩罚器,使得开辟者能够剖析上传的文件流,并管理文件名、大小限制等复杂操作。它的API易于使用,支持断点续传以及错误处理惩罚,广泛应用于web应用开辟中的文件上传组件。
[*] 文件上传剖析器——spring设置文件中
若使用springboot框架,仅引入上述依靠即可
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      <property name="maxUploadSize" value="1000000000"/>
    </bean>

[*] controller
@Autowired
    private DemoDAO demoDAO;
    @PostMapping("/upload")
    @ResponseBody //将返回值转化为json格式
    public String upload(MultipartFile file) throws IOException{
      EasyExcel.read(file.getInputStream(), ExcelDemo.class, new DemoDataListener(demoDAO)).sheet().doRead();
      return "success";
    }
       DemoDao层参加注入spring容器的注解:@Component
[*] 测试——使用postman完成测试
https://i-blog.csdnimg.cn/direct/2ce2da98ae92426ea0e3fb779059e7e9.png#pic_center

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: EasyExcel相关