Вы, кажется, неправильно поняли, для чего apache poi
создан. С точки зрения Excel
это сделано для создания Excel
файлов. Это создает файлы, которые Excel
может открыть. Когда он открывает файлы книги, он открывает их как apache poi
Workbook
только для возможности добавления содержимого. 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();
}
...
затем вычисляется формула SUM
, а cell2_4
содержит вычисленное число чисел c, дополнительное к формуле.
Но, конечно,
...
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();
}
}