一、POI和easyExcel介绍
1、POI介绍
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
-
基本功能
HSSF - 提供读写Microsoft Excel格式档案的功能。
XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
HWPF - 提供读写Microsoft Word格式档案的功能。
HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
HDGF - 提供读写Microsoft Visio格式档案的功能。
-
资料来源 :http://poi.apache.org/
2、easyExcel介绍
easyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。
-
特点
easyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
下图是easyExcel和POI在解析Excel时的对比图。
二、POI操作Excel
前期准备
导入依赖
<dependencies>
<!--xls(03)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<!--xlsx(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>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
1、POI写入Excel
使用HSSFWorkbook生成的Excel文件格式是xls ,使用XSSFWorkbook生成的Excel文件格式是xlsx,使用SXSSFWorkbook使用更省时的方法生成xlsx。
- 使用SXSSFWorkbook简单生成Excel代码样例
@Test
public void testPoiWrite() throws IOException {
String PATH = "D:\\subject\\poi\\";
String FILE_NAME = "POI测试表.xlsx";
//1、创建工作薄
Workbook workBookTest = new SXSSFWorkbook();
//2、创建工作表
Sheet sheet = workBookTest.createSheet("POI测试");
//3、创建一个行(1,1)
Row row1 = sheet.createRow(0);
//4、创建一个单元格
Cell cell11 = row1.createCell(0);
cell11.setCellValue("工号");
//5、创建第二列
Cell cell12 = row1.createCell(1);
cell12.setCellValue("创建时间");
//6、插入数据到第二行
Row row2 = sheet.createRow(1);
Cell cell21 = row2.createCell(0);
cell21.setCellValue("Z20210428");
Cell cell22 = row2.createCell(1);
String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
cell22.setCellValue(time);
//7、写入到文件(IO流)
FileOutputStream fileOutputStream = new FileOutputStream(PATH+FILE_NAME);
workBookTest.write(fileOutputStream);
fileOutputStream.close();//关闭IO流
((SXSSFWorkbook)workBookTest).dispose();//清除临时文件
System.out.println("文件生成完毕");
}
- 注意事项
- 大数据批量写入Excel
大文件写HSSF
缺点:每次最多处理65536行,否则会发生异常。
有点:过程中使用缓存,不操作硬盘,最后一次性写入磁盘,所以速度快。
大文件写XSSF
缺点:写数据时速度非常慢,非常耗内存,数据量过大也会发生内存溢出,比如100万条以上。
优点:可以写较大批的数据,比如20万条左右。
大文件写SXSSF
优点:写入大批量数据(超100万条)速度较快,占用内存较少。
注意:过程中产生临时文件,所以需要清理临时文件
((SXSSFWorkbook)workBookTest).dispose();//清除临时文件
2、POI读取Excel
-
HSSF读取代码样例
@Test public void testPoiRead() throws IOException { String PATH = "D:\\subject\\poi\\"; String FILE_NAME = "POI测试表.xls"; //获取文件流 FileInputStream fileInputStream = new FileInputStream(PATH+FILE_NAME); //1、创建工作薄 Workbook workBookTest = new HSSFWorkbook(fileInputStream); FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workBookTest);//获取公式 //2、读取第一张表 Sheet sheet = workBookTest.getSheetAt(0); if(sheet!=null){ //3、读取行 int rowCount = sheet.getPhysicalNumberOfRows(); for (int rowNum = 0; rowNum < rowCount; rowNum++) { Row row = sheet.getRow(rowNum); if(row!=null){ //4、读取所有列 int cellCount = row.getPhysicalNumberOfCells(); for (int cellNum = 0; cellNum < cellCount; cellNum++) { //5、读取单元格 Cell cell = row.getCell(cellNum); if(cell!=null){ String cellValue = ""; int cellType = cell.getCellType(); switch (cellType){ case Cell.CELL_TYPE_NUMERIC: if(HSSFDateUtil.isCellDateFormatted(cell)){ Date date = cell.getDateCellValue(); cellValue = new DateTime(date).toString("yyyy-MM-dd"); }else{ //不是日期格式,防止数字过长,转换为字符串显示 //注意转换为字符串后影响公式计算 //cell.setCellType(Cell.CELL_TYPE_STRING); //cellValue = cell.toString(); cellValue = String.valueOf(cell.getNumericCellValue()); } break; case Cell.CELL_TYPE_STRING: cellValue = cell.getStringCellValue(); break; case Cell.CELL_TYPE_BOOLEAN: cellValue = String.valueOf(cell.getBooleanCellValue()); break; case Cell.CELL_TYPE_FORMULA: //String formula = cell.getCellFormula(); //System.out.println(formula); //直接计算 cellValue = (formulaEvaluator.evaluate(cell)).formatAsString(); break; case Cell.CELL_TYPE_ERROR: System.out.println("【数据类型错误】"); break; default: break; } System.out.println(cellValue); }else{ System.out.println("【空白格】"); cellCount++; } } }else{ System.out.println("【空白行】"); rowCount++; } } } //关闭IO流 fileInputStream.close(); }
-
注意事项
公式计算
计算公式前栏位格式不能变化,以SUM公式为例,如果在公式计算前将数字字符转换为字符串,则计算值为0。
//注意转换为字符串后影响公式计算 //cell.setCellType(Cell.CELL_TYPE_STRING); //cellValue = cell.toString(); FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workBookTest);//获取公式 String cellValue = (formulaEvaluator.evaluate(cell)).formatAsString();
-
三、easyExcel操作
前期准备
导入依赖
<!--导入easyExcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
1、easyExcel写入
@Test public void simpleWrite() { EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data()); }
2、easyExcel读取
@Test
public void simpleRead() {
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
}