zoukankan      html  css  js  c++  java
  • excel导入导出

    • EasyExcel

    EasyExcel导入的用法

    实体类(员工表)

    @Data
    @ApiModel("员工")
    public class Employe {
    
        @ExcelIgnore
        private Integer id;
    
        @ExcelProperty(value = "姓名", index = 0)
        private String name;
    
        @ExcelProperty(value = "年龄", index = 1)
        private Integer age;
    
        @ExcelProperty(value = "生日", index = 2)
        @DateTimeFormat(value = "yyyy-MM-dd")
        private Date birth;
    }
    
    /**
    这里使用的是EasyExcel中@DateTimeFormat(value = "yyyy-MM-dd")注解。可以对Excel表中日期数据,进行格式处理。
    
    在此处有个小坑,“private Date birth;”这里birth是Date类型,所以数据库连接驱动要改成中国时间,如:“
    ?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC”要改为“
    ?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai”,不然下面测试数据,1997年10月1日到数据库后会变成1997-09-30;也可以将birth改为String类型,这样就不用改数据库连接驱动。
    **/
    

    controller层

    @RestController
    @RequestMapping("/employe")
    @Api(tags = "EmployeController", description = "员工管理")
    public class EmployeController {
    
        @Autowired
        private EmployeService employeService;
    
        @PostMapping("/importEmployeExcel")
        @ApiOperation("导入员工信息")
        public String importEmployeExcel(@ApiParam("导入的文件") @RequestBody MultipartFile file) {
            try {
                employeService.importEmployeExcel(file);
            } catch (Exception e) {
                e.printStackTrace();
                return "导入失败";
            }
            return "导入成功";
        }
    }
    

    service层

    @Service
    public class EmployeServiceImpl implements EmployeService {
    
        @Autowired
        private EmployeDao employeDao;
    
        @Override
        public void importEmployeExcel(MultipartFile file) throws Exception {
            EasyExcel.read(file.getInputStream(), Employe.class, new AnalysisEventListener<Employe>() {
    
                /**
                 * 批处理阈值,作用:减轻数据库的压力
                 */
                private static final int BATCH_COUNT = 2;
    
                /**
                 * 存储员工对象
                 */
                List<Employe> list = new ArrayList<Employe>(BATCH_COUNT);
    
                //easyExcel每次从Excel中读取一行数据就会调用一次invoke方法
                @Override
                public void invoke(Employe employe, AnalysisContext analysisContext) {
                    list.add(employe);
                    if (list.size() >= BATCH_COUNT) {
                     	employeDao.addBatch(list);
                        list.clear();
                    }
                }
    
                //easyExcel在将Excel表中数据读取完毕后,最终执行此方法
                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                    //最后,如果size<BATCH_COUNT就在这里进行数据的处理
                    if (list.size() > 0) {
                        employeDao.addBatch(list);
                    }
                }
            }).sheet().doRead();//sheet()参数指定,默认读取第一张工作表
        }
    }
    

    DAO层

    public interface EmployeDao {
        int addBatch(List<Employe> employes);
    }
    
    <?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.expect.easyexcel.user.dao.EmployeDao">
    
        <insert id="addBatch" parameterType="com.expect.easyexcel.user.domain.Employe">
            insert into employe values
            <foreach collection="list" item="employe" separator=",">
                (null,#{employe.name},#{employe.age},#{employe.birth})
            </foreach>
        </insert>
    
    </mapper>
    

    准备数据

    注意:表头必须加,EasyExcel是从第二行开始读取数据的,亲测过。

    数据库结果

    问题

    至此,我们导入数据的目的达到了,可是有个小小的问题,Service层使用了匿名内部内,造成程序略显臃肿,如果是大家,大家会用什么方法呢?

    1.首先,定义一个获取AnalysisEventListener对象的工具类
    
    public class EasyExcelUtils {
    
        /**
         * @param consumer   传入一个消费者接口对象,作用:业务逻辑处理
         * @param thresshold 批处理阈值,作用:减轻数据库的压力
         * @param <T>        实体类
         * @return
         */
        public static <T> AnalysisEventListener<T> getListener(Consumer<List<T>> consumer, int thresshold) {
            return new AnalysisEventListener<T>() {
                /**
                 * 存储员工对象
                 */
                List<T> list = new ArrayList<T>(thresshold);
    
                //easyExcel每次从Excel中读取一行数据就会调用一次invoke方法
                @Override
                public void invoke(T t, AnalysisContext analysisContext) {
                    list.add(t);
                    if (list.size() >= thresshold) {
                        consumer.accept(list);
                        list.clear();
                    }
                }
    
                //easyExcel在将Excel表中数据读取完毕后,最终执行此方法
                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                    //最后,如果size<thresshold就在这里进行数据的处理
                    if (list.size() > 0) {
                        consumer.accept(list);
                    }
                }
            };
        }
    }
    
    2.把Service层改写
    
    @Service
    public class EmployeServiceImpl implements EmployeService {
    
        @Autowired
        private EmployeDao employeDao;
    
        @Override
        public void importEmployeExcel(MultipartFile file) throws Exception {
            EasyExcel.read(file.getInputStream(),Employe.class, EasyExcelUtils.getListener(this.process(),2)).sheet().doRead();
        }
    
        public Consumer<List<Employe>> process(){
            return employes -> employeDao.addBatch(employes);
        }
    }
    
    
  • 相关阅读:
    centos7上以RPM方式安装MySQL5.6
    区别和详解:jQuery extend()和jQuery.fn.extend()
    jQuery笔记总结
    CSS Hack的一些知识
    12种不宜使用的javascript的语法
    64位Win7系统下vs2010调试无法连接oracle解决办法
    HashCode()与equals()深入理解
    Java ArrayList自动扩容机制
    Java基础知识
    MySQL的MVCC机制
  • 原文地址:https://www.cnblogs.com/kutoutuo/p/14181504.html
Copyright © 2011-2022 走看看