• EasyExcel实现文件上传-批量插入 文件下载


    传统的excel处理工具(apache poi、jxl等)严重消耗内存(3兆的文件一般需要100兆的内存),在并发量大或者数据量很大时,容易发生内存溢出(OOM)、jvm频繁full gc;

    easyexcel重写了poi对07版Excel的解析,减少了内存消耗;同时对模型转换进行封装,简化了用户使用

    传统excel解析工具将所有数据一次性加载到内存进行解析,解析完成后返回数据;

    easyexcel没有将数据一次性加载到内存,而是在磁盘上一行一行读取,逐个解析;

    将解析结果通过观察者模式返回,交给程序进行后续处理;

    解析时丢弃一些不重要的数据(宽度、样式、字体等),节省了内存消耗
     

     文件上传

     1,导入pom依赖 

    
        3.0.5
    
    
        com.alibaba
        easyexcel
        ${easyexcel.version}
    
    

     2,编写Excel表的实体类

     

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public class Tcinfos {
            //主键自增
        @TableId(type = IdType.AUTO)
           //忽略下面的id
        @ExcelIgnore
        private Integer tcid;
        @ExcelProperty("吊塔类型")
        private String type;
        @JsonFormat(pattern = "yyyy-MM-dd")//取日期时使用
        @DateTimeFormat(pattern = "yyyy-MM-dd")//存日期时使用
        @ExcelProperty("建造日期")
        private Date makedate;
        @ExcelProperty("最大高度")
        private Integer maxhigh;
        @ExcelProperty("最大幅度")
        private Integer maxrange;
        @ExcelProperty("最大载重")
        private Integer maxweight;
        @ExcelProperty("安全员工号")
        private Integer secman;
        @ExcelProperty("负责人工号")
        private Integer resman;
    }
    

     3.配置监听器类ExcelReadListener

    package com.kgc.towercrane.tcmanager.common;
    
    import com.alibaba.excel.context.AnalysisContext;
    import com.alibaba.excel.event.AnalysisEventListener;
    import com.kgc.towercrane.tcmanager.domian.module.Tcinfos;
    import com.kgc.towercrane.tcmanager.mapper.TCinfosMapper;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ExcelReadListener extends AnalysisEventListener {
        //定义批量  每次读取500行数据  最合适可以3000
        private static final int BATCH_SIZE=500;
        //创建一个全局集合 每次读取数据存入其中
        private List tcs=new ArrayList<>();
    
        //定义一个mapper接口属性
        private TCinfosMapper tCinfosMapperss;
    
        //创建一个有参构造 方便在controller层传入mapper接口
        public ExcelReadListener(TCinfosMapper tcinfos){
            this.tCinfosMapperss=tcinfos;
        }
        /**
         * 每读一行 自动触发invoke方法
         * @param tcinfos
         * @param analysisContext
         * 
         */
        @Override
        public void invoke(Tcinfos tcinfos, AnalysisContext analysisContext) {
            System.out.println(tcinfos);
            //读取数据到集合
            tcs.add(tcinfos);
            //判断集合有木有到500
            if(tcs.size()>=BATCH_SIZE){
                //读取到的数据大于等于500  插入500条数据到mysql数据库
                tCinfosMapperss.batchSaveTcInfo(tcs);
                //清空集合
                tcs.clear();
            }
    
        }
    
        /**
         * 文件读完后触发doAfterAllAndLysed一次
         * 假设数据量是3490条 invoke方法每500跳插入一次
         * 最后一条还剩490就不会插入 我们在这个方法手动在保存一次
         * 插入最后的490跳
         * @param analysisContext
         */
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("文件读完后再触发一次!!");
            tCinfosMapperss.batchSaveTcInfo(tcs);
            tcs.clear();
        }
    }
    

    4.配置controller层

    @RestController
    @RequestMapping("/tcinfo")
    public class TcinfosCtrl {
     
    /**
     * 2 批量插入
     * @param file
     * @return
     */
    
    @PostMapping(value ="/batchTowerCrane")
    public String batchTc(MultipartFile file){
        tcinfoStoreService.batch_save(file);
        return BackinfoConf.BATCHADDTC_SUCCESS;
    }
    }
    

    5. 配置service层

    #接口

    /**
     * 上传文件 读取文件内容
     * 并批量保存数据
     * @param file
     */
    void batch_save(MultipartFile file);

    #实现类

    @Transactional
    @Override
    public void batch_save(MultipartFile file) {
    
    @Resource
    private TCinfosMapper tCinfosMapper;
        try {
            //new ExcelReadListener调用他的有参构造  注入mapper对象
            EasyExcel.read(file.getInputStream(),Tcinfos.class,new ExcelReadListener(tCinfosMapper)).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    }

    6. 配置mapper层 

    #接口
    @Mapper
    //使用mybatis-plus实现crud
    public interface TCinfosMapper extends BaseMapper {
       //对于传进来的数组批量插入数据库
       void batchSaveTcInfo(List tc);
    }
    
    #配置mapper.xml 批量插入 使用动态sql
    
    
    
    
        
                insert into tcinfos
                (type,makedate,maxhigh,maxrange,maxweight,secman,resman) values
                
                    (#{tc.type},#{tc.makedate},#{tc.maxhigh},#{tc.maxrange},#{tc.maxweight},#{tc.secman},#{tc.resman})
                
        
    

    文件上传就完成了!!测试接口即可 


     文件下载

    1.配置controller层

    @RestController
    @RequestMapping("/tcinfo")
    public class TcinfosCtrl {
    @Resource
    private TcinfoStoreService tcinfoStoreService;
    //   5  数据库获取数据 在转为excel文件 然后再给用户文件下载
    //    @Parame 回写文件信息对象
        @GetMapping(value ="/downloadTowerCrane")
        public void downloadTcinfo(HttpServletResponse response) throws IOException {
            //用于下载的流
            ServletOutputStream sos = response.getOutputStream();
            //用户生成网页的流  前端可以直接从后端获得一个生成好的网页
            // PrintWriter out = response.getWriter();
            //获取所有的塔吊信息
            List tcs = tcinfoStoreService.findAllTc();
            //下载文件名
            String downloadExcelFile="塔吊信息.xlsx";
            //准备回传response头部信息
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(downloadExcelFile, "UTF-8").replaceAll("\\+", "%20"));
            //向客户端发送
            EasyExcel.write(sos,Tcinfos.class)
                    .sheet("塔吊基础信息")
                    .doWrite(tcs);
            //写完后关闭流
            sos.close();
        }

    }

     2.配置service层

    #接口

    public interface TcinfoStoreService {
    /**
     * 下载所有塔机资料
     * @return
     */
    List findAllTc();

    }

    #实现类

    @Service
    public class TcinfoStoreServiceImpl implements TcinfoStoreService {
        @Resource
        private TCinfosMapper tCinfosMapper;
    /**
     * 查询所有塔吊信息
     */
    public List findAllTc(){
        return tCinfosMapper.selectList(null);
    }

    }

    3.配置mapper层

    @Mapper
    //使用mybatis-plus实现基础的CRUD
    public interface TCinfosMapper extends BaseMapper {
       //对于传进来的数组批量插入数据库
       void batchSaveTcInfo(List tc);
    }

     下载就完成了 测试接口即可!!!

     


     

     

  • 相关阅读:
    逆向-beginners之数组溢出
    优先队列题目:滑动窗口最大值
    Oracle数据库中的集合(联合数组,嵌套表和可变数组)
    My Forty-fifth - Page - 修剪二叉搜索树- By Nicolas
    React-hooks
    整理了2022百度上最全涨粉技巧,宝宝们,100种涨粉技巧供给选择。
    【uni-app】常用组件和 API
    力扣 | 2582递枕头 | 取余?滑动窗口?异曲同工?
    3D设计软件Rhinoceros 6 mac 犀牛6中文版功能特征
    MyBatisPlus的使用【详细】
  • 原文地址:https://blog.csdn.net/just_learing/article/details/125903031