zoukankan      html  css  js  c++  java
  • 使用EsayExcel 实现 web上传excel文件(读取excel文件)

    使用EsayExcel 实现 web上传excel文件(读取excel文件)

    1.创建项目、添加依赖

    
      <!-- 官方文档  https://www.yuque.com/easyexcel/doc/read#1bfaf593 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>2.2.10</version>
            </dependency>
            <!-- 模板引擎 类似jsp  -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    

    2. 上传表单

    这里用到了 thymeleaf

    <!DOCTYPE html>
    <!-- 需要添加
    <html  xmlns:th="http://www.thymeleaf.org">
    这样在后面的th标签就不会报错
     -->
    <html  xmlns:th="http://www.thymeleaf.org">
    <head lang="en">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    </head>
    <body>
    
    
    <h1>表单提交  上传一个excel   </h1>
    <h2>Demo   在项目resouces 目录下</h2>
    <!-- 表单提交用户信息,注意字段的设置,直接是*{} -->
    <form action="#" th:action="@{/upload}" enctype="multipart/form-data" method="post">
        <input type="file" name="file" value="文件上传" />
        <input type="submit" />
    </form>
    </body>
    </html>
    

    3.配置文件

    spring:
      thymeleaf:
        enabled: true  #开启thymeleaf视图解析
        encoding: utf-8  #编码
        prefix: classpath:/templates/  #前缀
        cache: false  #是否使用缓存
        mode: HTML  #严格的HTML语法模式
        suffix: .html  #后缀名
    server:
      port: 80
    

    4.源码

    package com.example.excelupload.demo;
    
    import com.alibaba.excel.EasyExcel;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    
    /**
     *
     * @description
     * @create 2021/6/25 13:52
     */
    @Controller
    public class DemoController {
    
        @Autowired
        DemoDAO demoDAO;
        @GetMapping("")
        public String index() {
            return "index";
        }
    
        /**
         * 文件上传
         * <p>
         * 1. 创建excel对应的实体对象
         * <p>
         * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器
         * <p>
         * 3. 直接读即可
         */
        @PostMapping("upload")
        @ResponseBody
        public String upload(MultipartFile file) throws IOException {
            EasyExcel.read(file.getInputStream(), DemoData.class, new DemoDataListener(demoDAO)).sheet().doRead();
            return "success";
        }
    }
    
    
    package com.example.excelupload.demo;
    
    /**
     *
     * @description
     * @create 2021/6/25 13:55
     */
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    /**
     * 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。
     **/
    @Slf4j
    @Component
    public class DemoDAO {
        public void save(List<DemoData> list) {
            // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
            log.info("模拟批量insert"  );
        }
    }
    
    
    package com.example.excelupload.demo;
    
    import lombok.Data;
    
    import java.util.Date;
    
    /**
    
     * @description
     * @create 2021/6/25 13:53
     */
    
    @Data
    public class DemoData {
       private String string;
       private Date date;
       private Double doubleData;
    }
    
    package com.example.excelupload.demo;
    
    import com.alibaba.excel.context.AnalysisContext;
    import com.alibaba.excel.event.AnalysisEventListener;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @description
     * @create 2021/6/25 13:54
     */
    // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
    public class DemoDataListener extends AnalysisEventListener<DemoData> {
        private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
    
        /**
         * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
         */
        private static final int BATCH_COUNT = 5;
        List<DemoData> list = new ArrayList<DemoData>();
        /**
         * 假设这个是一个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(DemoData data, AnalysisContext context) {
            LOGGER.info("解析到一条数据:{}", data.toString());
            list.add(data);
            // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
            if (list.size() >= BATCH_COUNT) {
                //入库操作
                saveData();
                // 存储完成清理 list
                list.clear();
            }
        }
    
        /**
         * 所有数据解析完成了 都会来调用
         *
         * @param context
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            // 这里也要保存数据,确保最后遗留的数据也存储到数据库
            saveData();
            LOGGER.info("所有数据解析完成!");
        }
    
        /**
         * 加上存储数据库
         */
        private void saveData() {
            LOGGER.info("{}条数据,开始存储数据库!", list.size());
            demoDAO.save(list);
            LOGGER.info("存储数据库成功!");
        }
    }
    

    5.启动项目上传demo.xlsx

    直接访问127.0.0.1

    demo.xlsx在 项目目录resouces目录下

    选择上传。

    控制台解析到excel内的数据。

    源码地址: https://gitee.com/confectionary/excelUpload.git

  • 相关阅读:
    PyCharm2019激活
    实时统计每天pv,uv的sparkStreaming结合redis结果存入mysql供前端展示
    Python批量删除mysql中千万级大量数据
    SpringBoot + thymeleaf 实现分页
    适合用设计模式解决的问题场景
    重新理解面向过程和面向对象编程
    优化前端单页面应用性能指南
    使用ts开发vue项目知识点1
    职场人的核心竞争力应该是什么
    重新理解原型链
  • 原文地址:https://www.cnblogs.com/paidaxing7090/p/14930990.html
Copyright © 2011-2022 走看看