JAVA POI 1.17读取模板公式数据问题
最近在开发过程中碰到了一个这样的需求:工程内导入一个excel模板,模板有四个sheet页,第一个sheet页用来填充从数据库中读取的原始数据,剩余的三个sheet页全都是各种各样的计算公式,通过计算第一个sheet页的原始数据得出计算数据并存入我们的数据库。
数据导入之后,当我读取公式计算数据的时候,问题出现了,cell读到的是公式而不是计算好的数据,使用下面两个方法读取会报公式错误:
try {
cellValue = String.valueOf(cell.getNumericCellValue());
} catch (IllegalStateException e) {
cellValue = String.valueOf(cell.getRichStringCellValue());
}
于是我将生成的excel拿出来看了一下,原始数据已经插入了,但是应该生成数据的计算sheet页却全部还是显示的公式,并没有显示计算好的数据。于是我去网上查了一下,得到了以下一个方法,可以强制刷新计算公式:
//刷新sheet页里面的公式
sheet.setForceFormulaRecalculation(true);
刷新完之后excel确实已经生成了数据,但是java代码里面读取到的还是公式,这就比较奇怪了。于是我又用表达式强制计算了一遍,这次终于可以读取到了:
//强制计算
wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
附整体的一个计算代码:
XSSFWorkbook wb = new XSSFWorkbook(file);
//读取sheet页
XSSFSheet sheet = wb.getSheet("sheet1");
//刷新公式
wb.setForceFormulaRecalculation(true);
//强制计算
wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
//工作表的行
Row row;
Cell cell;
//获取sheet页A1的公式的数据
row = sheet.getRow(0);
cell = row.getCell(0);
String cellValue="-";
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
switch (cell.getCellTypeEnum()) {
case STRING: // 文本
cellValue = cell.getRichStringCellValue().getString();
break;
case NUMERIC: // 数字、日期
if (DateUtil.isCellDateFormatted(cell)) {
cellValue = ft.format(cell.getDateCellValue());
} else {
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
case BOOLEAN: // 布尔型
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case BLANK: // 空白
cellValue = cell.getStringCellValue();
break;
case ERROR: // 错误
cellValue = "错误";
break;
case FORMULA: // 公式
// 得到对应单元格的字符串
try {
cellValue = String.valueOf(cell.getNumericCellValue());
} catch (IllegalStateException e) {
cellValue = String.valueOf(cell.getRichStringCellValue());
}
break;
default:
cellValue = "-";
}