问题追踪
- 实现简单的数学公式计算,例如方差、阶乘、排列组合等。
- 自定义公式进行计算。
- 单值后果。
需要剖析
利用Apache POI
实现动静写入Excel
公式和公式参数,读取计算后的数值。
Maven
<!-- Apache POI start --><dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.0.0</version> <scope>test</scope></dependency><!-- xss模式 --><dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.0.0</version> <scope>test</scope></dependency><!-- Apache POI end -->
JAVA
import org.apache.poi.hssf.usermodel.HSSFCell;import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellValue;import org.apache.poi.ss.usermodel.FormulaEvaluator;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xssf.usermodel.XSSFCell;import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;import org.apache.poi.xssf.usermodel.XSSFWorkbook;/** * 利用Apache Poi实现动静公式计算 * * @author BBF */public class PoiTest { private static final CellValue DEFAULT_VALUE = new CellValue(""); /** * 获取单元格 * <p>如果单元格没有值,须要构建单元格</p> * * @param row 行对象 * @param idx 单元格的列索引号,从0开始 * @return 单元格对象 */ private static Cell getCell(Row row, int idx) { Cell cell = row.getCell(idx); if (cell == null) { cell = row.createCell(idx); } return cell; } /** * 从新计算单元格的值 * <p style="color:red">特地留神:当动静扭转excel的值的时候,必须用本办法从新用公式计算单元格的值</p> * * @param cell 单元格 * @return {@link org.apache.poi.ss.usermodel.CellValue} */ private static CellValue calcCellValue(Cell cell) { Workbook workbook = cell.getSheet().getWorkbook(); FormulaEvaluator formulaEvaluator = null; if (cell instanceof HSSFCell) { // Excel 2003 formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook); } else if (cell instanceof XSSFCell) { // Excel 2007+ formulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook); } if (formulaEvaluator != null) { // 进行计算并拿到值 return formulaEvaluator.evaluate(cell); } return DEFAULT_VALUE; } /** * 从新设置公式和值,并读取公式计算后的值 * * @param args Main函数默认入参 */ public static void main(String[] args) { // 创立空对象(xssf - excel2007+;hssf - excel2003) Workbook hw = new XSSFWorkbook(); // 创立sheet Sheet sheet = hw.createSheet(); // 定位excel的行 Row r1 = sheet.createRow(0); // 调用公式取值 Cell c1 = getCell(r1, 0); // 从新设置单元格的公式,不容许等号结尾!!此公式间接从excel文件中复制进去。 c1.setCellFormula("SQRT(POWER(B1+C1,2)/D1)"); // 传入值,顺次是B1、C1、D1 getCell(r1, 1).setCellValue(9); getCell(r1, 2).setCellValue(8); getCell(r1, 3).setCellValue(4); // 获取c1的值,也就是公式计算后的值 CellValue v1 = calcCellValue(c1); System.out.println("单元格的值:" + v1.formatAsString()); c1.setCellFormula("FACT(B1)"); System.out.println("阶乘值: " + calcCellValue(c1).getNumberValue()); }}
执行后果
单元格的值:8.5阶乘值: 362880.0
备注
- 应用空的
XSSFWorkbook
对象,实用于Excel2007+
,同时也向下兼容Excel2003
的公式。 - 公式的语法能够参考
Excel
相干文档,倡议先在Excel
中编辑调试一下。