这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」
使用POI
poi会将excel的所有数据放入内存,再将其读出,所以当文件过大时可能会OOM(内存溢出)
适用于小文件,速度快
excel
xls版和xlsx不同
两个版本需要使用不同的依赖
<!--03版excel-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.13</version>
</dependency>
<!--07版excal-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.13</version>
</dependency>
xls
最多只有65536行,使用HSSFWorkbook
写入速度快,但是写入数据的量不大
public void test1() throws Exception {
//使用HSSF创建工作簿
Workbook workbook = new HSSFWorkbook();
// 后缀为xls
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "studen03.xls");
}
xlsx
数量没有限制,使用XSSFWorkbook
写入数据非常慢,耗内存,会发生内存溢出,但是可以写很大的数据量
可以使用加强版的SXSSF
- 可以写非常大的数据量,写速度快,占用内存少
- 会产生临时文件,需要清理
- 每次读取100条数据,如果超过就被写入临时文件
public void test2() throws Exception {
//使用XSSF创建工作簿
Workbook workbook = new XSSFWorkbook();
//文件后缀为xlsx
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "studen07.xlsx");
}
导出
基本的excel文件生成
public void test2() 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("1");
Cell cell22 = row2.createCell(1);
cell22.setCellValue("yy");
// IO流生成文件,xls需要加后缀
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "studen07.xlsx");
workbook.write(fileOutputStream);
// 关闭IO流
fileOutputStream.close();
}
数据批量
public void test3big() throws Exception {
long begin = System.currentTimeMillis();
Workbook workbook = new HSSFWorkbook();
Sheet big = workbook.createSheet("big");
for (int i = 0; i < 65536; i++) {
Row row = big.createRow(i);
for (int j = 0; j < 3; j++) {
Cell cell = row.createCell(j);
cell.setCellValue(j);
}
}
System.out.println("over");
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "03big.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
long last = System.currentTimeMillis();
System.out.println("执行时间为"+(last-begin));
}
HSSF的执行时间
XSSF时间
XSSF
Workbook workbook = new SXSSFWorkbook();
//关闭流之后java清理临时文件
((SXSSFWorkbook) workbook).dispose();
导入
@Test
public void read03() throws Exception {
//创建文件流读取文件
FileInputStream fileOutputStream = new FileInputStream(PATH + "studen03.xls");
//读取获取到的文件
Workbook workbook = new HSSFWorkbook(fileOutputStream);
//读取第一张表
Sheet sheetAt = workbook.getSheetAt(0);
//读取第一行
Row row = sheetAt.getRow(0);
//读取第一行的第一个单元格
Cell cell = row.getCell(0);
System.out.println(cell.getStringCellValue());
fileOutputStream.close();
}
发现如果要获取指定的值,就需要指定他的类型,所以遍历的时候需要判断他的类型
for (Row row : sheetAt){
for (Cell cell : row){
//获取值的类型
int cellType = cell.getCellType();
String value = "";
switch (cellType){
case CELL_TYPE_STRING :
value =cell.getStringCellValue();
break;
//数字里还有日期也要区分
case CELL_TYPE_NUMERIC:
if(HSSFDateUtil.isCellDateFormatted(cell)){
Date date = cell.getDateCellValue();
value =date.toString();
}
else{
cell.setCellType(CELL_TYPE_STRING);
value = cell.getStringCellValue();
}
break;
case CELL_TYPE_BOOLEAN:
value = String.valueOf(cell.getBooleanCellValue()) ;
break;
case CELL_TYPE_BLANK:
break;
case CELL_TYPE_ERROR:
value = "error";
break;
}
System.out.print(value);
}
导入多个sheet
在导入单个sheet的基础上,将获取指定sheet变成遍历所有sheet
for(Sheet sheetAt : workbook){
//获取工作表名称
System.out.println(sheetAt.getSheetName());