POI及EasyExcel
所用场景:
1.将用户信息导出为excel表格(导出数据)
2.将Excel表中的信息录入到网站数据库(习题上传)大大减轻网站录入量
开发中会经常设计到excel的处理,如导出Excel,导入Excel到数据库中
POI简介
Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对[Microsoft Office](https://baike.baidu.com/item/Microsoft Office)格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。
基本功能:
HSSF:提供读写Microsoft Excel格式档案的功能
XSSF:提供读写Microsoft Exlce OOXML格式档案的功能
HWPF:提供读写Microsoft Word格式档案的功能
HSLF:提供读写Microsoft PowerPoint格式档案的功能
HDGF:提供读写Microsoft Visio格式档案的功能
EasyExcel介绍
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel, github地址:https://github.com/alibaba/easyexcel。
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称
EasyExcel能大大减少占用内存的主要原因是在解析Excel是没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个分析
内存问题:POI=100W先加载到内存,在写入文件
POI-Excel写
pom依赖
<!--导入依赖-->
<dependencies>
<!--xls(03)excel 03版-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<!--xls(07) excel 07版-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</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.12</version>
</dependency>
</dependencies>
xls03与xls07的区别:
- xls03表格只能到65530,xls07可以一直往下拉
- 两者文件后缀名分别是xls与xlsx
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;
public class ExcelWriteTest {
//PATH填生成的地址
String PATH ="D:\\ideaworkspace";
@Test
public void testWrite03() throws Exception {
//创建一个工作簿
Workbook workbook=new HSSFWorkbook();
//创建一个工作表
Sheet sheet=workbook.createSheet("wj");
//创建一行
Row row1=sheet.createRow(0);
//创建一个单元格
Cell cell=row1.createCell(1);
cell.setCellValue(666);
Row row2=sheet.createRow(1);
Cell cell2=row2.createCell(0);
cell2.setCellValue(666);
Cell cell3=row2.createCell(1);
String time=new DateTime().toString("yyyy-mm-dd HH:mm:ss");
cell3.setCellValue(time);
FileOutputStream fileOutputStreamnew = new FileOutputStream(PATH+"poi01.xls");
workbook.write(fileOutputStreamnew);
fileOutputStreamnew.close();
System.out.println("生成完毕");
}
}
xls07写大文件耗时长!优化,缓存!
大文件写XSSF
缺点:写数据时速度非常慢,非常消耗内存,也会发生一处,如100万条
优点:可以写较大的数据量,如20万条
注意:
过程中会产生临时文件,需要清理临时文件
默认由100条记录被保存在内存中,如果超过这数量,则在最前面的数据被写入临时文件中,如果超过这数量,可以使用new SXSSFWorkbook(数量)
POI-Excel读
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 java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExcelReadTest {
String PATH ="D:\\ideaworkspace\\poi\\src\\main";
public void testRead() throws IOException {
FileInputStream fileInputStream=new FileInputStream(PATH+"wj");
Workbook workbook=new HSSFWorkbook();
//创建一个工作表
Sheet sheet=workbook.createSheet("wj");
Row row=sheet.getRow(0);
Cell cell=row.getCell(1);
System.out.println(cell.getStringCellValue());
fileInputStream.close();
}
}
注意获取值的类型
读取不同类型
public void testCellType()throws Exception{
FileInputStream fileInputStream=new FileInputStream(PATH+"wj");
Workbook workbook=new HSSFWorkbook();
//创建一个工作表
Sheet sheet=workbook.createSheet("wj");
Row row=sheet.getRow(0);
if(row!=null){
int cells=row.getPhysicalNumberOfCells();
for(int i=0;i<cells;i++){
Cell cell=row.getCell(cells);
if(cell!=null){
String celltype=cell.getCellType();
sout(celltype);
}
}
sout();
int rowCount=sheet.getPhysicalNumberOfRows();
for(int i=0;i<rowCount;i++){
Row rowData =sheet.getRow(i);
if(row!=null){
String cellCount=row.getCellType()getPhysicalNumberOfRows();
for(int j=0;j<cellCount;j++){
sout((i+1)+(j+1));
Cell cell=rowData.getCell(i);
//匹配里的数据类型
if(cell!=null){
int cellType=cell.getCellType();
String cellvalue="";
switch(cellType){
case HSSFCelll.CELL_TYPE_STRING: cellvalue=cell.getStringValue();
break;
case HSSFCelll.CELL_TYPE_BOOLEAN: cellvalue=cell.getBooleanCellValue();
cellValue=String.valueOf(cell.getBooleanCellValue());
break;
}
}
}
}
}
fileInputStream.close();
}
计算公式:
@Test
public void testFormula() throws Exception{
FileInputStream InputStream = new FileInputStream(path + "/公式.xls");
Workbook workbook = new HSSFWorkbook(InputStream);
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(4);
Cell cell = row.getCell(0);
//拿到计算公式
FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook);
//输出单元格的内容
int cellType = cell.getCellType();
switch (cellType){
case Cell.CELL_TYPE_FORMULA://公式
String formula = cell.getCellFormula();
System.out.println(formula);
//计算
CellValue evaluate = formulaEvaluator.evaluate(cell);
String cellValue = evaluate.formatAsString();
System.out.println(cellValue);
break;
}
InputStream.close();
}
EasyExcel操作
pom依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.0-beta2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
<scope>test</scope>
</dependency>
EasyExcel:https://www.yuque.com/easyexcel/doc/easyexcel
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
@Data
public class DemoData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
@ExcelProperty("数字标题")
private double doubleData;
@ExcelIgnore
private String ignore;
}
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Test {
String PATH ="D:\\ideaworkspace\\poi\\src\\main";
private List<DemoData> data(){
List<DemoData> list=new ArrayList<DemoData>();
for(int i=0;i<10;i++){
DemoData data=new DemoData();
data.setString("字符串"+i);
data.setDate(new Date());
data.setDoubleData(0.56);
list.add(data);
}
return list;
}
@org.junit.Test
public void simpleWrite(){
String fileName =PATH+"EasyTest.xls";
EasyExcel.write(fileName,DemoData.class).sheet("模板").doWrite(data());
}
}
这里要注意的是,要注意poi与easyexcel的版本冲突!