easypoi 多sheet导入_SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出easypoi...

67228c8b0033c103a6ded4b9eee55daa.png

有天上飞的概念,就要有落地的实现

  • 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍

  • 先赞后看,养成习惯

SpringBoot 图文教程系列文章目录

  1. SpringBoot图文教程1「概念+案例 思维导图」「基础篇上」

  2. SpringBoot图文教程2—日志的使用「logback」「log4j」

  3. SpringBoot图文教程3—「‘初恋’情结」集成Jsp

  4. SpringBoot图文教程4—SpringBoot 实现文件上传下载

  5. SpringBoot图文教程5—SpringBoot 中使用Aop

  6. SpringBoot图文教程6—SpringBoot中过滤器的使用

  7. SpringBoot图文教程7—SpringBoot拦截器的使用姿势这都有

  8. SpringBoot图文教程8 — SpringBoot集成MBG「代码生成器」

  9. SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」

前言

e515012db5c1a6d8ab8d6bd96230e076.png

上一篇文章中简单介绍了Poi的使用方式,但是用Poi去写代码着实繁琐了一些,假如你要实现的是复杂的需求,譬如:图片导出,多表数据导出,模板导出,大数据量导出等等,用最原生的Poi就不是很好的选择了。

难道要自己封装工具类了吗?

d223f6a79b10d9da1776d5ed49347a69.png

no no 轮子虽好,最好是别人写好的。所以从这篇文章开始介绍两个优秀的Poi工具 Easypoi 和 阿里开源的 EasyExcel。

EasyPoi

EasyPoi 是对poi封装的一个工具库,封装好了一些常见的Excel操作

  • 最基本的导入导出

  • 图片的导入导出

  • 多表数据的导入导出

  • 大批量数据的导入导出

  • 模板的导出

接下来我们一起来将以上的功能实现出来

官网地址:http://easypoi.mydoc.io/#category_50222

最基本的导入导出

最基本的导入导出,要导出的数据的实体类如下:

public class Teacher {
    /**
     * 老师的主键
     */
    private Integer teacherId;
    /**
     * 名字
     */
    private String teacherName;
    /**
     * 头像图片地址
     */
    private String teacherImage;
    /**
     * 老师的状态 0代表正常 1代表删除
     */
    private Integer teacherStatus;
}
 

省略get set

1.导入依赖
<dependency>
            <groupId>cn.afterturngroupId>
            <artifactId>easypoi-baseartifactId>
            <version>3.2.0version>
        dependency>
        <dependency>
            <groupId>cn.afterturngroupId>
            <artifactId>easypoi-webartifactId>
            <version>3.2.0version>
        dependency>
        <dependency>
            <groupId>cn.afterturngroupId>
            <artifactId>easypoi-annotationartifactId>
            <version>3.2.0version>
        dependency>
2.给要导出数据实体类加注解

我们要导出的数据的实体类是Teacher 所以需要给Teacher加 Easypoi的注解EasyPoi是注解式开发,所有的注解详情见官方文档,但是如果要完成的需求是最简单的导入导出的话,@Excel一个注解就足够了。

@Excel
这个是必须使用的注解,如果需求简单只使用这一个注解也是可以的,涵盖了常用的Excel需求,需要大家熟悉这个功能,主要分为基础,图片处理,时间处理,合并处理几块

@Excel 的官方api http://easypoi.mydoc.io/#text_186900

添加好注解的实体类如下:

96d3f7a1198c4e0e8df775e7d7a8ce86.png
3.直接使用 EasyPoi 中的工具类导入导出

EasyPoi 是注解式开发,对Excel所有的定义,样式也好,日期格式化也好,都是在实体类的注解中定义

导出代码
/**
     * easypoi导出
     */
    @Testpublic void test4() throws IOException {
//        模拟数据
        List list = new ArrayList<>();list.add(new Teacher(1,"李老师","hhh.jpg",1));list.add(new Teacher(2,"李老师","hhh.jpg",1));list.add(new Teacher(3,"李老师","hhh.jpg",1));list.add(new Teacher(4,"李老师","hhh.jpg",1));list.add(new Teacher(5,"李老师","hhh.jpg",1));list.add(new Teacher(6,"李老师","hhh.jpg",1));/**
         * 导出参数对象
         * 参数1 标题
         * 参数2 表的名字
         */
        ExportParams exportParams = new ExportParams("所有老师数据","teacher");/**
         * exportExcel 导出Excel文件
         * 参数1 导出参数对象
         * 参数2 要导出的实体类的类对象
         * 参数3 要导出的数据 需要一个集合  数据库查询出来的老师对象的集合
         *
         * 返回值就是封装好的文件对象
         */
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, Teacher.class, list);
        workbook.write(new FileOutputStream("/Users/lubingyang/Desktop/teachers.xls"));
    }

导出之后的Excel如下:

67c50dd994f0e47c88159ae8165eb3c8.png
导入代码

关于导入  没有需要单独定义的配置  只要能够导出就能够直接写导入的代码

 /**
     * easypoi导入
     */
    @Testpublic void test5() throws Exception {
        FileInputStream inputStream = new FileInputStream("/Users/lubingyang/Desktop/teachers.xls");
        /**
         * ImportParams 导入参数对象
         * 定义标题栏和表头数据
         */
        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(1);
        importParams.setHeadRows(1);
        /**
         * importExcel 导入方法
         * 参数1 流 读取要导入的文件
         * 参数2 要导入的实体类的类对象  老师对象的类对象
         * 参数3 导入参数对象
         *
         * 返回值 导入数据 直接封装为集合对象
         */
        List teachers = ExcelImportUtil.importExcel(inputStream, Teacher.class, importParams);for (Teacher teacher : teachers) {
            System.out.println(teacher);
        }
    }

值的替换 图片导入导出

值的替换
bbff7d1830001659044c0c73a43683bb.png

通过官方文档很容易找到如下内容

67b75baaf6808dc0b7a12ce70d17dc5c.png

根据文档修改实体类

684d4528bdc0dd6c9d66091ae9040ac0.png

执行导出代码 可以得到如下效果

fbedbd56fee12f13c95ab5814fdf1862.png
图片导出

修改实体类

e36f9217e56882b8396c0bc60f8b6e75.png

修改完之后可以直接导出

根据测试,如果图片地址字段存储的是相对路径,最好处理为网络绝对绝对路径或者本地绝对路径

图片导入

在实体类的注解上需要设置图片导入之后的保存路径

api

3acc81a620ee7164b481b658cad11bc5.png
822f7c8872064a837519156ae6c231ab.png

集合数据导入导出

在增加一个实体类 Student ,在Teacher类中有一个学生集合,导出Teacher的同时需要将Student的数据也导出,对应的数据库操作一般都是连表查询,那么这样的数据怎么导出到Excel呢?

实体类加注解

针对 Teacher 类集合属性的导入导出,需要给该属性加注解 @ExcelConllection
官方文档地址:http://easypoi.mydoc.io/#text_197841

6d6b9de6839554fe5848428d2a059756.png
ab5b62d5b0e675a3540a34d17c4f3422.png
导出代码如下
@Testpublic void test4() throws IOException {
        List students = new ArrayList<>();
        students.add(new Student("hh","男"));
        students.add(new Student("hh","男"));//        模拟数据
        List list = new ArrayList<>();list.add(new Teacher(1,"李老师","/Users/lubingyang/Desktop/hhh.jpg",1,students));list.add(new Teacher(6,"李老师","/Users/lubingyang/Desktop/hhh.jpg",1,students));/**
         * 导出参数对象
         * 参数1 标题
         * 参数2 表的名字
         */
        ExportParams exportParams = new ExportParams("所有老师数据","teacher");/**
         * exportExcel 导出Excel文件
         * 参数1 导出参数对象
         * 参数2 要导出的实体类的类对象
         * 参数3 要导出的数据 需要一个集合  数据库查询出来的老师对象的集合
         *
         * 返回值就是封装好的文件对象
         */
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, Teacher.class, list);
        workbook.write(new FileOutputStream("/Users/lubingyang/Desktop/teachers.xls"));
    }

效果如下

51af240a4a2f9805f56379e383a6f2ea.png

大批量数据导出(百万数据)

关于百万数据导出 推荐使用 阿里开源的 EasyExcel 官方介绍可以将内存控制在kb

大数据导出是当我们的导出数量在几万,到上百万的数据时,一次从数据库查询这么多数据加载到内存,然后写入会对我们的内存和CPU都产生压力,这个时候需要我们像分页一样处理导出,分段写入Excel缓解压力

EasyPoi提供的是两个方法 强制使用 xssf版本的Excel

/**
     * @param entity
     *            表格标题属性
     * @param pojoClass
     *            Excel对象Class
     * @param dataSet
     *            Excel对象数据List
     */
    public static Workbook exportBigExcel(ExportParams entity, Class> pojoClass,
                                          Collection> dataSet) {
        ExcelBatchExportServer batachServer = ExcelBatchExportServer
            .getExcelBatchExportServer(entity, pojoClass);
        return batachServer.appendData(dataSet);
    }

    public static void closeExportBigExcel() {
        ExcelBatchExportServer batachServer = ExcelBatchExportServer.getExcelBatchExportServer(null,
            null);
        batachServer.closeExportBigExcel();
    }

思路

  1. 分页读取数据

  2. 将每次读取到的数据写入Excel

实现代码

准备一个百万数据的用户表

82e24c8ee484f3a04e5e8e3ae7e770e3.png
 @Testpublic void test10() throws IOException {
        Date start = new Date();
//        查询数据库 用户表总条数
        Integer userCount = userDao.selectCount(null);
//        计算总页数
        Integer pageCount = userCount / 200000 + 1;

        List users = null;
        Workbook workbook = null;
        ExportParams params = new ExportParams("大数据测试", "测试");//        查询测试 页数  每次查询20w条数据for (int i = 1; i <= pageCount; i++) {
            System.out.println(i);
            users = userDao.selectPage(new Page<>(i, 200000), null).getRecords();//            通过 EasyPoi 的大数据导出方法 导出
            workbook = ExcelExportUtil.exportBigExcel(params, CmfzUser.class, users);
            users.clear();
        }
        Date end = new Date();
        System.out.println(new Date().getTime() - start.getTime());
        workbook.write(new FileOutputStream("/Users/lubingyang/Desktop/hhhh.xlsx"));
    }

执行的总时间为:

9ad9877eb7e3e522f1c218e2d0dcb7a3.png

Tips:

  1. 时间问题没做详细的性能测试 官方有相关的测试:http://easypoi.mydoc.io/#text_202983

  2. 数据库查询使用MybatisPlus 如果有兴趣 可以看我的相关文章 SpringBoot 集成 MybatisPlus

  3. 百万数据用 xssf 不如使用 CSV 和 SXSSF( POI针对大数据量的导出,专门提供了一个类)

模板导出

模板是处理复杂Excel的简单方法,复杂的Excel样式,可以用Excel直接编辑,完美的避开了代码编写样式的雷区,同时指令的支持,也提了模板的有效性。
EasyPoi支持的指令以及作用

空格分割
三目运算 {{test ? obj:obj2}}
n: 表示 这个cell是数值类型 {{n:}}
le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
fn: 格式化数字 {{fn:(obj;###.00)}}
fe: 遍历数据,创建row
!fe: 遍历数据不创建row$fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入#fe: 横向遍历
v_fe: 横向遍历值
!if: 删除当前列 {{!if:(test)}}
单引号表示常量值 '' 比如'1' 那么输出的就是 1
&NULL& 空格
]] 换行符 多行遍历导出
sum: 统计数据

采用的写法是{{}}代表表达式,然后根据表达式里面的数据取值

代码如下

示例代码所用模板文件地址:

a6327803a7ba91eb686a624fdd775d4d.png
    @Test
    public void fe_map() throws Exception {
//        读取模板文件
        TemplateExportParams params = new TemplateExportParams(
                "/Users/k/Desktop/专项支出用款申请书_map.xls");

//        模拟要写入模板的数据
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2014-12-25");
        map.put("money", 2000000.00);
        map.put("upperMoney", "贰佰万");
        map.put("company", "执笔潜行科技有限公司");
        map.put("bureau", "财政局");
        map.put("person", "JueYue");
        map.put("phone", "1879740****");
        List<Map<String, String>> listMap = new ArrayList<Map<String, String>>();
        for (int i = 0; i 4; i++) {
            Map<String, String> lm = new HashMap<String, String>();
            lm.put("id", i + 1 + "");
            lm.put("zijin", i * 10000 + "");
            lm.put("bianma", "A001");
            lm.put("mingcheng", "设计");
            lm.put("xiangmumingcheng", "EasyPoi " + i + "期");
            lm.put("quancheng", "开源项目");
            lm.put("sqje", i * 10000 + "");
            lm.put("hdje", i * 10000 + "");

            listMap.add(lm);
        }
        map.put("maplist", listMap);

//        导出模板
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);

        FileOutputStream fos = new FileOutputStream("/Users/k/Desktop/专项支出用款申请书111_map.xls");
        workbook.write(fos);
        fos.close();
    }

结果如下

a3e5c5b3369be6212b853fea0aab42af.png

总结

Tips:通过EasyPoi 基本上已经可以完成所有的Excel相关的工作

可以关注相关文章 poi 和 EasyExcel 以及 Poi中文 API 文档 「40种操作 Excel文件的姿势」

恭喜你完成了本章的学习,为你鼓掌!如果本文对你有帮助,请帮忙点赞,评论,转发,这对作者很重要,谢谢。

ca720f27bde6c50162cabc7d8ff83594.gif

让我们再次回顾本文的学习目标

  • 掌握SpringBoot中Easypoi的使用

要掌握SpringBoot更多的用法,请持续关注本系列教程。

求关注,求点赞,求转发

欢迎关注本人公众号:鹿老师的Java笔记,将在长期更新Java技术图文教程和视频教程,Java学习经验,Java面试经验以及Java实战开发经验。

5e5f07264c112967e309a8361b4f435e.png

点个在看,让更多人看到 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值