EasyPoi与EasyExcel操作Excel
一、Poi介绍
Poi是操作Excel的一套规范,EasyPoi是Apache公司开发的一套框架,而EasyExcl是阿里开发的一套框架。EasyPoi是将表格一次行全部读到内存中再进行操作,因此很容易造成OOM,且对内存的消耗比较大;而EasyExcel是从磁盘中一行一行的读取表格,因此无论数据再大也不会出现OOM,且对内存的消耗很小
二、EasyPoi
1、对象介绍
Excl中有工作簿Workbook
、工作表sheet
、行row
、单元格cell
,在EasyPoi中也有对应的对象,其中workbook是一个接口,他有三个实现类
- HSSF:2003版的Excl,只支持65536行数据(好像是)
- XSSF:2007版的Excl,可操作的数据不限
- SXSSF:在XSSF的基础上做了一些性能上的优化
2、Maven依赖
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>3.2.0</version>
</dependency>
3、写操作
首先创建一个工作簿
//创建一个工作簿
Workbook workbook = new XSSFWorkbook();
接着创建工作表、行、单元格
//创建一张表
Sheet sheet = workbook.createSheet("example.xlsx");
//创建一行
Row row1 = sheet.createRow(0);
//创建单元格
Cell cell11 = row1.createCell(0);
Cell cell12 = row1.createCell(1);
Cell cell13 = row1.createCell(2);
向单元格中插入值
//向单元格中插入值
cell11.setCellValue("first");
cell12.setCellValue(new Date());
cell13.setCellValue(true);
向磁盘中写入文件
//创建一个输出流
File file = new File("D:\\exclFile", "example.xlsx");
OutputStream outputStream = new FileOutputStream(file);
//向磁盘中写入Excl文件
workbook.write(outputStream);
若需要向页面中传入Excl文件,则只需要把输出流换成HttpServletResponse的流即可
ServletOutputStream outputStream = response.getOutputStream(); workbook.write(outputStream);
完整demo:
@Test
void testExcl() throws IOException {
//创建一个工作簿
Workbook workbook = new XSSFWorkbook();
//创建一张表
Sheet sheet = workbook.createSheet("demo.xlsx");
//创建一行
Row row1 = sheet.createRow(0);
//创建单元格
Cell cell11 = row1.createCell(0);
Cell cell12 = row1.createCell(1);
Cell cell13 = row1.createCell(2);
//向单元格中插入值
cell11.setCellValue("first");
cell12.setCellValue(new Date());
cell13.setCellValue(true);
//创建一个输出流
File file = new File("D:\\exclFile", "demo.xlsx");
OutputStream outputStream = new FileOutputStream(file);
//向磁盘中写入Excl文件
workbook.write(outputStream);
}
4、读操作
读与写类型,都需要创建一个WorkBook对象,获取到表,遍历获取行,再遍历获取单元格;其区别就是需要根据数据类型执行不同的操作
完整demo如下:
ExclReceive结构:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExclReceive {
private String stringValue;
private Double numberValue;
private Boolean booleanValue;
private Date dateValue;
}
读操作
public static List<ExclReceive> readExcl(InputStream inputStream){
//创建返回值集合
List<T> list=new ArrayList<>();
try {
//创建工作簿
Workbook workbook = new XSSFWorkbook(inputStream);
//获取表
Sheet sheet = workbook.getSheetAt(0);
//获取标题并打印
Row title = sheet.getRow(0);
int titleCount = sheet.getRow(0).getPhysicalNumberOfCells();
for (int i=0;i<titleCount;i++){
System.out.print(title.getCell(i)+" | ");
}
System.out.println();
//获取总行数
int rowCount = sheet.getPhysicalNumberOfRows();
//遍历表
for (int rowNum = 1; rowNum < rowCount; rowNum++) {
ExclReceive receive = new ExclReceive();
//获取行
Row row = sheet.getRow(rowNum);
//获取每行单元格数
int cellCount = row.getPhysicalNumberOfCells();
//遍历单元格
for (int cellNum = 0; cellNum < cellCount; cellNum++) {
Cell cell = row.getCell(cellNum);
//匹配单元格数据类型
switch (cell.getCellType()){
//字符串
case Cell.CELL_TYPE_STRING:
String cellValue = cell.getStringCellValue();
receive.setStringValue(cellValue);
break;
//布尔
case Cell.CELL_TYPE_BOOLEAN:
boolean booleanCellValue = cell.getBooleanCellValue();
receive.setBooleanValue(booleanCellValue);
break;
//数字
case Cell.CELL_TYPE_NUMERIC:
//日期
if (XSSFDateUtil.isCellDateFormatted(cell)){
Date dateCellValue = cell.getDateCellValue();
receive.setDateValue(dateCellValue);
break;
//数字
}else {
double numericCellValue = cell.getNumericCellValue();
receive.setNumberValue(numericCellValue);
break;
}
//公式
case Cell.CELL_TYPE_FORMULA:
String formula = cell.getCellFormula();
//公式解析器
FormulaEvaluator formulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
//计算公式
CellValue evaluate = formulaEvaluator.evaluate(cell);
//得到计算结果
String s = evaluate.formatAsString();
System.out.println(formula);
System.out.println(s);
break;
}
}
list.add(receive);
}
}catch (Exception e){
e.printStackTrace();
}
return list;
}
三、EasyExcel
EasyExcel是阿里巴巴的一个开源项目,操作很简单,相较于EasyPoi代码量更少,其具体操作可参考官网: