poi工具读写excel操作学习总结

写在前面的话

        POI作为比较早期的Excel处理工具,其使用较为成熟且广泛。EasyExcel相较之下,则是相对较新的工具,其却有着比POI更为优越的一些特性,如更加简单的API接口和更加优秀的性能。

        性能对比:在数据量较小的情况下,POI和EasyExcel的性能表现较为相似,但在数据量较大的情况下,EasyExcel要比POI具有更快的速度。这主要得益于EasyExcel内部优化的使用反射技术,避免了POI中频繁创建Cell和Row等对象时的性能问题。

        API对比:在API接口使用上,EasyExcel相较于POI也更为简单直观。POI的API接口使用较为繁琐,需要使用大量的行列、坐标等信息来操作Excel表格数据,而EasyExcel则将其进行了封装和优化,使其更加易用和方便。

        简单易用性对比:EasyExcel相较于POI也更具有易用性和灵活性。EasyExcel的代码量较POI更少并且更为优美,使得开发者能够更容易的上手使用和进行二次封装,同时EasyExcel还支持自定义注解的方式进行Excel表格数据和Java对象之间的映射关系,使其在应用场景上更加丰富多彩。

        其他方面的对比:POI和EasyExcel也有着各自的优缺点。如在对于老版本的Excel文件的支持上,POI更胜一筹;而在对于较为复杂的Excel表格数据处理方面,POI则有着更多的功能和接口可供探索,EasyExcel的功能相对较为局限。

1.poi简单写操作

        03版本,结尾是:.xls,03和07版本的主要区别是能写的数据量大小,03版本只能写65536行,07版本基本没限制。03版本对象是:HSSFWorkbook。07版本对象是:XSSFWorkbook。

/*** poi,excel03版本* @throws IOException*/@Testpublic void test03() throws IOException {String PATH = "D:\\code\\excel";//首先创建一个工作簿HSSFWorkbook work = new HSSFWorkbook();//然后创建一个工作表HSSFSheet sheet = work.createSheet("weiqinag");//其次创建一个行(1,1)HSSFRow row = sheet.createRow(0);//其次再创建一个单元格,坐标(1,1)单元格HSSFCell cell11 = row.createCell(0);cell11.setCellValue("我是第一个单元格");//坐标(1,2)单元格HSSFCell cell12 = row.createCell(1);cell12.setCellValue("我是第一行第二个单元格");//坐标(2,1)HSSFRow row1 = sheet.createRow(1);HSSFCell cell21 = row1.createCell(0);cell21.setCellValue("我是第二行一个单元格");//坐标(2,2)HSSFCell cell22 = row1.createCell(1);String string = new DateTime().toString("yyyy-MM--dd HH:mm:ss");cell22.setCellValue(string);//生成一张表(IO)流,03版本的是xls结尾FileOutputStream fileOutputStream = new FileOutputStream(PATH +"\\"+"weiqiang03.xls");work.write(fileOutputStream);//关闭流fileOutputStream.close();System.out.println("excel生成完毕");}

        07版本,结尾是:.xlsx

        可以看到只是对象变化了,03版本的对象是 HSSFWorkbook,07版本的对象是XSSFWorkbook,接口没有变化,这就是面向对象的好处之一。

@Testpublic void test07()throws Exception{String PATH = "D:\\code\\excel";//首先创建一个工作簿07版本XSSFWorkbook work = new XSSFWorkbook();//然后创建一个工作表Sheet sheet = work.createSheet();//其次创建一个行(1,1)Row row = sheet.createRow(0);//其次再创建一个单元格,坐标(1,1)单元格Cell cell11 = row.createCell(0);cell11.setCellValue("我是第一个单元格");//坐标(1,2)单元格Cell cell12 = row.createCell(1);cell12.setCellValue("我是第一行第二个单元格");//坐标(2,1)Row row1 = sheet.createRow(1);Cell cell21 = row1.createCell(0);cell21.setCellValue("我是第二行一个单元格");//坐标(2,2)Cell cell22 = row1.createCell(1);String string = new DateTime().toString("yyyy-MM--dd HH:mm:ss");cell22.setCellValue(string);//生成一张表(IO)流,03版本的是xlsx结尾FileOutputStream fileOutputStream = new FileOutputStream(PATH +"\\"+"weiqiang07.xlsx");work.write(fileOutputStream);//关闭流fileOutputStream.close();System.out.println("excel生成完毕");}

2.大文件写操作

        对于大文件写操作来说,03版本的缺点是最多处理65536行,否则会排除异常,优点是过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快。

        07版本的缺点是写数据非常慢,非常耗内存,会发生内存溢出的异常,如100万条,优点是可以写较大的数据量,如20万条,远远大于03版本的65536行。

2.1 03版本大文件写

        HSSFWorkbook对象大数据写操作,总耗时是1.3秒左右,很快。

@Testpublic void test03BigData() throws IOException {String PATH = "D:\\code\\excel";long begin = System.currentTimeMillis();HSSFWorkbook 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);}}System.out.println("循环完毕,开始写");FileOutputStream fileOutputStream = new FileOutputStream(PATH+"\\"+"bigDate.xls");workbook.write(fileOutputStream);fileOutputStream.close();long end = System.currentTimeMillis();System.out.println("消耗时间:"+(double)(end - begin)/1000);}

2.2 07版本大文件写

        XSSFWorkbook对象大数据写操作,总耗时达到6.5秒左右,很慢。

 @Testpublic void test07BigData() throws IOException {long begin = System.currentTimeMillis();String PATH = "D:\\code\\excel";XSSFWorkbook workbook = new XSSFWorkbook();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);}}System.out.println("循环结束,开始写操作");FileOutputStream fileOutputStream = new FileOutputStream(PATH + "\\" + "bigdate07.xlsx");workbook.write(fileOutputStream);fileOutputStream.close();long end = System.currentTimeMillis();System.out.println("消耗时间:" + (double) (end - begin) / 1000);}

2.2 SXSSF大文件写操作

        根据前两个比较,03版本虽然快,但是数据量有限制,07版本的数量大,但是速度慢,那有没有速度快又写入数据量大的对象呢?有,那就是SXSSF对象,他可以写非常大的数据量,如100万条以上,写数据速度快,占用内存更少。写数据100000行,用时2.5秒左右。是不是非常快,还要记得一点,利用SXSSF对象会有临时文件产生,需要清除临时文件。

@Testpublic void testBigData() throws IOException {long begin = System.currentTimeMillis();String PATH = "D:\\code\\excel";SXSSFWorkbook workbook = new SXSSFWorkbook();Sheet sheet = workbook.createSheet();for (int rowNum = 0; rowNum < 100000; rowNum++) {Row row = sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("循环结束,开始写输出流写操作");FileOutputStream fileOutputStream = new FileOutputStream(PATH + "\\" + "bigdate.xlsx");workbook.write(fileOutputStream);fileOutputStream.close();//清除临时文件((SXSSFWorkbook)workbook).dispose();long end = System.currentTimeMillis();System.out.println("消耗时间:" + (double) (end - begin) / 1000);}

3.读操作

3.1 03版本excel表的读操作

        读操作,首先获取文件流,然后把流放入工作簿中,其次得到这个表,再得到行和列,最后得到行列坐标的值。读取值的时候一定要注意值的类型,否则出错。

  @Testpublic void testRead03() throws IOException {String PATH = "D:\\code\\excel";//获取文件流FileInputStream fileInputStream = new FileInputStream(PATH + "\\" + "weiqiang03.xls");//首先创建一个工作簿,把流放到工作簿里HSSFWorkbook work = new HSSFWorkbook(fileInputStream);//然后得到表Sheet sheet = work.getSheetAt(0);//得到行和得到列Cell cell = sheet.getRow(0).getCell(0);//得到坐标的值System.out.println(cell.getStringCellValue());}

3.2  07版本excel表读操作        

        只需要换对象即可

  @Testpublic void testRead03() throws IOException {String PATH = "D:\\code\\excel";//获取文件流FileInputStream fileInputStream = new FileInputStream(PATH + "\\" + "weiqiang03.xls");//首先创建一个工作簿,把流放到工作簿里XSSFWorkbook work = new XSSFWorkbook(fileInputStream);//然后得到表Sheet sheet = work.getSheetAt(0);//得到行和得到列Cell cell = sheet.getRow(0).getCell(0);//得到坐标的值System.out.println(cell.getStringCellValue());}

3.3 读取不同类型的数据(难点)

 /*** 把该类封装成工具类,直接调用该方法时,传递参数fileInputStream就行了* @param fileInputStream* @throws Exception*/@Testpublic void testRead(FileInputStream fileInputStream)throws Exception{String PATH = "D:\\code\\excel";//首先获取文件流,读取哪个文件
//         fileInputStream = new FileInputStream(PATH + "\\" + "03.xls");//首先创建一个工作簿07版本进行读,也可以用03版本读取,但是03文件是xls,所以用03版本读取HSSFWorkbook work = new HSSFWorkbook(fileInputStream);//然后获取这工作表Sheet sheetAt = work.getSheetAt(0);//获取第一行,就是标题Row rowTitle = sheetAt.getRow(0);//获取第一行的所有标题if (rowTitle != null) {//获取第一行所有的列int cellCount = rowTitle.getPhysicalNumberOfCells();//遍历,取出每列的内容,就是具体标题for (int cellNum = 0; cellNum < cellCount; cellNum++) {//获取列Cell cell = rowTitle.getCell(cellNum);if (cell != null) {//获取列类型int cellType = cell.getCellType();//现在默认是是String类型,一般第一行都是字符串String stringCellValue = cell.getStringCellValue();System.out.print(stringCellValue+" | ");}}System.out.println();}//获取表中的内容,先获取所有的行int rows = sheetAt.getPhysicalNumberOfRows();//rowNum =1 是从第二行开始,第一行是标题for (int rowNum = 1; rowNum < rows; rowNum++) {//获取每行的数据Row rowData = sheetAt.getRow(rowNum);//读取列,每行的每列if (rowData != null) {int cells = rowTitle.getPhysicalNumberOfCells();for (int cellsNum = 0; cellsNum < cells; cellsNum++) {System.out.print("["+(rowNum+1)+"-"+(cellsNum+1)+"]");//拿到每行每列的数据Cell cell = rowData.getCell(cellsNum);//匹配列的数据类型if (cell != null) {CellType cellType = cell.getCellTypeEnum();String cellValue= "";switch (cellType) {case STRING:System.out.print("String类型");cellValue = cell.getStringCellValue();break;case BOOLEAN:System.out.print("布尔类型");cellValue = String.valueOf(cell.getBooleanCellValue());break;case BLANK:System.out.print("空格");break;case NUMERIC:System.out.print("数字类型");//需要区分是数字还是日期if (HSSFDateUtil.isCellDateFormatted(cell)) {System.out.print("日期");Date date = cell.getDateCellValue();cellValue = new DateTime(date).toString("yyyy-MM--dd");} else {//不是日期格式,防止数字过长System.out.print("转换为字符串输出");cell.setCellType(CellType.STRING);cellValue = cell.toString();}break;case ERROR:System.out.print("数据类型错误");break;}System.out.println(cellValue);}}}}fileInputStream.close();}

4.EasyExcel读写操作

        学习完poi操作Excel后,感觉是有一些困难,不太方便,所以继续学习阿里巴巴开源下的EasyExcel工具,该工具就是简单高效,会发现代码很简洁。

4.1准备一个Student类

@Data
//@ContentRowHeight(20)//内容行高
//@HeadRowHeight//表头行高
public class Student {@ExcelProperty(value = "ID",index = 4)//表头顺序@ExcelIgnoreprivate Integer sno;@ExcelProperty("姓名")private String sname;@ExcelProperty("年龄")@ColumnWidth(20)private Integer sage;@ExcelProperty("性别")private String ssex;@DateTimeFormat("yyyy-MM-dd")private Date birthday;
}

4.2 EasyExcel读操作

public class StudentListener extends AnalysisEventListener<Student> {/*** 读监听器,每读一行内容,都会调用一次该对象的invoke,在invoke中可以操作使用读取到的数据。* @param student 每次读取到的数据封装对象* @param analysisContext*/@Overridepublic void invoke(Student student, AnalysisContext analysisContext) {System.out.println("student = "+student);}/*** 读取完整的文档之后调用的方法* @param analysisContext*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}
}
 /*** 读操作,从excel表格读操作,也就是导入操作。*/@Testpublic void testRead(){/*构建一个工作簿对象pathName 要读的文件的路径head 文件中每一行的数据redaListener 读监听器*///获得一个工作簿对象ExcelReaderBuilder read = EasyExcel.read("student.xlsx", Student.class, new StudentListener());//获得一个工作表的对象ExcelReaderSheetBuilder sheet = read.sheet();//读取工作表中的内容sheet.doRead();}

4.3 EasyExcel写操作

 /*** 写操作,向excel文件中写内容,也就是导出操作*/@Testpublic void testWrite() {//首先是获取一个工作簿,和poi一样ExcelWriterBuilder writeWorkBook = EasyExcel.write("student-write.xls", Student.class);//然后是获取一个工作表ExcelWriterSheetBuilder sheet = writeWorkBook.sheet();//最后是写入到excel表中List<Student> students = intData();System.out.println(students);sheet.doWrite(students);}public static List<Student> intData(){ArrayList<Student> students = new ArrayList<>();for (int i = 0; i < 10; i++) {Student student = new Student();student.setSname("哈哈"+i);student.setSno(i);student.setSage(20+i);student.setSsex("男");students.add(student);}System.out.println(students);return students;}

完!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mybatis mysql insert 主键id为空

错误示范 java代码设置了param参数&#xff0c;但是sql 字段没有带上参数&#xff0c;例如 void insertV2(Param("historyDO") HistoryDO historyDO); <insert id"insertDuplicate" parameterType"com.test.entity.HistoryDO"keyProperty&…

MySQL:一行记录如何

1、表空间文件结构 表空间由段「segment」、区「extent」、页「page」、行「row」组成&#xff0c;InnoDB存储引擎的逻辑存储结构大致如下图&#xff1a; 行 数据库表中的记录都是按「行」进行存放的&#xff0c;每行记录根据不同的行格式&#xff0c;有不同的存储结构。 页…

hippy 调试demo运行联调-mac环境准备篇

适用对于终端编译环境不熟悉的人看&#xff0c;仅mac端 hippy 调试文档官网地址 前提&#xff1a;请使用node16 联调预览效果图&#xff1a; 编译iOS Demo环境准备 未跑通&#xff0c;待补充 编译Android Demo环境准备 1、正常安装Android Studio 2、下载Android NDK&a…

Windows系统误删文件恢复

最近很多用户反馈误删文件的场景比较多.下面华仔将讲解数据恢复的原理和过程.以及一些注意事项。 建议的数据恢复软件 1.EaseUS Data Recovery Wizard(易我数据恢复)需要断网使用 2.Wondershare Recoverit(万兴数据恢复)&#xff0c; Windows系统删除文件原理&#xff1a;如果是…

Android ShellUtils手机管理器

1. Android ShellUtils手机管理器 Android Shell工具类&#xff0c;可用于检查系统root权限&#xff0c;并在shell或root用户下执行shell命令。如&#xff1a; checkRootPermission() 检查root权限 。execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg)…

HTTPS是什么,详解它的加密过程

目录 1.前言 2.两种加密解密方式 2.1对称加密 2.2非对称加密 3.HTTPS的加密过程 3.1针对明文的对称加密 3.2针对密钥的非对称加密 3.3证书的作用 1.前言 我们知道HTTP协议是超文本传输协议,它被广泛的应用在客户端服务器上,用来传输文字,图片,视频,js,html等.但是这种传…

java数据结构与算法刷题-----LeetCode572. 另一棵树的子树(经典题,树字符串化KMP)

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 暴力求解&#xff0c;深度优先2. KMP算法进行串匹配 1. 暴力求…

WinForm、Wpf自动升级 AutoUpdater.NET

Github AutoUpdater.NET 目录 一、IIS部署 更新站点 二、创建Winform 一、IIS部署 更新站点 IIS默认站点目录下创建 目录 Downloads、Updates Updates目录创建文件 UpdateLog.html、AutoUpdaterStarter.xml UpdateLog.html&#xff1a; <html><body><h1…

从零开始手写RPC框架(2)——Netty入门

学习前需要掌握基本的java网络编程&#xff0c;可参考这篇博客 目录 Netty 简介Netty 使用 kryo 序列化传输对象案例客户端代码服务端代码编码器 Netty 简介 是什么&#xff1f; Netty 是一个基于 NIO (Non-blocking I/O&#xff0c;非阻塞I/O)的 client-server(客户端服务器…

mysql学习--binlog与gtid主从同步

基础环境 基于centOS7-MySQL8.0.35版本 我们先准备一台主服务器两台从服务器来实现我们主从同步的诉求 Master&#xff1a;192.168.75.142 slave1:192.168.75.143 slave&#xff1a;192.168.75.145 binlog主从同步 主库配置 #我们需要在主从库中都需要添加server_id&am…

大龙谈智能内容开通视频号啦

大家好&#xff0c;大龙谈只能内容开通视频号了&#xff0c;欢迎大家扫码关注&#xff1a;

RISC-V特权架构 - 中断与异常概述

RISC-V特权架构 - 中断与异常概述 1 中断概述2 异常概述3 广义上的异常3.1 同步异常3.2 异步异常3.3 常见同步异常和异步异常 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 中断概述 中断&#xff08;Interrupt&#xff09;机制&#xff0c;即…

RocketMQ安装

mq服务端安装配置启动把windows做成服务 mq管理界面安装配置启动 mq服务端 安装 RocketMQ下载地址 配置 ROCKETMQ_HOME D:\google-d\rocketmq-all-5.2.0-bin-release启动 # bin目录cmd输入 start mqnamesrv.cmd把windows做成服务 http://t.csdnimg.cn/qd2RD mq管理界面 …

ubuntu22.04安裝mysql8.0

官网下载mysql&#xff1a;MySQL :: Download MySQL Community Server 将mysql-server_8.0.20-2ubuntu20.04_amd64.deb-bundle.tar上传到/usr/local/src #解压压缩文件 tar -xvf mysql-server_8.0.20-2ubuntu20.04_amd64.deb-bundle.tar解压依赖包依次输入命令 sudo dpkg -i m…

编程笔记 Golang基础 045 math包

编程笔记 Golang基础 045 math包 一、math包主要功能常量&#xff1a;函数&#xff1a;数值运算&#xff1a;三角函数&#xff1a;对数函数&#xff1a;随机数相关&#xff1a; 二、示例代码一三、示例代码二小结 Go 语言的标准库 math 提供了一系列基础数学函数和常量&#xf…

EasyRecovery数据恢复软件2024最新版包括Windows和Mac

EasyRecovery数据恢复软件适用于多种环境和使用场景。首先&#xff0c;它适用于各种操作系统&#xff0c;包括Windows和Mac。无论用户使用的是哪种操作系统&#xff0c;都可以使用该软件进行数据恢复。 其次&#xff0c;EasyRecovery支持从各种存储设备和媒介中恢复数据&#…

自定义BeanNameGenerator生成规则

通过点进ComponentScan注解进入源码可以看到 追随BeanNameGenerator进入源码可以看到该类是个借口且只有一个方法 点击上面黑色箭头出现两个实现方法 点击第一个方法 进入determineBeanNameFromAnnotation方法中 通过上诉自定义一个生成beanName方法 先创建一个CustomeBeanN…

使用结构体和类在Unity中管理IMU数据

使用结构体和类在Unity中管理IMU数据 IMU数据简介使用结构体管理IMU数据结构体的优点结构体的使用场景 使用类管理IMU数据类的优点类的使用场景 结构体(struct) vs 类(class)为什么考虑使用结构体 结论 在Unity开发中&#xff0c;合理地选择数据结构对于确保游戏和应用的性能和…

60 个 CSS 选择器,一网打尽!

CSS 选择器用于选择 HTML 元素并将样式应用于它们。使用这些选择器&#xff0c;可以定义特定条件下应用哪些样式。除了普通的选择器外&#xff0c;还有伪类和伪元素&#xff0c;用于选择具有特定状态或特定部分的元素&#xff0c;并将样式应用于它们。本文将通过图文并茂的方式…

Windows11家庭版安装Docker

文章目录 安装Docker安装hyper-v继续解决报错完成效果图进一步测试是否完成安装 安装Docker windows如何安装docker 装好之后&#xff0c;我打开报错。 安装hyper-v 按这个视频操作&#xff1a;Windows 11 家庭版安装 Hyper-V bat文件里的代码是&#xff1a; pushd "…