0
点赞
收藏
分享

微信扫一扫

POI

夜空一星 2022-02-12 阅读 48


Poi(适合小数据量)

Apache POI 官网:https://poi.apache.org/

POI是Apache软件基金会的,POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。

所以POI的主要功能是可以用Java操作Microsoft Office的相关文件,这里我们主要讲Excel

小数据写


1 .导入依赖


<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>

</dependencies>


2 .开启读写操作,代码走起


无非就是对api的充分认识,接下来我们先去了解他的api

Workbook wordkbook =new HSSFWorkbook();//创建一个Workbook对象
wordkbook.createSheet();//创建表名,如果不写参数,会有默认值
Row row1=sheet.createRow(0);//根据里面的数字拿到对应的行,0默认为第一行
Cell cell = row1.createCell(0);//根据行对象创建单元格,这里0为第一个
cell.setCellValue("");//可以给单元格赋值

写入一个Excel

package com.kuang;

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.joda.time.DateTime;
import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelWriteTest {
//先要有个路劲
static String path="D:\JAVA---EasyExcel\TEST";
@Test
public void testWrite03(String[] args) throws IOException {
//1,创建一个工作薄
Workbook wordkbook =new HSSFWorkbook();
//表名
Sheet sheet=wordkbook.createSheet("灰灰统计表");
//创建行
Row row1=sheet.createRow(0);
//4.创建一个单元格
Cell cell = row1.createCell(0);
cell.setCellValue("今日新增观众");
Cell cell2 = row1.createCell(1);
cell2.setCellValue("卢本伟");

//创建行
Row row2=sheet.createRow(1);
//4.创建一个单元格
Cell cell3 = row2.createCell(0);
cell3.setCellValue("统计时间");
Cell cell24= row2.createCell(1);
String time=new DateTime().toString("yyyy-MM-dd HH:mm:ss");
cell24.setCellValue(time);

//生成一张表 03是xls 07是xlsx
FileOutputStream fileOutputStream = new FileOutputStream(path + "灰灰统计表03.xls");
wordkbook.write(fileOutputStream);

fileOutputStream.close();
System.out.println("灰灰统计表03已生成");
}
@Test
public void testWrite07() throws IOException {
//1,创建一个工作薄
Workbook wordkbook =new XSSFWorkbook();
//表名
Sheet sheet=wordkbook.createSheet("灰灰统计表");
//创建行
Row row1=sheet.createRow(0);
//4.创建一个单元格
Cell cell = row1.createCell(0);
cell.setCellValue("今日新增观众");
Cell cell2 = row1.createCell(1);
cell2.setCellValue("卢本伟");

//创建行
Row row2=sheet.createRow(1);
//4.创建一个单元格
Cell cell3 = row2.createCell(0);
cell3.setCellValue("统计时间");
Cell cell24= row2.createCell(1);
String time=new DateTime().toString("yyyy-MM-dd HH:mm:ss");
cell24.setCellValue(time);

//生成一张表 03是xls 07是xlsx
FileOutputStream fileOutputStream = new FileOutputStream(path + "\灰灰统计表07.xlsx");
wordkbook.write(fileOutputStream);

fileOutputStream.close();
System.out.println("灰灰统计表07已生成");
}


}

上面写完后会在项目目录下生成一个表格

03 | 07 版本的写,就是对象不同,方法一样的!

大数据写

HSSF

缺点:最多只能处理65536行,否则会抛出异常

java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0…65535)

优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快

@Test
public void testWrite03BigData() throws IOException {
long begin = System.currentTimeMillis();

HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
for (int rowNum = 0; rowNum < 65535; rowNum++) {
Row row = sheet.createRow(rowNum);
for (int cellNum = 0; cellNum < 10; cellNum++) {
Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("over");
FileOutputStream outputStream = new FileOutputStream(path + "//testWrite03BigData");
workbook.write(outputStream);
outputStream.close();
long end = System.currentTimeMillis();
System.out.println((double) (end-begin)/1000);


}

XSSF

缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条

优点:可以写较大的数据量,如20万条

@Test
public void testWrite07BigData() throws IOException {
long begin = System.currentTimeMillis();

Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
for (int rowNum = 0; rowNum < 655350; rowNum++) {
Row row = sheet.createRow(rowNum);
for (int cellNum = 0; cellNum < 10; cellNum++) {
Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("over");
FileOutputStream outputStream = new FileOutputStream(path + "//testWrite03BigData.xlsx");
workbook.write(outputStream);
outputStream.close();
long end = System.currentTimeMillis();
System.out.println((double) (end-begin)/1000);


}

SXSSF

优点:可以写非常大的数据量,如100万条甚至更多条,写数据速度快,占用更少的内存

注意:

过程中会产生临时文件,需要清理临时文件

默认由100条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件 如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook ( 数量 )

@Test
public void testWrite07BigDataS() throws IOException {
long begin = System.currentTimeMillis();

Workbook 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("over");
FileOutputStream outputStream = new FileOutputStream(path + "//testWrite07BigDataS.xlsx");
workbook.write(outputStream);
outputStream.close();
((SXSSFWorkbook)workbook).dispose();//关闭临时文件
long end = System.currentTimeMillis();
System.out.println((double) (end-begin)/1000);


}

SXSSFWorkbook-来至官方的解释:实现“BigGridDemo”策略的流式XSSFWorkbook版本。这允许写入 非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。

请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注释…仍然只存 储在内存中,因此如果广泛使用,可能需要大量内存。

读取单一类型的数据

这个操作跟上述的写并没有什么不同,不同就是方法是get而不是set

static String path="F:\\demo\\javapoi\\demopoi";
@Test
public void testRead03() throws IOException {


//Sheet sheet=workbook.createSheet("统计表");
//sheet操作表中元素
FileInputStream fileInputStream = new FileInputStream(path + "\灰灰统计表03.xls");
Workbook workbook=new HSSFWorkbook(fileInputStream);
Sheet sheet = workbook.getSheetAt(0);
// Sheet sheet2 = workbook.getSheet("灰灰统计表");
Row row = sheet.getRow(1);
Cell cell = row.getCell(0);
Cell cell2 = row.getCell(1);
System.out.println(cell.getStringCellValue());
System.out.println(cell2.getStringCellValue());
fileInputStream.close();
}


这里值得注意的是,使用表格对象要注意三种创建方式



  • POI-HSSF
  • POI-XSSF
  • SXSSF

**HSSF:*Excel97-2003版本,扩展名为.xls。一个sheet最大行数*65536,最大列数256。

**XSSF:*Excel2007版本开始,扩展名为.xlsx。一个sheet最大行数*1048576,最大列数16384。

SXSSF:**是在XSSF基础上,POI3.8版本开始提供的**支持低内存占用的操作方式,扩展名为.xlsx。

Excel版本兼容性是向下兼容

读取不同类型的数据

在读取数据的时候我们需要先判断值类型,才能用对应API

下面这个是先拿到表头那一行,相当于数据库的字段

POI_poi

FileInputStream fileInputStream = new FileInputStream(path + "数据表07.xlsx");
Workbook workbook=new XSSFWorkbook(fileInputStream);
Sheet sheet = workbook.getSheetAt(0);
Row rowTitle = sheet.getRow(0);
if(rowTitle!=null){
int cellCount=rowTitle.getPhysicalNumberOfCells(); //拿到第row行的那一行的总个数
for (int i = 0; i <cellCount ; i++) { //循环个数取出
Cell cell = rowTitle.getCell(i);
if(cell!=null){ //如果不等于空取出值
int cellType = cell.getCellType(); //这里是知道我们标题是String,考虑不确定的时候怎么取
String cellValue = cell.getStringCellValue();
System.out.print(cellValue+"|");
}
}
System.out.println();
}

下面接着读取对应的数据,这里就需要我们刚刚讲的类型判断

int cellType=cell.getCellType();利用这个,然后判断它的XSSFCell类型再具体输出

//获取表中内容
int rowCount=sheet.getPhysicalNumberOfRows();
for(int rowNum=1;rowNum<rowCount;rowNum++){
Row rowData=sheet.getRow(rowNum); //取出对应的行
if(rowData!=null){
int cellCount=rowTitle.getPhysicalNumberOfCells();
for(int cellNum=0;cellNum<cellCount;cellNum++){
System.out.print("["+(rowNum+1+"-"+(cellNum+1)+"]"));
Cell cell = rowData.getCell(cellNum);
//匹配数据类型
if(cell!=null){
int cellType=cell.getCellType();
switch (cellType){
case XSSFCell.CELL_TYPE_STRING: System.out.print("字符串:"+cell.getStringCellValue());break;
case XSSFCell.CELL_TYPE_BOOLEAN: System.out.print("布尔:"+cell.getBooleanCellValue());break;
case XSSFCell.CELL_TYPE_NUMERIC:
if(HSSFDateUtil.isCellDateFormatted(cell)){
System.out.println("日期格式:"+new DateTime(cell.getDateCellValue()).toString("yyyy-MM-dd HH:mm:ss"));break;
}else
cell.setCellType(XSSFCell.CELL_TYPE_STRING);
System.out.print("整形:"+cell.toString());break;
case XSSFCell.CELL_TYPE_BLANK: System.out.print("空");break;
case XSSFCell.CELL_TYPE_ERROR: System.out.print("数据类型错误");break;
case Cell.CELL_TYPE_FORMULA:
//拿到计算公式
XSSFFormulaEvaluator FormulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
String formula=cell.getCellFormula();
System.out.println("公式:"+formula);

//
CellValue evaluate = FormulaEvaluator.evaluate(cell);
String cellValue=evaluate.formatAsString();
System.out.println(cellValue);
break;
default:break;
}
}
}
}
}


fileInputStream.close();


举报

相关推荐

0 条评论