当前位置:网站首页>Apache POI的读写
Apache POI的读写
2022-06-27 08:55:00 【仲夏月二十八】
POI-Excel
常用信息
- 将用户信息导出为excel表格(例如是导出数据:数据库信息)
- 将excel表中的信息录入网站数据库(例如是导入数据:题库)
开发中经常会用到excel的处理,例如导入、导出excel
操作Excel目前比较流行的就是 Apache POI 和阿里巴巴的 easyExcel
Apache POI(会比较麻烦一些)
官网:Apache POI - the Java API for Microsoft Documents

百度简介:
Apache POI [1] 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对[Microsoft Office](https://baike.baidu.com/item/Microsoft Office)格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。
结构:

easyExcel(alibaba)
官网:https://github.com/alibaba/easyexce or EasyExcel · 语雀 (yuque.com)

EasyExcel 是阿里巴巴开源的一个excel处理框架,以使用简单,节约内存著称
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
文件解压文件读取通过文件形式

POI-Excel写
创建项目
创建一个新项目
引入pom依赖
<!--导入依赖--> <dependencies> <!--03--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.0</version> </dependency> <!--07--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.0</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.13.2</version> <scope>test</scope> </dependency> </dependencies>科普:
03版本的execl和07版本的execl有什么区别了?03与07版本的区别:
03版本
@Test public void test03() throws IOException { //创建一个工作簿 Workbook workbook = new HSSFWorkbook(); //创建一个工作表 Sheet sheet = workbook.createSheet("李凯的工作表"); //创建行 Row row = sheet.createRow(0); //创建单元格子((0,0) Cell cell = row.createCell(0); /*添加内容*/ cell.setCellValue("今天花费"); //(0,1) Cell cell1 = row.createCell(1); cell.setCellValue("20"); /*1,0*/ final Row row1 = sheet.createRow(1); final Cell cell2 = row1.createCell(0); cell2.setCellValue("统计时间"); final String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss:sss"); final Cell cell3 = row1.createCell(1); /*放入时间*/ cell3.setCellValue(time); /*生成一张表 03版本使用xls结尾*/ FileOutputStream fileOutputStream = new FileOutputStream(PATH + "李凯的日出消费表.xls"); workbook.write(fileOutputStream); //关闭流 fileOutputStream.close(); workbook.close(); System.out.println("生成完毕"); }07版本
public void test07() throws IOException { //创建一个工作簿 Workbook workbook = new XSSFWorkbook(); //创建一个工作表 Sheet sheet = workbook.createSheet("李凯的工作表"); //创建行 Row row = sheet.createRow(0); //创建单元格子((0,0) Cell cell = row.createCell(0); /*添加内容*/ cell.setCellValue("今天花费"); //(0,1) Cell cell1 = row.createCell(1); cell1.setCellValue("20"); /*1,0*/ Row row1 = sheet.createRow(1); Cell cell2 = row1.createCell(0); cell2.setCellValue("统计时间"); final String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss:sss"); final Cell cell3 = row1.createCell(1); /*放入时间*/ cell3.setCellValue(time); /*生成一张表 03版本使用xls结尾*/ FileOutputStream fileOutputStream = new FileOutputStream(PATH + "李凯的日出消费表.xlsx"); workbook.write(fileOutputStream); //关闭流 fileOutputStream.close(); workbook.close(); System.out.println("生成完毕"); }区别:
对象的区别
03版本:
Workbook workbook = new HSSFWorkbook();07版本:
Workbook workbook = new XSSFWorkbook();后缀名的区别
03 07 xls xlsx
03版本的大文件写入
缺点:最多只可以写入65536行,否则会抛出异常
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)
优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快
时间:
正确代码:
public void test03BigData() throws IOException {
// 时间差:
final long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//创建表
final Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNum = 0;rowNum<65536;rowNum++){
final Row row = sheet.createRow(rowNum);
for (int cellNum = 0;cellNum<10;cellNum++){
final Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("over");
final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
final long end = System.currentTimeMillis();
System.out.println((double)(end-begin)/1000);
}
报错代码:
public void test03BigData() throws IOException {
// 时间差:
final long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//创建表
final Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNum = 0;rowNum<65537;rowNum++){
final Row row = sheet.createRow(rowNum);
for (int cellNum = 0;cellNum<10;cellNum++){
final Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("over");
final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
final long end = System.currentTimeMillis();
System.out.println((double)(end-begin)/1000);
}
07版本的大文件写入
缺点:写数据时数据速度非常慢,非常消耗内存,也会发生溢出,如100w条数据
优点:可以写比较大的数据量,如20w条数据
时间:

可以发现哪怕多了一条数据,时间就多了将进4倍
代码:
public void test07BigData() throws IOException { // 时间差: final long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new XSSFWorkbook(); //创建表 final Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNum = 0;rowNum<65537;rowNum++){ final Row row = sheet.createRow(rowNum); for (int cellNum = 0;cellNum<10;cellNum++){ final Cell cell = row.createCell(cellNum); cell.setCellValue(cellNum); } } System.out.println("over"); final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close(); final long end = System.currentTimeMillis(); System.out.println((double)(end-begin)/1000); }07版本的大数据写SXSSF
优点:可以写非常大的数据量,例如100w条数据甚至更多条,相对于07版本的XSSF,他的读写数据更快,占用内存更少注意:过程中会产生临时文件,需要清理临时文件默认的时100条记录被保存在内存中,如果超过这个数量,则最前面的数据将会写入到临时文件当中。
如果要想自定义内存中的数据的数量,则可以通过
new SXXSFWorkbook(数量)时间:

代码:
public void test07BigDataS() throws IOException { // 时间差: final long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new SXSSFWorkbook(); //创建表 final Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNum = 0;rowNum<65537;rowNum++){ final Row row = sheet.createRow(rowNum); for (int cellNum = 0;cellNum<10;cellNum++){ final Cell cell = row.createCell(cellNum); cell.setCellValue(cellNum); } } System.out.println("over"); final FileOutputStream fileOutputStream = new FileOutputStream(PATH+"测试.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close(); /*清除临时文件*/ ((SXSSFWorkbook)workbook).dispose(); final long end = System.currentTimeMillis(); System.out.println((double)(end-begin)/1000); }
POI-Excel读
07/03版本
@Test
public void test03() throws IOException {
//获取文件流
FileInputStream fileInputStream = new FileInputStream(PATH+"ABC.xls");
//创建一个工作簿.使用excel能完成的操作这里都可以完成
Workbook workbook = new HSSFWorkbook(fileInputStream);
//获取表
final Sheet sheetAt = workbook.getSheetAt(0);
/*获取行*/
final Row row = sheetAt.getRow(0);
final int RowNum = sheetAt.getLastRowNum();
/*获取列*/
final Cell cell = row.getCell(0);
final String stringCellValue = cell.getStringCellValue();
System.out.println(stringCellValue);
System.out.println(RowNum);
fileInputStream.close();
}
07版本:
@Test
public void test03() throws IOException {
//获取文件流
FileInputStream fileInputStream = new FileInputStream(PATH+"ABC.xlsx");
//创建一个工作簿.使用excel能完成的操作这里都可以完成
Workbook workbook = new XSSFWorkbook(fileInputStream);
//获取表
final Sheet sheetAt = workbook.getSheetAt(0);
/*获取行*/
final Row row = sheetAt.getRow(0);
final int RowNum = sheetAt.getLastRowNum();
/*获取列*/
final Cell cell = row.getCell(0);
final String stringCellValue = cell.getStringCellValue();
System.out.println(stringCellValue);
System.out.println(RowNum);
fileInputStream.close();
}
读取不同的数据类型
重点:数据转换类型!
@Test
public void test07Demo() throws IOException {
//获取文件流
FileInputStream fileInputStream = new FileInputStream(PATH+"ABC.xlsx");
//创建一个工作簿.使用excel能完成的操作这里都可以完成
Workbook workbook = new XSSFWorkbook(fileInputStream);
//获取表
Sheet sheetAt = workbook.getSheetAt(0);
/*获取行数*/
Row row = sheetAt.getRow(0);
if (row!=null){
/*获取所有的行数*/
final int physicalNumberOfCells = row.getPhysicalNumberOfCells();
for (int CellNum = 0; CellNum < physicalNumberOfCells; CellNum++) {
final Cell cell = row.getCell(CellNum);
if (cell!=null){
/*获取行的类型*/
CellType cellType = cell.getCellType();
String stringCellValue = cell.getStringCellValue();
System.out.print(stringCellValue+" ");
}
}
System.out.println();
}
//获取表中的数据(列数)
int physicalNumberOfRows = sheetAt.getPhysicalNumberOfRows();
for (int RowNum = 1; RowNum < physicalNumberOfRows; RowNum++) {
final Row row1 = sheetAt.getRow(RowNum);
if (row1!=null){
//读取列
final int physicalNumberOfCells = row1.getPhysicalNumberOfCells();
for (int cellNumber = 0; cellNumber < physicalNumberOfCells; cellNumber++) {
final Cell cell = row1.getCell(cellNumber);
//匹配列的数据类型
if (cell!=null){
CellType cellType = cell.getCellType();
String cellValue = "";
/*判断类型*/
switch (cellType){
case STRING:
System.out.println("字符串");
cellValue= cell.getStringCellValue();
break;
case BOOLEAN:
System.out.println("布尔类型");
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case BLANK:
System.out.println("为空");
break;
case NUMERIC: //数字(日期和普通数字)
if (HSSFDateUtil.isCellDateFormatted(cell)){
//日期
System.out.println("日期类型");
Date date = cell.getDateCellValue();
cellValue = new DateTime(date).toString("yyyy-MM-dd");
}else {
System.out.println("数字");
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
case ERROR:
System.out.println("数组类型错误");
break;
}
System.out.println(cellValue);
}
}
}
}
fileInputStream.close();
}
计算公式:
@Test
public void testFormula() throws IOException {
FileInputStream fileInputStream = new FileInputStream(PATH + "Documents测试.xlsx");
Workbook workbook= new XSSFWorkbook(fileInputStream);
Sheet sheetAt = workbook.getSheetAt(0);
Row row = sheetAt.getRow(4);
Cell cell = row.getCell(0);
//拿到计算公式 eval
FormulaEvaluator xssfFormulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
//输出单元格的内容
CellType cellType = cell.getCellType();
switch (cellType){
case FORMULA: //公式
String cellFormula = cell.getCellFormula();
System.out.println(cellFormula);
//计算
CellValue evaluate = xssfFormulaEvaluator.evaluate(cell);
String CellValue = evaluate.formatAsString();
System.out.println(CellValue);
break;
}
}
边栏推荐
- oracle怎样将字符串转为多行
- Code source AQS sous - jacent pour la programmation simultanée juc
- Process 0, process 1, process 2
- How much do you know about the cause of amplifier distortion?
- Analysis log log
- About the problem that the El date picker Click to clear the parameter and make it null
- JVM常见的垃圾收集器
- 招聘需求 视觉工程师
- A classic interview question covering 4 hot topics
- Some considerations on operation / method overloading for thread to release lock resources
猜你喜欢

Obsidian 一周使用心得(配置、主题和插件)

Redis master-slave replication and sentinel mode

I'm almost addicted to it. I can't sleep! Let a bug fuck me twice!

Rough reading DS transunet: dual swing transformer u-net for medical image segmentation

Semi-supervised Learning入门学习——Π-Model、Temporal Ensembling、Mean Teacher简介

Code source AQS sous - jacent pour la programmation simultanée juc

webrtc入门:12.Kurento下的RtpEndpoint和WebrtcEndpoint

Some exercises about binary tree

Markem Imaje Marken IMAS printer maintenance 9450e printer maintenance

Improving efficiency or increasing costs, how should developers understand pair programming?
随机推荐
Design of a solar charge pump power supply circuit
Quelques exercices sur les arbres binaires
oracle用一条sql查出哪些数据不在某个表里
MySQL索引详解
The background prompt module for accessing fastadmin after installation does not exist
2022.06.26 (LC Luo 6101 Luo determines whether the matrix is an X matrix)
main()的参数argc与argv
RMAN-08137 主库无法删除归档文件
快捷键 bug,可复现(貌似 bug 才是需要的功能 [滑稽.gif])
0号进程,1号进程,2号进程
1098 insertion or heap sort (PAT class a)
Process 0, process 1, process 2
Order by injection of SQL injection
了解神经网络结构和优化方法
我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
冒牌构造函数???
orthofinder直系同源蛋白分析及结果处理
Analysis log log
MySQL lock details
1098 Insertion or Heap Sort(堆排序解释)(PAT甲级)