poi 등록 함수
5661 단어 문제 소기
poi는 excle의 일부 함수만 지원합니다:
지원되는 함수:[ABS, ACOS, ACOSH, ADDRESS, AND, ASIN, ASINH, ATAN, ATAN2, ATANH, AVEDEV, AVERAGE, CEILING, CHAR, CHOOSE, CLEAN, CODE, COLUMN, COLUMNS, COMBIN, CONCATENATE, COS, COSH, COUNT, COUNTA, COUNTBLANK, COUNTIF, DATE, DAY, DAYS360, DEGREES, DEVSQ, DOLLAR, ERROR.TYPE, EVEN, EXACT, EXP, FACT, FALSE, FIND, FIXED, FLOOR, FV, HLOOKUP, HOUR, HYPERLINK, IF, INDEX, INDIRECT, INT, INTERCEPT, IPMT, IRR, ISBLANK, ISERROR, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISREF, ISTEXT, LARGE, LEFT, LEN, LN, LOG, LOG10, LOOKUP, LOWER, MATCH, MAX, MAXA, MEDIAN, MID, MIN, MINA, MINUTE, MIRR, MOD, MODE, MONTH, NA, NOT, NOW, NPER, NPV, ODD, OFFSET, OR, PERCENTILE, PI, PMT, POISSON, POWER, PPMT, PRODUCT, PROPER, PV, RADIANS, RAND, RANK, RATE, REPLACE, REPT, RIGHT, ROMAN, ROUND, ROUNDDOWN, ROUNDUP, ROW, ROWS, SEARCH, SECOND, SIGN, SIN, SINH, SLOPE, SMALL, SQRT, stdEV, SUBSTITUTE, SUBTOTAL, SUM, SUMIF, SUMPRODUCT, SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2, T, TAN, TANH, TEXT, TIME, TODAY, TRIM, TRUE, TRUNC, UPPER, VALUE, VAR, VARP, VLOOKUP, WEEKDAY, YEAR]
지원되지 않는 함수:[AREAS, ASC, AVERAGEA, BETADIST, BETAINV, BINOMDIST, CELL, CHIDIST, CHIINV, CHITEST, CONFIDENCE, CORREL, COVAR, CRITBINOM, DATEDIF, DATESTRING, DATEVALUE, DAVERAGE, DB, DBCS, DCOUNT, DCOUNTA, DDB, DGET, DMAX, DMIN, DPRODUCT, DstdEV, DstdEVP, DSUM, DVAR, DVARP, EXPONDIST, FDIST, FINDB, FINV, FISHER, FISHERINV, FORECAST, FREQUENCY, FTEST, GAMMADIST, GAMMAINV, GAMMALN, GEOMEAN, GETPIVOTDATA, GROWTH, HARMEAN, HYPGEOMDIST, INFO, ISERR, ISPMT, KURT, LEFTB, LENB, LINEST, LOGEST, LOGINV, LOGNORMDIST, MDETERM, MIDB, MINVERSE, MMULT, N, NEGBINOMDIST, NORMDIST, NORMINV, NORMSDIST, NORMSINV, NUMBERSTRING, PEARSON, PERCENTRANK, PERMUT, PHONETIC, PROB, QUARTILE, REPLACEB, RIGHTB, RSQ, SEARCHB, SKEW, SLN, STANDARDIZE, stdEVA, stdEVP, stdEVPA, STEYX, SYD, TDIST, TIMEVALUE, TINV, TRANSPOSE, TREND, TRIMMEAN, TTEST, TYPE, USDOLLAR, VARA, VARPA, VDB, WEIBULL, ZTEST]
지원하지 않는 함수를 사용할 때 수동으로 등록해야 합니다. 다음은 수동으로 함수를 등록하는 방법입니다.
최근에 해석 excle에서 NORMINV(정적 분포)라는 함수를 만났습니다.
우선 등록할 때 저희는 한 번만 등록하면 돼요. (등록이 중복되면 오류가 발생) 그래서 제가 감청을 썼어요. bean에 불러온 후에 등록 함수.
package com.tsingyun.iec104.listener;
import org.apache.poi.ss.formula.eval.FunctionEval;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import com.tsingyun.iec104.poi.registerFunction;
/**
* @author gyx
* @date 2018 7 20 2:55:05
*
*/
@Component
public class Listener implements ApplicationListener{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//
FunctionEval.registerFunction("NORMINV", new registerFunction());
}
}
그 다음에 공식 클래스를 만듭니다. ('org.apache.commons:commons-math3:3.6.1')
package com.tsingyun.iec104.poi;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author gyx
* @date 2018 8 9 5:17:37
*
*/
public class registerFunction implements Function{
@Override
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
String argss = args[0].toString()+args[1].toString()+args[2].toString();
List list = extractMessageByRegular(argss);
//new NormalDistribution(mean,standard_dev)
NormalDistribution normalDistributioin = new NormalDistribution(Double.valueOf(list.get(1)), Double.valueOf(list.get(2)));
//double S1 = normalDistributioin.cumulativeProbability(Double.valueOf(list.get(0)));
//normalDistributioin.inverseCumulativeProbability(probability)
double S2 = normalDistributioin.inverseCumulativeProbability(Double.valueOf(list.get(0)));
return new NumberEval(S2);
}
/**
*
* @param msg
* @return
*/
public static List extractMessageByRegular(String msg){
List list=new ArrayList();
Pattern p = Pattern.compile("(\\[[^\\]]*\\])");
Matcher m = p.matcher(msg);
while(m.find()){
list.add(m.group().substring(1, m.group().length()-1));
}
return list;
}
}
이제 NORMINV 공식이 등록되었습니다.
NORMINV 방정식이 나타나면 방정식을 업데이트할 수 있습니다.
/**
* cell , cell , String
*
* @param cell
* @return
*/
private String getCellValue(XSSFCell cell) {
String value = null;
if(cell==null){
return "";
}
//
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_STRING://
value = cell.getRichStringCellValue().toString();
break;
case XSSFCell.CELL_TYPE_NUMERIC://
long dd = (long) cell.getNumericCellValue();
value = dd + "";
break;
case XSSFCell.CELL_TYPE_BLANK:
value = "";
break;
case XSSFCell.CELL_TYPE_FORMULA:
eval.evaluateFormulaCell(cell); //
try {
value = String.valueOf(cell.getNumericCellValue());
} catch (IllegalStateException e) {
value = String.valueOf(cell.getRichStringCellValue());
}
break;
case XSSFCell.CELL_TYPE_BOOLEAN:// boolean
value = String.valueOf(cell.getBooleanCellValue());
break;
case XSSFCell.CELL_TYPE_ERROR:
value = String.valueOf(cell.getErrorCellValue());
break;
default:
System.out.println("default");
break;
}
return value;
}