各位兄台,想必经过昨日好梦,早已精神饱满,请允许小编接听上回,讲解POI进阶功法。
昨日奇闻:POI搞定电子表格
我们经过昨日的学习,懂得了POI基本的读写操作,今日让我们进一步看一下POI的高级使用方法。
壹
我们知道对于Excel是含有03版本和07版本,且对于两种版本其操作的不同,那么两者到底有何不同呢?
HSSF的写入
在写入的行数超过65536行,会报错
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0…65535)
但是它的速度很快,执行的流程是先写入缓存中,最后一起写入磁盘中去
@Test
public void test() throws Exception {
Long start = System.currentTimeMillis(); //默认的返回值为毫秒
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("我的03EXCELBIg");
for (int rowNum=0;rowNum<65536;++rowNum){
Row row = sheet.createRow(rowNum);
for (int cellNum=0;cellNum<10;++cellNum){
Cell cell = row.createCell(cellNum);
cell.setCellValue(rowNum+"-"+cellNum);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "03Big.XLS");
workbook.write(fileOutputStream);
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println((end-start)/1000);
}
//当rowNum超过65536时,报上面的错误,花费的时间根据电脑配置不同,花费的时间也不同 这里我的是3s
XSSF的写入
速度慢,耗内存,但是可以写入的数据为100万条
@Test
public void test() throws Exception {
Long start = System.currentTimeMillis();
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("我的07EXCELBIg");
for (int rowNum=0;rowNum<65536;++rowNum){
Row row = sheet.createRow(rowNum);
for (int cellNum=0;cellNum<10;++cellNum){
Cell cell = row.createCell(cellNum);
cell.setCellValue(rowNum+"-"+cellNum);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "03Big.XLSX");
workbook.write(fileOutputStream);
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println((end-start)/1000);
}
//这里的时间为18s 显然hssf更快
那么,当我们的数据很大时,速度不可以提升吗?当然是可以的,我们看一些Workbook的实现类
HSSFWorkbook //处理xls XSSFWorkbook //处理xlsx SXSSFWorkbook
//XSSFWorkbook的进阶版,为了提高处理xlsx的速度,使用方法和XSSFWorkbook是一样的
SXSSFWorkbook
SXSSF(软件包:org.apache.poi.xssf.streaming)是XSSF的API兼容流扩展,可用于必须生成非常大的电子表格且堆空间有限的情况。
XSSFWorkbook的进阶版,为了提高处理xlsx的速度,使用方法和XSSFWorkbook是一样的
SXSSF分配临时文件,您必须始终通过调用dispose方法来明确清理这些文件。
@Test
public void test2()throws Exception {
Long start = System.currentTimeMillis();
Workbook workbook = new SXSSFWorkbook();
Sheet sheet = workbook.createSheet("我的07EXCELBIgs");
for (int rowNum=0;rowNum<65536;++rowNum){
Row row = sheet.createRow(rowNum);
for (int cellNum=0;cellNum<10;++cellNum){
Cell cell = row.createCell(cellNum);
cell.setCellValue(rowNum+"-"+cellNum);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "03Bigs.XLSX");
workbook.write(fileOutputStream);
fileOutputStream.close();
//删除临时文件 注意
((SXSSFWorkbook) workbook).dispose();
long end = System.currentTimeMillis();
System.out.println((end-start)/1000);
}
速度变为4s 从18s到4s提高了
贰
昨天,我们使用POI读取数据时,都是字符串类型,但在Excel中的数据类型,却不仅仅只有字符串一种数据类型呢?
那么其他类型的读取怎么做呢?
我们通过查找源码,发现其中单元格的类型为
那么我们在读取时,先判断类型,然后在输出。代码小编已经写好了,小伙伴们可以直接拿去用,可以作为工具类的简单模型。
public class TestDifferentType {
private static String PATH = "D:\\Data\\idea数据\\small\\";
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream(PATH + "不同类型.xls");
Workbook workbook = new HSSFWorkbook(fileInputStream);
Sheet sheet = workbook.getSheetAt(0);
if(sheet!=null){
Row rowTop = sheet.getRow(0);
if(rowTop!=null){
int cells = rowTop.getPhysicalNumberOfCells();
for (int cellNum = 0; cellNum < cells; cellNum++) {
System.out.print(rowTop.getCell(cellNum).getStringCellValue()+" | ");
}
}
System.out.println("");
int rows = sheet.getPhysicalNumberOfRows();
for (int rowNum = 1; rowNum <rows ; rowNum++) {
Row row = sheet.getRow(rowNum);
int cells = rowTop.getPhysicalNumberOfCells();
for (int cellNum = 0; cellNum < cells; cellNum++) {
String cellValue = "";
Cell cell = row.getCell(cellNum);
CellType cellType = cell.getCellType();
switch (cellType){
case _NONE:
System.out.println("[异常类型]");
break;
case BLANK:
System.out.println("[空的]");
break;
case ERROR:
System.out.println("[错误的类型]");
break;
case STRING:
System.out.println("[字符串类型]");
cellValue = cell.getStringCellValue();
break;
case BOOLEAN:
System.out.println("[布尔型]");
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case NUMERIC:
System.out.println("[数字类型]");
if(HSSFDateUtil.isCellDateFormatted(cell)){
System.out.println("[日期]");
cellValue =new DateTime(cell.getDateCellValue()).toString("yyyy-MM-dd HH:mm:ss");
break;
}
cellValue = String.valueOf(cell.getNumericCellValue());
break;
}
System.out.println(cellValue);
}
}
}
fileInputStream.close();
}
}
叁
Excel在实际的工作中,可以做成绩单,工资表,其中关于数字的求和,求差等操作,可以利用公式解决。
那么POI也可以读取公式,从而达到读取数据的作用。
得到公式 String cellFormula = cell.getCellFormula();
// 下面的类进行执行
FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook); CellValue value = formulaEvaluator.evaluate(cell);
后记
poi的使用讲解完毕,希望各位小伙伴们,都有所收获。