POI读取公式的值

简介: excel中的数据:   package poi; import java.io.FileInputStream; import java.io.IOException; import java.

excel中的数据:

 

package poi;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

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;

public class TestReadFormula {
    private static FormulaEvaluator evaluator;
    public static void main(String[] args) throws IOException {
        InputStream is=new FileInputStream("ReadFormula.xls");
        HSSFWorkbook wb=new HSSFWorkbook(is);
        Sheet sheet=wb.getSheetAt(0);
        
        evaluator=wb.getCreationHelper().createFormulaEvaluator();
        
        for (int i = 1; i <4; i++) {
            Row  row=sheet.getRow(i);
            for (Cell cell : row) {
                System.out.println(getCellValue(cell));
            }
        }
        wb.close();
        
        
    }

    private static String getCellValue(Cell cell) {
        if (cell==null) {
            return "isNull";
        }
        System.out.println("rowIdx:"+cell.getRowIndex()+",colIdx:"+cell.getColumnIndex());
        String cellValue = null;
        switch (cell.getCellType()) {
        case Cell.CELL_TYPE_STRING:
            System.out.print("STRING :");
            cellValue=cell.getStringCellValue();
            break;

        case Cell.CELL_TYPE_NUMERIC:
            System.out.print("NUMERIC:");
            cellValue=String.valueOf(cell.getNumericCellValue());
            break;
            
        case Cell.CELL_TYPE_FORMULA:
            System.out.print("FORMULA:");
            cellValue=getCellValue(evaluator.evaluate(cell));
            break;
        default:
            System.out.println("Has Default.");
            break;
        }
        
        return cellValue;
    }

    private static String getCellValue(CellValue cell) {
        String cellValue = null;
        switch (cell.getCellType()) {
        case Cell.CELL_TYPE_STRING:
            System.out.print("String :");
            cellValue=cell.getStringValue();
            break;

        case Cell.CELL_TYPE_NUMERIC:
            System.out.print("NUMERIC:");
            cellValue=String.valueOf(cell.getNumberValue());
            break;
        case Cell.CELL_TYPE_FORMULA:
            System.out.print("FORMULA:");
            break;
        default:
            break;
        }
        
        return cellValue;
    }

}

 

Output:

rowIdx:1,colIdx:0
STRING :begin
rowIdx:1,colIdx:1
STRING :end
rowIdx:1,colIdx:2
FORMULA:String :beginend
rowIdx:2,colIdx:0
NUMERIC:1.0
rowIdx:2,colIdx:1
NUMERIC:3.0
rowIdx:2,colIdx:2
FORMULA:String :13
rowIdx:3,colIdx:0
NUMERIC:1.0
rowIdx:3,colIdx:1
NUMERIC:3.0
rowIdx:3,colIdx:2
FORMULA:NUMERIC:4.0

 

 

Formula Evaluation:

User API How-TO

The following code demonstrates how to use the FormulaEvaluator in the context of other POI excel reading code.

There are several ways in which you can use the FormulaEvalutator API.

Using FormulaEvaluator.evaluate(Cell cell)

This evaluates a given cell, and returns the new value, without affecting the cell

FileInputStream fis = new FileInputStream("c:/temp/test.xls");
Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("c:/temp/test.xls")
Sheet sheet = wb.getSheetAt(0);
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

// suppose your formula is in B3
CellReference cellReference = new CellReference("B3"); 
Row row = sheet.getRow(cellReference.getRow());
Cell cell = row.getCell(cellReference.getCol()); 

CellValue cellValue = evaluator.evaluate(cell);

switch (cellValue.getCellType()) {
    case Cell.CELL_TYPE_BOOLEAN:
        System.out.println(cellValue.getBooleanValue());
        break;
    case Cell.CELL_TYPE_NUMERIC:
        System.out.println(cellValue.getNumberValue());
        break;
    case Cell.CELL_TYPE_STRING:
        System.out.println(cellValue.getStringValue());
        break;
    case Cell.CELL_TYPE_BLANK:
        break;
    case Cell.CELL_TYPE_ERROR:
        break;

    // CELL_TYPE_FORMULA will never happen
    case Cell.CELL_TYPE_FORMULA: 
        break;
}				
        

Thus using the retrieved value (of type FormulaEvaluator.CellValue - a nested class) returned by FormulaEvaluator is similar to using a Cell object containing the value of the formula evaluation. CellValue is a simple value object and does not maintain reference to the original cell.

Using FormulaEvaluator.evaluateFormulaCell(Cell cell)

evaluateFormulaCell(Cell cell) will check to see if the supplied cell is a formula cell. If it isn't, then no changes will be made to it. If it is, then the formula is evaluated. The value for the formula is saved alongside it, to be displayed in excel. The formula remains in the cell, just with a new value

The return of the function is the type of the formula result, such as Cell.CELL_TYPE_BOOLEAN

FileInputStream fis = new FileInputStream("/somepath/test.xls");
Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
Sheet sheet = wb.getSheetAt(0);
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

// suppose your formula is in B3
CellReference cellReference = new CellReference("B3"); 
Row row = sheet.getRow(cellReference.getRow());
Cell cell = row.getCell(cellReference.getCol()); 

if (cell!=null) {
    switch (evaluator.evaluateFormulaCell(cell)) {
        case Cell.CELL_TYPE_BOOLEAN:
            System.out.println(cell.getBooleanCellValue());
            break;
        case Cell.CELL_TYPE_NUMERIC:
            System.out.println(cell.getNumericCellValue());
            break;
        case Cell.CELL_TYPE_STRING:
            System.out.println(cell.getStringCellValue());
            break;
        case Cell.CELL_TYPE_BLANK:
            break;
        case Cell.CELL_TYPE_ERROR:
            System.out.println(cell.getErrorCellValue());
            break;

        // CELL_TYPE_FORMULA will never occur
        case Cell.CELL_TYPE_FORMULA: 
            break;
    }
}
				

Using FormulaEvaluator.evaluateInCell(Cell cell)

evaluateInCell(Cell cell) will check to see if the supplied cell is a formula cell. If it isn't, then no changes will be made to it. If it is, then the formula is evaluated, and the new value saved into the cell, in place of the old formula.

FileInputStream fis = new FileInputStream("/somepath/test.xls");
Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
Sheet sheet = wb.getSheetAt(0);
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

// suppose your formula is in B3
CellReference cellReference = new CellReference("B3");
Row row = sheet.getRow(cellReference.getRow());
Cell cell = row.getCell(cellReference.getCol()); 

if (cell!=null) {
    switch (evaluator.evaluateInCell(cell).getCellType()) {
        case Cell.CELL_TYPE_BOOLEAN:
            System.out.println(cell.getBooleanCellValue());
            break;
        case Cell.CELL_TYPE_NUMERIC:
            System.out.println(cell.getNumericCellValue());
            break;
        case Cell.CELL_TYPE_STRING:
            System.out.println(cell.getStringCellValue());
            break;
        case Cell.CELL_TYPE_BLANK:
            break;
        case Cell.CELL_TYPE_ERROR:
            System.out.println(cell.getErrorCellValue());
            break;

        // CELL_TYPE_FORMULA will never occur
        case Cell.CELL_TYPE_FORMULA:
            break;
    }
}

        

Re-calculating all formulas in a Workbook

FileInputStream fis = new FileInputStream("/somepath/test.xls");
Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
    Sheet sheet = wb.getSheetAt(sheetNum);
    for(Row r : sheet) {
        for(Cell c : r) {
            if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
                evaluator.evaluateFormulaCell(c);
            }
        }
    }
}
        

Alternately, if you know which of HSSF or XSSF you're working with, then you can call the static evaluateAllFormulaCells method on the appropriate HSSFFormulaEvaluator or XSSFFormulaEvaluator class.

http://poi.apache.org/spreadsheet/eval.html

 

相关文章
excel根据数据得出公式
excel根据数据得出公式
excel判断表格中是否有重复值
excel判断表格中是否有重复值
POI生成EXCEL,公式不自动执行的有关问题
POI生成EXCEL,公式不自动执行的问题 场景:POI读取Excel模板。 当使用POI操作Excel时,发现由POI生成的公式能够在打开Excel是被执行, 而事先手工写入Excel模板文件的公式则不自动被调用,必须手动双击该Cell才能生效。
1668 0
|
6月前
Excel实例:数组公式和函数
Excel实例:数组公式和函数
|
6月前
|
Java Apache 索引
POI操作大全(动态合并单元格,为单元格生成一个自定义的数据显示格式,自定义公式计算结果生成,读取excel,word文件在生成图片,word指定位置生成图片)
POI操作大全(动态合并单元格,为单元格生成一个自定义的数据显示格式,自定义公式计算结果生成,读取excel,word文件在生成图片,word指定位置生成图片)
909 0
|
6月前
|
人工智能 程序员 数据处理
Pandas数据处理4、DataFrame记录重复值出现的次数(是总数不是每个值的数量)
Pandas数据处理4、DataFrame记录重复值出现的次数(是总数不是每个值的数量)
97 0
Pandas数据处理4、DataFrame记录重复值出现的次数(是总数不是每个值的数量)
excel使用poi获取单元格类型和数据、判断单个单元格为空、判断每行列数是否相等问题
excel使用poi获取单元格类型和数据、判断单个单元格为空、判断每行列数是否相等问题
590 0
POI读取不同的数据类型
POI读取不同的数据类型
304 0
POI读取不同的数据类型
成功解决在excel表中通过数学函数转换后,接着去掉公式转为不再随着变化的数值
成功解决在excel表中通过数学函数转换后,接着去掉公式转为不再随着变化的数值
成功解决在excel表中通过数学函数转换后,接着去掉公式转为不再随着变化的数值
ML之DS:仅需一行代码实现对某字段下的所有数值实现同一机制的改变或转换(比如全部转为str类型/全部取平方值)
ML之DS:仅需一行代码实现对某字段下的所有数值实现同一机制的改变或转换(比如全部转为str类型/全部取平方值)
ML之DS:仅需一行代码实现对某字段下的所有数值实现同一机制的改变或转换(比如全部转为str类型/全部取平方值)