保姆级文件导入导出功能开发{POI || EasyExcel},还看不懂,你来咬我啊(一)

简介: 保姆级文件导入导出功能开发{POI || EasyExcel},还看不懂,你来咬我啊

1.前言


相信大家都应该看到过下面的功能:


20201120151018731.png


文件的导入导出:


这个功能主要就是帮助我们的用户能够快速的将数据导入到数据库中,不用在自己手动的一条一条的将数据新增到我们的数据库中.同时又能够方便我们能够将数据导出之后打印出来给领导们查看.不用非得带着电脑这里那里的跑.非常实用的功能.


功能好是好,但是这样的功能我们又应该怎么来开发呢,主要用到的技术又有那些呢?知道该用那些技术之后,我们又应该怎么来使用呢?相信大家肯定都有这样那样的困扰,正是因为大家有这样那样的困扰,所以就更加需要看看这篇文章了.这里我会用案例+代码+源码的方式带大家更好的学习这方面的知识.


文件的导入导出功能目前主要是两家独大,一个就是Apache的POI,另一家就是阿里的EasyExcel.这里两种技术我都会在下面的文章里面详细讲解.


2.POI:


2.1-POI介绍:


POI的全称是: Poor Obfuscation Implementation ,意思是可怜的模糊实现.说是可怜但是一点都不可怜.是由Apache公司用Java开发并且免费开源的一套Java Api.


它能够帮助我们简单快速的对Excel的数据进行读写的操作.他不仅支持Excel,同时也支持PowerPoint,Word等等,但是这两者我们就暂时不讲,我们主要需要了解的就是关于Excel的操作.


POI所需的依赖:


<!--        xls03版本-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
<!--        xlsx07版本-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>
<!--        日期格式化工具-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.1</version>
        </dependency>
<!--        test-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

2.2-03版Excel与07版Excel区别


在使用POI之前,我们需要先了解一下Excel的版本更替,这样能够方便我们更好的了解POI的使用.


这里面Excel主要就是有两类,分别是Excel03版本和Excel07版本


这两个版本之间主要有以下的差别:


两者数据量都是有限制的


03版本行数最多只能到65536,列数最多只能到256


03版本行数最多只能到1048576 ,列数最多只能到16384


03版本:


行数限制:


2020111711302048.png

列数限制:

9*29+22=256(简单的四则运算)

20201117113052892.png

07版本:

行数限制:

20201117113110973.png

列数限制:

20201117113130903.png

两者的文件名后缀也不一样,03版本的后缀是xls,07版本的后缀是xlsx,既然两者的后缀不一样就说明操作两者的工具类肯定也就是不一样的,这一点我们会在下面的代码中着重体现,其次就是 .xlsx文件比.xls的压缩率高,也就是相同数据量下,.xlsx的文件会小很多。


2.3-数据写入操作


知道上述两者的差异之后,才能更好的方便我们下面处理我们编写过程中可能遇到的bug.


其次在java中有一个非常重要的理念就是"万物皆对象",所以我们想要操作Excel表格的话,就要知道表格具体是由那些对象构成的.


20201117113149319.png


具体分下来主要就是图中标注出来的几种对象:工作簿,工作表,行,单元格

了解完有上述对象之后,我们就通过一个简单的案例来帮助大家更好的 了解这个概念.

具体代码实现:

  • 03版本-HSSFWorkbook:


 @Test
    public void  testExcel03() throws Exception{
        //创建一个工作簿
        Workbook workbook=new HSSFWorkbook();
        //创建一张工作表
        Sheet sheet=workbook.createSheet("我是一个新表格");
        //创建一行即(1,1)的单元格
        Row row1=sheet.createRow(0);
        Cell cell11=row1.createCell(0);
        //往该单元格中填充数据
        cell11.setCellValue("姓名");
        //创建(1,2)单元格
        Cell cell12=row1.createCell(1);
        cell12.setCellValue("印某人");
        Row row2=sheet.createRow(1);
        Cell cell21=row2.createCell(0);
        cell21.setCellValue("注册日期");
        Cell cell22=row2.createCell(1);
        String time=new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);
        //创建文件流
        FileOutputStream fileOutputStream=new FileOutputStream(PATH+"登记表03.xls");
        //把文件流写入到工作簿中
        workbook.write(fileOutputStream);
        //关闭文件流
        fileOutputStream.close();
        System.out.println("文件生成成功");
    }


运行完代码之后我们就可以看到我们的文件夹下面就生成了登记表03.xls这样一个文件


20201117113209111.png


打开文件之后我们也能发现,数据的确已经写进来了.


20201117113228581.png


  • 07版本-XSSFWorkbook:


@Test
    public void testExcel07()throws Exception{
        //注意只有这里创建的对象是不一样的!!!!!
        Workbook workbook=new XSSFWorkbook();
        Sheet sheet=workbook.createSheet("我是一个新表格");
        Row row1=sheet.createRow(0);
        Cell cell11=row1.createCell(0);
        cell11.setCellValue("姓名");
        Cell cell12=row1.createCell(1);
        cell12.setCellValue("印某人");
        Row row2=sheet.createRow(1);
        Cell cell21=row2.createCell(0);
        cell21.setCellValue("注册日期");
        Cell cell22=row2.createCell(1);
        String time=new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);
        FileOutputStream fileOutputStream=new FileOutputStream(PATH+"登记表07.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        System.out.println("文件生成成功");
    }

可以看到在上面的代码中我们除了修改了创建的对象之外,其他的代码,我们都是没有修改的.本质操作都是一致的.


2.4-HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook大数据量下写入速度对比


我们了解了基本的写入数据的流程之后,接下来我们测试一下,在大数据量的情况下,他们生成相应的文件需要多长的时间,看看他们两者的性能又是如何的.顺便我们也了解一下他们写入数据的整个流程.


03版本-HSSFWorkbook:


@Test
    public void test03BigData()throws Exception{
        Long begin=System.currentTimeMillis();
        Workbook workbook=new HSSFWorkbook();
        Sheet sheet=workbook.createSheet();
        for(int rownum=0;rownum<65536;rownum++){
            Row row=sheet.createRow(rownum);
            for(int cellnum=0;cellnum<10;cellnum++){
                Cell cell=row.createCell(cellnum);
                cell.setCellValue(cellnum);
            }
        }
        FileOutputStream fileOutputStream=new FileOutputStream(PATH+"test03BigData.xls");
        workbook.write(fileOutputStream);
        System.out.println("文件生成完毕");
        Long end=System.currentTimeMillis();
        System.out.println("共用时:"+(double)(end-begin)/1000+"秒");
    }


这里我们运行完成之后可以看到一共运行了1.811秒,还是很快的


20201117113247161.png


但是就上我们上面所说的一样,03版本的只支持最多65536条数据,如果超过这个数据量的话,是会报这个错的: Invalid row number (65536) outside allowable range (0…65535) ,这里我们运行测试一下看一下报错:


20201117113303941.png


看完他的运行速度之后我们来看看,为什么HSSFWorkbook能够这么快就能将数据写入到文件中呢.


因为HSSFworkbook是直接将整个文件写入到内存中的,文件直接就能从内存中读到,所以使得整个写入的过程十分的快速.既然选择写入内存里面,那么就会出现一个问题那就是内存不够,直接就爆了,严重影响性能,所以可能是出于这个问题的考虑,03版本才会限制数据的条数(后面部分是我自己猜的,嘤嘤嘤)


2020112018545472.png


07版本-XSSFWorkbook:


 @Test
    public void test07BigData()throws Exception{
        Long begin=System.currentTimeMillis();
        Workbook workbook=new XSSFWorkbook();
        Sheet sheet=workbook.createSheet();
        for(int rownum=0;rownum<65537;rownum++){
            Row row=sheet.createRow(rownum);
            for(int cellnum=0;cellnum<10;cellnum++){
                Cell cell=row.createCell(cellnum);
                cell.setCellValue(cellnum);
            }
        }
        FileOutputStream fileOutputStream=new FileOutputStream(PATH+"test07BigData.xlsx");
        workbook.write(fileOutputStream);
        System.out.println("文件生成完毕");
        Long end=System.currentTimeMillis();
        System.out.println("共用时:"+(double)(end-begin)/1000+"秒");
    }


相关文章
|
数据采集 人工智能 数据处理
覆盖16省方言的老人语音数据集!SeniorTalk:智源研究院开源全球首个超高龄老年人中文语音数据集
SeniorTalk是由智源研究院与南开大学联合推出的全球首个中文超高龄老年人对话语音数据集,包含202位75岁及以上老年人的55.53小时语音数据,涵盖16个省市的不同地域口音。
1723 5
覆盖16省方言的老人语音数据集!SeniorTalk:智源研究院开源全球首个超高龄老年人中文语音数据集
|
前端开发 Java 关系型数据库
Java中的电子商务网站开发实战
Java中的电子商务网站开发实战
|
存储 前端开发 JavaScript
VSCode调试揭秘:Live Server助力完美测试Cookie与Session,远超“Open in Browser“!
VSCode调试揭秘:Live Server助力完美测试Cookie与Session,远超“Open in Browser“!
|
前端开发 Java API
Spring Boot与GraphQL的集成
Spring Boot与GraphQL的集成
|
Python Windows
Windows安装pip和pygame详细教程(附国内下载地址)
Windows安装pip和pygame详细教程(附国内下载地址)
1190 0
|
数据采集 供应链 程序员
制造企业实施MES系统受到的影响因素有哪些?
在当前MES产品化程度普遍不高的大环境下,对项目及管理软件本身认知过于简单,且缺失有经验行业人才,是当前大部分MES系统影响交付的主要原因。
制造企业实施MES系统受到的影响因素有哪些?
|
12天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23475 11
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
16天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
5219 19
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病