保姆级文件导入导出功能开发{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+"秒");
    }


相关文章
|
6月前
|
存储 运维 监控
SelectDB 实现日志高效存储与实时分析,完成任务可领取积分、餐具套装/水杯/帆布包!
SelectDB 实现日志高效存储与实时分析,完成任务可领取积分、餐具套装/水杯/帆布包!
|
前端开发 Java 关系型数据库
Java中的电子商务网站开发实战
Java中的电子商务网站开发实战
|
存储 前端开发 JavaScript
VSCode调试揭秘:Live Server助力完美测试Cookie与Session,远超“Open in Browser“!
VSCode调试揭秘:Live Server助力完美测试Cookie与Session,远超“Open in Browser“!
|
JSON 监控 测试技术
Groovy脚本编写员工上网行为监控自动化测试
本文介绍了如何使用Groovy脚本创建一个自动化工具来监控员工的网络活动。通过编写简单脚本记录员工访问的网站并打印信息,可进一步扩展为将数据保存至数据库。此外,通过设定定时任务,实现了每30分钟自动监控一次的功能。最后,展示了如何将监控数据转换为JSON格式并使用HTTP POST请求提交到网站,以实现数据的自动化上报,有助于企业保障网络安全、保护数据并提升工作效率。
267 5
|
前端开发 Java API
Spring Boot与GraphQL的集成
Spring Boot与GraphQL的集成
|
存储 达摩院
「达摩院MindOpt」线性规划用于排程排程问题(03)
比上一篇问题02中,我们只考虑了一次性的采购和生产计划,实际中的排产排程问题要更加复杂和精细。例如,我们要考虑未来三个月内采购和排产排程计划。其中,原材料每个月的采买价格均有不同,并且原材料购买后的存储也需要成本开销。在本节中,我们将考虑这样一个相对复杂的排产排程的决策问题。
「达摩院MindOpt」线性规划用于排程排程问题(03)
|
Java 数据库连接 数据处理
实时计算 Flink版产品使用合集之是否支持将数据直接写入adb
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
存储 Java Android开发
制作内置XPosed模块应用(详细教程,有手就会,无需Root即可使用)
众所周知,如今许多的安卓app,为了获利,为了赚钱,为了老板买别墅换豪车,加入了非常多的广告及推广内容以及软件模块。随着安卓的时代发展,Xposed的出现,在一定程度上改变了这种困境。
4859 0
|
弹性计算 运维 Cloud Native
Serverless的优势
Serverless的优势自制脑图, 开发者只需专注代码开发,无需在各个云资源控制台手动开通服务和配置管理,并能够根据业务请求自动进行弹性伸缩;支持用户按需付费,成本较低;开发周期快,很大程度上提升了开发、部署的效率。
245 0
Serverless的优势
|
域名解析 数据采集 运维
阿里云AIoT物联网平台如何实现设备全球就近接入
对于物联网平台,设备上云是第一步,也是至关重要的一步,那阿里云AIoT物联网平台如何实现设备全球就近接入的呢,设备分发服务将为您解答。
1175 3