EasyExcel采用一行一行的解析模式
,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。
03和07版本的写,就是对象不同,方法一样
最大行列得数量
不同:
xls最大只有65536行、256列
xlsx可以有1048576行、16384列
org.apache.poi
poi
3.9
org.apache.poi
poi-ooxml
3.9
poi 操作xls的
poi-ooxml 操作xlsx的
操作的版本不同,使用的工具类也不同
工作簿:
工作表:
行:
列:
5.1小数据量
package cn.bloghut;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Date;
/**
-
@Classname ExcelWrite
-
@Description TODO
-
@Date 2022/1/7 12:41
-
@Created by 闲言
*/
public class ExcelWrite {
String PATH = “G:\狂\POIStudy\xy-poi”;
/**
- 写工作簿 03版本
*/
@Test
public void Write03() throws Exception {
//1.创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//2.创建 一个工作表
Sheet sheet = workbook.createSheet(“闲言粉丝统计表”);
//3.创建一行
Row row1 = sheet.createRow(0);
//4.创建一个单元格
//(1,1)
Cell cell1 = row1.createCell(0);
cell1.setCellValue(“今日新增观众”);
//(1,2)
Cell cell2 = row1.createCell(1);
cell2.setCellValue(666);
//创建第二行
Row row2 = sheet.createRow(1);
//(2,1)
Cell cell21 = row2.createCell(0);
cell21.setCellValue(“统计时间”);
//(2,2)
Cell cell22 = row2.createCell(1);
String datetime = new DateTime().toString(“yyyy-MM-dd HH:mm:ss”);
cell22.setCellValue(datetime);
//生成一张表(IO流),03版本就是使用xls结尾
FileOutputStream fos = new FileOutputStream(PATH + “闲言观众统计表03.xls”);
//输出
workbook.write(fos);
//关闭流
fos.close();
System.out.println(“文件生成完毕”);
}
/**
- 写工作簿 07版本
*/
@Test
public void Write07() throws Exception {
//1.创建一个工作簿
Workbook workbook = new XSSFWorkbook();
//2.创建 一个工作表
Sheet sheet = workbook.createSheet(“闲言粉丝统计表”);
//3.创建一行
Row row1 = sheet.createRow(0);
//4.创建一个单元格
//(1,1)
Cell cell1 = row1.createCell(0);
cell1.setCellValue(“今日新增观众”);
//(1,2)
Cell cell2 = row1.createCell(1);
cell2.setCellValue(666);
//创建第二行
Row row2 = sheet.createRow(1);
//(2,1)
Cell cell21 = row2.createCell(0);
cell21.setCellValue(“统计时间”);
//(2,2)
Cell cell22 = row2.createCell(1);
String datetime = new DateTime().toString(“yyyy-MM-dd HH:mm:ss”);
cell22.setCellValue(datetime);
//生成一张表(IO流),03版本就是使用xlsx结尾
FileOutputStream fos = new FileOutputStream(PATH + “闲言观众统计表07.xlsx”);
//输出
workbook.write(fos);
//关闭流
fos.close();
System.out.println(“文件生成完毕”);
}
}
注意对象一个区别,文件后缀
5.2大文件写HSSF(03)
缺点:最多只能处理65536行
,否则会抛异常
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0…65535)
优点:过程中写入缓存,不操作磁盘,最后一次性吸入磁盘,速度快
@Test
public void Write03BigData() throws Exception{
//时间
long begin = System.currentTimeMillis();
//1.创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//2.创建一个表
Sheet sheet = workbook.createSheet(“第一页”);
//写入数据
for (int rowNum = 0;rowNum<65536;rowNum++){
//3.创建行
Row row = sheet.createRow(rowNum);
for (int CellNum = 0;CellNum<10;CellNum++){
Cell cell = row.createCell(CellNum);
cell.setCellValue(CellNum);
}
}
System.out.println(“over”);
//获取io流
FileOutputStream fos = new FileOutputStream(PATH+“Write03BigData.xls”);
//生成一张表
workbook.write(fos);
fos.close();
long end = System.currentTimeMillis();
System.out.println(“耗时:”+(end-begin));
}
结果:
5.3大文件写XSSF(07)
缺点:写数据时速度非常慢,非常耗内存
,也会发生内存溢出,如100万条。
优点:可以写较大数据量,如20万条
。
@Test
public void Write07BigData() throws Exception{
//时间
long begin = System.currentTimeMillis();
//1.创建一个工作簿
Workbook workbook = new XSSFWorkbook();
//2.创建一个表
Sheet sheet = workbook.createSheet(“第一页”);
//写入数据
for (int rowNum = 0;rowNum<65537;rowNum++){
//3.创建行
Row row = sheet.createRow(rowNum);
for (int CellNum = 0;CellNum<10;CellNum++){
Cell cell = row.createCell(CellNum);
cell.setCellValue(CellNum);
}
}
System.out.println(“over”);
//获取io流
FileOutputStream fos = new FileOutputStream(PATH+“Write03BigData.xlsx”);
//生成一张表
workbook.write(fos);
fos.close();
long end = System.currentTimeMillis();
System.out.println(“耗时:”+(end-begin));
}
结果:
5.4大文件写SXSSF
优点:可以写非常大的数据量,如100万条甚至更多条写数据速度快,占用更少的内存
注意:
-
过程中会
产生临时文件
,需要清理临时文件 -
默认由100条记录被保存在内存中
,如果超过这数量,则最前面的数据被写入临时文件 -
如果想自定义内存中数据的数量,可以使用
new SXSSFWorkbook(数量)
@Test
public void Write07BigDataS() throws Exception{
//时间
long begin = System.currentTimeMillis();
//1.创建一个工作簿
Workbook workbook = new SXSSFWorkbook();
//2.创建一个表
Sheet sheet = workbook.createSheet(“第一页”);
//写入数据
for (int rowNum = 0;rowNum<100000;rowNum++){
//3.创建行
Row row = sheet.createRow(rowNum);
for (int CellNum = 0;CellNum<10;CellNum++){
Cell cell = row.createCell(CellNum);
cell.setCellValue(CellNum);
}
}
System.out.println(“over”);
//获取io流
FileOutputStream fos = new FileOutputStream(PATH+“Write03BigDataS.xlsx”);
//生成一张表
workbook.write(fos);
fos.close();
//清除临时文件
((SXSSFWorkbook) workbook).dispose();
long end = System.currentTimeMillis();
System.out.println(“耗时:”+(end-begin));
}
SXSSFWorkbook-来至官方的解释︰实现"BigGridDemo"策略的流式XSSFWorkbook版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。
请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注.…….当然只存储在内存中,因此如果广泛使用,可能需要大量内存。
再使用POI的时候!内存问题
Jprofile !
6.1 (03版本)
@Test
public void Read03() throws Exception{
//1.获取文件流
FileInputStream fis = new FileInputStream(PATH+“xy-poi闲言观众统计表03.xls”);
//2.创建一个工作簿。使用excel能操作的这边都可以操作!
Workbook workbook = new HSSFWorkbook(fis);
//3.获取表
Sheet sheet = workbook.getSheetAt(0);
//4.获取第一行
Row row1 = sheet.getRow(0);
//5.获取第一列
Cell cell1 = row1.getCell(0);
//6.获取第一行第一列的值
String stringCellValue = cell1.getStringCellValue();
//获取第二列
Cell cell2 = row1.getCell(1);
//获取第一行第二列的值
double numericCellValue = cell2.getNumericCellValue();
System.out.println(stringCellValue+" | "+numericCellValue);
fis.close();
}
注意获取值的类型即可
6.2(07版本)
@Test
public void Read07() throws Exception{
//1.获取文件流
FileInputStream fis = new FileInputStream(PATH+“xy-poi闲言观众统计表07.xlsx”);
//2.创建一个工作簿。使用excel能操作的这边都可以操作!
Workbook workbook = new XSSFWorkbook(fis);
//3.获取表
Sheet sheet = workbook.getSheetAt(0);
//4.获取第一行
Row row1 = sheet.getRow(0);
//5.获取第一列
Cell cell1 = row1.getCell(0);
//6.获取第一行第一列的值
String stringCellValue = cell1.getStringCellValue();
//获取第二列
Cell cell2 = row1.getCell(1);
//获取第一行第二列的值
double numericCellValue = cell2.getNumericCellValue();
System.out.println(stringCellValue+" | "+numericCellValue);
fis.close();
}
注意获取值的类型即可
6.3读取不同的数据类型
@Test
public void CellType03() throws Exception{
//获取文件流
FileInputStream fis = new FileInputStream(PATH+“明显表.xls”);
//获取一个工作簿
Workbook workbook = new HSSFWorkbook(fis);
//获取一个工作表
Sheet sheet = workbook.getSheetAt(0);
//获取第一行内容
Row row = sheet.getRow(0);
if (row != null){
//获取所有的列
int Cells = row.getPhysicalNumberOfCells();
for (int col = 0;col < Cells;col++){
//获取当前列
Cell cell = row.getCell(col);
if (cell != null){
//获取当前行的第 col 列的值
String cellValue = cell.getStringCellValue();
System.out.print(cellValue+" | ");
}
}
}
//获取标准的内容
//获取有多少行
int rowCount = sheet.getPhysicalNumberOfRows();
//从1开始,第一行是标题
for (int rowNum = 1;rowNum < rowCount;rowNum++){
Row rowData = sheet.getRow(rowNum);
if (rowData != null){
//获取当前行的列数
int cellCount = rowData.getPhysicalNumberOfCells();
System.out.println();
for (int col = 0;col < cellCount;col++){
//获取当前列的值
Cell cellData = rowData.getCell(col);
//打印当前行当前列的值
System.out.print(“[”+(rowNum+1)+“-”+(col+1)+“]”);
//匹配列的类型
if (cellData != null){
//获取列的类型
int cellType = cellData.getCellType();
String cellValue = “”;
switch (cellType){
case Cell.CELL_TYPE_STRING://字符串
System.out.print(“[string]”);
cellValue = cellData.getStringCellValue();
break;
case Cell.CELL_TYPE_BOOLEAN://布尔
System.out.print(“[boolean]”);
cellValue = String.valueOf(cellData.getBooleanCellValue());
break;
case Cell.CELL_TYPE_BLANK://空
System.out.print(“[blank]”);
break;
case Cell.CELL_TYPE_NUMERIC://数字(日期、普通数字)
System.out.print(“[numeric]”);
if (HSSFDateUtil.isCellDateFormatted(cellData)){
//如果是日期
System.out.print("[日期] ");
Date date = cellData.getDateCellValue();
cellValue = new DateTime(date).toString(“yyyy-MM-dd HH:mm:ss”);
}else {
//不是日期格式,防止数字过长
System.out.print("[转换字符串输出] ");
//转为字符串
cellData.setCellType(HSSFCell.CELL_TYPE_STRING);
cellValue = cellData.toString();
}
break;
case Cell.CELL_TYPE_ERROR://错误
System.out.print(“[error]”);
break;
}
System.out.print(“[”+cellValue+“]\n”);
}
}
}
}
System.out.println();
System.out.println(“over”);
fis.close();
}
如果是07版本的Excel ,只需要将HSSFWorkbook
类修改为XSSFWorkbook
类。将xls文件修改为xlsx
文件即可
测试:读取以下表格内容
结果:
7.1导入依赖
com.alibaba
easyexcel
2.2.0-beta2
7.2写入测试
1.格式类
@Getter
@Setter
@EqualsAndHashCode
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。
我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。
不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-rodCisMG-1713551885723)]
[外链图片转存中…(img-VrCkGowL-1713551885726)]
[外链图片转存中…(img-NvfUG8EF-1713551885727)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。
我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。
不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!