Java 如何使用ApachePOI缓存公式单元格

Java 如何使用ApachePOI缓存公式单元格,java,excel,apache-poi,Java,Excel,Apache Poi,因为我需要在excel中使用函数,所以我创建了如下代码来创建excel文件并计算和获取单元格值。apache poi不支持此函数,所以我认为我必须读取缓存的/格式化的值 主包装; 导入java.io.File; 导入java.io.FileOutputStream; 导入java.io.IOException; 导入java.util.Scanner; 导入org.apache.poi.ss.usermodel.Cell; 导入org.apache.poi.ss.usermodel.DataFo

因为我需要在excel中使用函数,所以我创建了如下代码来创建excel文件并计算和获取单元格值。apache poi不支持此函数,所以我认为我必须读取缓存的/格式化的值

主包装; 导入java.io.File; 导入java.io.FileOutputStream; 导入java.io.IOException; 导入java.util.Scanner; 导入org.apache.poi.ss.usermodel.Cell; 导入org.apache.poi.ss.usermodel.DataFormatter; 导入org.apache.poi.ss.usermodel.Row; 导入org.apache.poi.ss.usermodel.Sheet; 导入org.apache.poi.ss.usermodel.工作簿; 导入org.apache.poi.xssf.usermodel.XSSFRow; 导入org.apache.poi.xssf.usermodel.xssfheet; 导入org.apache.poi.xssf.usermodel.xssf工作簿; 公共类工作簿计算器 { 公共静态无效pop_u均值 { System.out.println测试总体平均值在两个不同总体中是否相同; System.out.println此程序仅适用于双尾; 扫描仪输入=新的ScannerSystem.in; 人口是什么意思; 双m=in.nextDouble; System.out.println从总体中采集了多少样本?:; 双n=in.nextDouble; System.out.println示例的含义是什么; 双X=in.nextDouble; System.out.println总体的无偏方差是多少:; 双U=in.nextDouble; System.out.println什么是具有%值的重要性级别类型; 双L=in.nextDouble; 双l=l/100; 双a=n-1; 双b=X-m; 双c=Math.sqrtn; 双d=数学sqrtU; 双f=d/c; 双T=b/f; System.out.println自由度为+a; System.out.println检验统计量为+T; 工作簿wb=新的XSSF工作簿; Sheet Sheet=wb.createSheet; 行row1=sheet.createRow1; 行row2=sheet.createRow2; Cell cell1_1=行1.createCell1; Cell cell1_2=row1.createCell2; Cell cell1_3=行1.createCell3; Cell cell2_3=row2.createCell3; Cell cell2_4=行2.createCell4; cell1_1.setCellValuel; cell1_2.setCellValuea; cell2_3.setCellFormula_xlfn.T.INV.2T+l+,+a+; cell2_4.setCellFormulaSUM+l+,+a+; FileOutputStream out=null; 试一试{ out=新文件outputstreamt-inverse.xlsx; wb.writeout; }卡奇奥例外{ System.out.printlne.toString; }最后{ 试一试{ 关上; }卡奇奥例外{ System.out.printlne.toString; } } } 公共静态无效读取\u excel引发IOException {
对于int q=3;q您似乎误解了apache poi的用途。就Excel而言,它是用来创建Excel文件的。这意味着它创建了Excel能够打开的文件。当它打开工作簿文件时,它将它们作为apache poi工作簿打开,只是为了能够附加内容。apache poi被认为与Excel不同,它确实如此不与任何Excel应用程序交互

因此,setForceFormulaRecalculation不是apache poi设置,而是Excel打开工作簿时的Excel设置。如果setForceFormulaRecalculation设置为true,则Excel在Excel打开工作簿文件时会重新计算所有公式。这并不意味着apache poi会重新计算所有公式

要强制apache poi计算公式,需要使用FormulaEvaluator

例如,如果按如下方式扩展代码:

...
import org.apache.poi.ss.usermodel.FormulaEvaluator;
...
            Workbook wb = new XSSFWorkbook();
            FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
...
            cell2_4.setCellFormula("SUM(" + l +"," + a + ")");
            try {
                evaluator.evaluateFormulaCell(cell2_4);
            } catch (org.apache.poi.ss.formula.eval.NotImplementedException notImplEx) {
                notImplEx.printStackTrace();
            }
...
然后求和公式,cell2_4包含公式之外的计算数值

但当然

...
            cell2_3.setCellFormula("TINV(" + l +"," + a + ")");
            try {
                evaluator.evaluateFormulaCell(cell2_3);
            } catch (org.apache.poi.ss.formula.eval.NotImplementedException notImplEx) {
                notImplEx.printStackTrace();
            }
...
将导致NotImplementedException,因为TINV尚未在apache poi中实现

因此,我们需要执行中所示的操作。就TINV函数而言,这将是:

...
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.formula.functions.*;
import org.apache.commons.math3.distribution.TDistribution;
...
    static Function TINV = new Fixed2ArgFunction() {
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2) {
            try {
                ValueEval ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
                double dArg1 = OperandResolver.coerceValueToDouble(ve1);
                ValueEval ve2 = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex);
                double dArg2 = OperandResolver.coerceValueToDouble(ve2);

                TDistribution t = new TDistribution(dArg2);
                double result = t.inverseCumulativeProbability(1d - dArg1/2d);

                if (Double.isNaN(result) || Double.isInfinite(result)) {
                    throw new EvaluationException(ErrorEval.NUM_ERROR);
                }

                return new NumberEval(result);

            } catch (EvaluationException e) {
                return e.getErrorEval();
            }
        }
    };
...
然后

...
        WorkbookEvaluator.registerFunction("TINV", TINV);
...
注意,我已经实现了TINV而不是xlfn.T.INV.2T,因为后者由于名称奇怪而无法以这种方式实现。我知道的所有Excel版本也支持TINV而不是xlfn.T.INV.2T

扩展代码的完整示例:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
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.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.formula.functions.*;
import org.apache.commons.math3.distribution.TDistribution;

public class WorkbookEvaluatorTest {

    static Function TINV = new Fixed2ArgFunction() {
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2) {
            try {
                ValueEval ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
                double dArg1 = OperandResolver.coerceValueToDouble(ve1);
                ValueEval ve2 = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex);
                double dArg2 = OperandResolver.coerceValueToDouble(ve2);

                TDistribution t = new TDistribution(dArg2);
                double result = t.inverseCumulativeProbability(1d - dArg1/2d);

                if (Double.isNaN(result) || Double.isInfinite(result)) {
                    throw new EvaluationException(ErrorEval.NUM_ERROR);
                }

                return new NumberEval(result);

            } catch (EvaluationException e) {
                return e.getErrorEval();
            }
        }
    };

    public static void pop_mean() {

        WorkbookEvaluator.registerFunction("TINV", TINV);

        System.out.println ("Test population mean in two different populations are same or not");
        System.out.println ("This program works only for two-tailed ");

        Scanner in = new Scanner(System.in);
        System.out.println ("What is population mean?:");
        double m = in.nextDouble();

        System.out.println ("How many samples are taken from population?:");
        double n = in.nextDouble();

        System.out.println ("What is Sample mean?:");
        double X = in.nextDouble();

        System.out.println ("What is unbiased variance for population:");
        double U = in.nextDouble();

        System.out.println ("What is Level of Significance (Type with %-value)");
        double L = in.nextDouble();
        double l = L/100;

        double a = n-1;
        double b = X-m;
        double c = Math.sqrt(n);
        double d = Math.sqrt(U);
        double f = d/c;
        double T = b/f;
        System.out.println ("Degree of freedom is " + a);
        System.out.println ("Test statistic is " + T);

        Workbook wb = new XSSFWorkbook();
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

        Sheet sheet = wb.createSheet();
        Row row1 = sheet.createRow(1);
        Row row2 = sheet.createRow(2);

        Cell cell1_1 = row1.createCell(1);
        Cell cell1_2 = row1.createCell(2);
        Cell cell1_3 = row1.createCell(3);
        Cell cell2_3 = row2.createCell(3);
        Cell cell2_4 = row2.createCell(4);

        cell1_1.setCellValue(l);
        cell1_2.setCellValue(a);
        cell2_3.setCellFormula("TINV(" + l +"," + a + ")");
        try {
            evaluator.evaluateFormulaCell(cell2_3);
        } catch (org.apache.poi.ss.formula.eval.NotImplementedException notImplEx) {
            notImplEx.printStackTrace();
        }

        cell2_4.setCellFormula("SUM(" + l +"," + a + ")");
        try {
            evaluator.evaluateFormulaCell(cell2_4);
        } catch (org.apache.poi.ss.formula.eval.NotImplementedException notImplEx) {
            notImplEx.printStackTrace();
        }

        FileOutputStream out = null;
        try {
            out = new FileOutputStream("T-inverse.xlsx");
            wb.write(out);
        } catch(IOException e) {
            System.out.println("Write: " + e.toString());
        } finally {
            try {
                out.close();
                wb.close();
            } catch(IOException e) {
                System.out.println("Close: " + e.toString());
            }
        }
    }

    public static void read_excel() throws IOException {
        for (int q=3;q<5;q++) {
            XSSFWorkbook book = new XSSFWorkbook("T-inverse.xlsx");
            //book.setForceFormulaRecalculation(true);
            XSSFSheet sheet = book.getSheetAt(0);
            //sheet.setForceFormulaRecalculation(true);
            XSSFRow row = sheet.getRow(2);
            final DataFormatter dataFormatter = new DataFormatter(); 
            final double formtatedValue = row.getCell((short) q).getNumericCellValue(); 
            System.out.println(formtatedValue);
        }
    }

    public static void main(String[] args) throws IOException {    
        pop_mean();
        read_excel();
    }
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
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.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.formula.functions.*;
import org.apache.commons.math3.distribution.TDistribution;

public class WorkbookEvaluatorTest {

    static Function TINV = new Fixed2ArgFunction() {
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2) {
            try {
                ValueEval ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
                double dArg1 = OperandResolver.coerceValueToDouble(ve1);
                ValueEval ve2 = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex);
                double dArg2 = OperandResolver.coerceValueToDouble(ve2);

                TDistribution t = new TDistribution(dArg2);
                double result = t.inverseCumulativeProbability(1d - dArg1/2d);

                if (Double.isNaN(result) || Double.isInfinite(result)) {
                    throw new EvaluationException(ErrorEval.NUM_ERROR);
                }

                return new NumberEval(result);

            } catch (EvaluationException e) {
                return e.getErrorEval();
            }
        }
    };

    public static void pop_mean() {

        WorkbookEvaluator.registerFunction("TINV", TINV);

        System.out.println ("Test population mean in two different populations are same or not");
        System.out.println ("This program works only for two-tailed ");

        Scanner in = new Scanner(System.in);
        System.out.println ("What is population mean?:");
        double m = in.nextDouble();

        System.out.println ("How many samples are taken from population?:");
        double n = in.nextDouble();

        System.out.println ("What is Sample mean?:");
        double X = in.nextDouble();

        System.out.println ("What is unbiased variance for population:");
        double U = in.nextDouble();

        System.out.println ("What is Level of Significance (Type with %-value)");
        double L = in.nextDouble();
        double l = L/100;

        double a = n-1;
        double b = X-m;
        double c = Math.sqrt(n);
        double d = Math.sqrt(U);
        double f = d/c;
        double T = b/f;
        System.out.println ("Degree of freedom is " + a);
        System.out.println ("Test statistic is " + T);

        Workbook wb = new XSSFWorkbook();
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

        Sheet sheet = wb.createSheet();
        Row row1 = sheet.createRow(1);
        Row row2 = sheet.createRow(2);

        Cell cell1_1 = row1.createCell(1);
        Cell cell1_2 = row1.createCell(2);
        Cell cell1_3 = row1.createCell(3);
        Cell cell2_3 = row2.createCell(3);
        Cell cell2_4 = row2.createCell(4);

        cell1_1.setCellValue(l);
        cell1_2.setCellValue(a);
        cell2_3.setCellFormula("TINV(" + l +"," + a + ")");
        try {
            evaluator.evaluateFormulaCell(cell2_3);
        } catch (org.apache.poi.ss.formula.eval.NotImplementedException notImplEx) {
            notImplEx.printStackTrace();
        }

        cell2_4.setCellFormula("SUM(" + l +"," + a + ")");
        try {
            evaluator.evaluateFormulaCell(cell2_4);
        } catch (org.apache.poi.ss.formula.eval.NotImplementedException notImplEx) {
            notImplEx.printStackTrace();
        }

        FileOutputStream out = null;
        try {
            out = new FileOutputStream("T-inverse.xlsx");
            wb.write(out);
        } catch(IOException e) {
            System.out.println("Write: " + e.toString());
        } finally {
            try {
                out.close();
                wb.close();
            } catch(IOException e) {
                System.out.println("Close: " + e.toString());
            }
        }
    }

    public static void read_excel() throws IOException {
        for (int q=3;q<5;q++) {
            XSSFWorkbook book = new XSSFWorkbook("T-inverse.xlsx");
            //book.setForceFormulaRecalculation(true);
            XSSFSheet sheet = book.getSheetAt(0);
            //sheet.setForceFormulaRecalculation(true);
            XSSFRow row = sheet.getRow(2);
            final DataFormatter dataFormatter = new DataFormatter(); 
            final double formtatedValue = row.getCell((short) q).getNumericCellValue(); 
            System.out.println(formtatedValue);
        }
    }

    public static void main(String[] args) throws IOException {    
        pop_mean();
        read_excel();
    }
}