EasyExcel相关

news2024/9/23 17:21:58

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表格中

在这里插入图片描述

实现步骤

  1. 引入依赖
<dependency>
            <groupId>repMaven.com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.0.5</version>
        </dependency>
  1. 封装相应的对象,创建与表格对应的实体类

    @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;
    }
    
    1. @ExcelProperty:标记excel的表头内容
    2. @ExcelIgnore:在写入excel表格时忽略该属性
  2. 通过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);
        }
    }
    
    1. 准备文件路径
    2. 写出文件

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读操作

  • 流程

在这里插入图片描述

  • 实现步骤
  1. 引入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.JSONObjectorg.json.JSONObject更快。

    使用Fastjson的好处包括:

    1. 高效:通过字节码操作,使得JSON解析和生成的速度非常快。
    2. 易用:API设计简洁明了,易于理解和上手。
    3. 功能丰富:支持复杂数据结构的处理,如日期、数组、集合等。

    在Java项目中,你可以通过Maven或Gradle添加fastjson依赖来使用它,然后通过JSONObjectJSONArray或其他类来进行JSON相关的操作。

  2. 创建监听器

    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("存储数据库成功!");
        }
    }
    

    进行读操作时就会触发监听器,基本不需要改动

  3. 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中填写需要的操作

  4. 读取

    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进行导入需要解析器的配合,使用监听器对读取的文件进行操作

解析器:用来读取文件,并将数据插入到数据库

  1. 加入文件上传的依赖

     <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应用开发中的文件上传组件。

  2. 文件上传解析器——spring配置文件中

    若使用springboot框架,仅引入上述依赖即可

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="1000000000"/>
        </bean>
    
  3. 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

  4. 测试——使用postman完成测试

    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1938267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习之基础知识整理

现在大语言模型很火&#xff0c;但它的基础仍然是以神经网络为基础的深度学习&#xff0c;不懂神经网络&#xff0c;不了解深度学习&#xff0c;对于大语言模型的二次开发也是整不明白。 那到底需要了解哪些知识&#xff1f;才能看懂深度学习/神经网络的基础模型&#xff0c;想…

后端传递中文到前端 乱码问题

后端代码 前端 乱码 decodeURI(name);使用这个方法,这个方法应该是jquery中的方法 这样就不乱码了

Pointnet++改进即插即用系列:全网首发WTConv2d大接受域的小波卷积|即插即用,提升特征提取模块性能

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入WTConv2d,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.理…

JVM:垃圾回收器演进

文章目录 一、演进二、Shenandoah三、ZGC 一、演进 二、Shenandoah Shenandoah是由Red Hat开发的一款低延迟的垃圾收集器&#xff0c;Shenandoah并发执行大部分GC工作&#xff0c;包括并发的整理&#xff0c;堆大小对STW的时间基本没有影响。 三、ZGC ZGC是一种可扩展的低延…

MySQL数据库基本用法

了解数据库基本概念 什么是数据库&#xff1f; • 长期存放在计算机内&#xff0c;有组织、可共享的大量数据的集合&#xff0c;是一个数据“仓库” MySQL数据库的特点 • 开源免费&#xff0c;小巧但功能齐全 • 可在Windows和Linux系统上运行 • 操作方便&#xff0c;…

VS2019安装MFC组件

VS2019支持的MFC版本是mfc140 ~ mfc142版本&#xff0c;它兼容VS2015、VS2017之前的老版本程序。 一、MFC的历史版本 MFC的历史版本如下&#xff1a; IDE发布时间工具集版本MSC_VERMSVCMFC版本dllVisual C6.01998V601200MSVC6.06.0mfc42.dll、mfcce400.dllVisual Studio 2002…

记录解决springboot项目上传图片到本地,在html里不能回显的问题

项目场景&#xff1a; 项目场景&#xff1a;在我的博客系统里&#xff1a;有个相册模块&#xff1a;需要把图片上传到项目里&#xff0c;在html页面上显示 解决方案 1.建一个文件夹 例如在windows系统下。可以在项目根目录下建个photos文件夹&#xff0c;把上传的图片文件…

[经验] 驰这个汉字的拼音是什么 #学习方法#其他#媒体

驰这个汉字的拼音是什么 驰&#xff0c;是一个常见的汉字&#xff0c;其拼音为“ch”&#xff0c;音调为第四声。它既可以表示动词&#xff0c;也可以表示形容词或副词&#xff0c;意义广泛&#xff0c;经常出现在生活和工作中。下面就让我们一起来了解一下“驰”的含义和用法。…

WSL2 Centos7 Docker服务启动失败怎么办?

wsl 安装的CentOS7镜像,安装了Docker之后,发现用systemctl start docker 无法将docker启动起来。 解决办法 1、编辑文件 vim /usr/lib/systemd/system/docker.service将13行注释掉,然后在下面新增14行的内容。然后保存退出。 2、再次验证 可以发现,我们已经可以正常通过s…

C++笔试练习笔记【3】:Fibonacci数列 WY22

文章目录 Fibonacci数列分析题目代码实现 Fibonacci数列 分析题目 首先我们可以通过三个变量进行移动来形成Fibonacci数列 其次我们通过最前面的变量与N进行比较从而固定数列 之后N和左右两个变量做差取最小值即可 代码实现 #include <iostream> using namespace std;…

pcdn技术如何降低网络延迟

PCDN技术通过以下方式降低网络延迟: 1.动态调度与负载均衡: PCDN通过在CDN的边缘节点上部署代理服务器&#xff0c;能够动态地调度和传输内容。当用户请求内容时&#xff0c; PCDN会根据各个节点的负载情况、距离、传输速度等因素来动态选择最优的节点来提供内容。这种动态调…

大语言模型-文本检索任务基准 BEIR

BEIR (A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models) 文本检索任务的基准&#xff0c;使用18 个数据集为检索系统的零样本评估提出了一个标准化基准&#xff0c; BEIR 基准上在9个不同领域的检索任务评估 10 种不同的检索方法。 九个…

剪画小程序:刷到好听的音频怎么将音频保存到手机里

在这个短视频盛行的时代&#xff0c;相信很多朋友都和我一样&#xff0c;常常会被那些精彩视频中的背景音乐深深吸引。 比如我&#xff0c;特别喜欢听歌&#xff0c;这段时间在短视频平台上刷到了好多好看的视频&#xff0c;里面的背景音乐简直绝绝子&#xff01; 那么&#x…

【Linux网络】epoll模型构建Reactor_Tcp服务器{协议/客户端/bind/智能指针}

文章目录 1.std::enable_shared_from_this<TcpServer>2.std::bind3.std::make_shared4.std::shared_ptrstd::shared_ptr 和 std::weak_ptr配合使用 5.剖析代码6.整体代码Calculator.hppClientCal.ccCMakeLists.txtCommon.hppEpoller.hppLog.hppMain.ccnocopy.hppProtocol…

RHCSA —— 第八节 (编辑器、编辑命令等)

Vi/vim编辑器 vim 编辑器 就是相当于在windows中创建一个记事本&#xff0c;一个word文档里面进行编辑所需要的内容。在linux中编辑文本文件&#xff0c;包括但不限于编辑源代码、配置文件、日志文件等文件内容。 三种模式 这是在编辑器中存在三种模式&#xff1a;命令模式、…

Linux 13:网络编程1

1. 预备知识 1-1. 理解源IP地址和目的IP地址 在IP数据包头部中&#xff0c;有两个IP地址&#xff0c;分别叫做源IP地址&#xff0c;和目的IP地址。 我们光有IP地址就可以完成通信了嘛&#xff1f;想象一下发qq消息的例子&#xff0c;有了IP地址能够把消息发送到对方的…

LeYOLO, New Scalable and Efficient CNN Architecture for Object Detection

LeYOLO, New Scalable and Efficient CNN Architecture for Object Detection 论文链接&#xff1a;http://arxiv.org/abs/2406.14239 代码链接&#xff1a;https://github.com/LilianHollard/LeYOLO 一、介绍 本文关注基于FLOP的高效目标检测计算的神经网络架构设计选择&am…

全新UI自助图文打印系统小程序源码/自助云打印机前后端源码

全新UI自助图文打印系统小程序源码&#xff0c;自助云打印机前后端源码。最新的自助图文打印系统和证件照云打印小程序源码采用了PHP作为后端开发语言&#xff0c;旨在为用户提供全面的自助打印服务。 这些服务覆盖了多种文件格式&#xff0c;包括文档、图片、表格等。除此之外…

Vue3 Composition API计算属性实现扁平化树节点的索引

本教程是Vue3 composition api计算属性活学活用&#xff08;作业题1 - 计算扁平化树树节点的索引&#xff09;的答案。通过该示例&#xff0c;让读者进一步巩固Vue3 Computed计算属性的最佳实践。 本作业题所使用的index计算属性在后续自定义Tree组件的高级功能实现中有着重要…

[经验] 孙叔敖举于海,百里奚举于市的翻译 #学习方法#学习方法#微信

孙叔敖举于海,百里奚举于市的翻译 1、孙叔敖举于海 孙叔敖&#xff0c;春秋时期鲁国大夫&#xff0c;是古代中国的著名政治家和军事家&#xff0c;他被誉为“孔子之后”的大贤。 孙叔敖的主要贡献在于他的外交策略和军事管理能力。在他的领导下&#xff0c;鲁国积极扩张其疆…