1 回答

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超21個(gè)贊
你的觀察是正確的。該問題的出現(xiàn)是因?yàn)橐话愕母↑c(diǎn)問題??梢院唵蔚乇硎緸椋?/p>
...
System.out.println(1.7/20.0); //0.08499999999999999
System.out.println((21.7-20.0)/20.0); //0.08499999999999996
...
如您所見,雙精度值 1.7 除以雙精度值 20.0 得到 0.08499999999999999。這很好,因?yàn)槭褂?時(shí)該值將被視為 0.085 DecimalFormat。但更復(fù)雜的方程 (21.7-20.0)/20.0 結(jié)果為 0.08499999999999996。這顯然低于 0.085。
Excel嘗試通過浮點(diǎn)值的附加規(guī)則來解決這些問題。它始終僅使用浮點(diǎn)值的 15 位有效十進(jìn)制數(shù)字。類似的事情也是如此Excel:
...
BigDecimal bd = new BigDecimal((21.7-20.0)/20.0);
System.out.println(bd.round(new MathContext(15)).doubleValue()); //0.085
...
apache poi's FormulaEvaluator和 it's 的DataFormatter行為都不像這Excel一點(diǎn)。這就是差異的原因。
人們可以擁有一個(gè)自己的,與/org/apache/poi/ss/usermodel/DataFormatter.javaMyDataFormatter的唯一區(qū)別是:
...
private String getFormattedNumberString(Cell cell, ConditionalFormattingEvaluator cfEvaluator) {
if (cell == null) {
return null;
}
Format numberFormat = getFormat(cell, cfEvaluator);
double d = cell.getNumericCellValue();
java.math.BigDecimal bd = new java.math.BigDecimal(d);
d = bd.round(new java.math.MathContext(15)).doubleValue();
if (numberFormat == null) {
return String.valueOf(d);
}
String formatted = numberFormat.format(Double.valueOf(d));
return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation
}
...
然后使用 thatMyDataFormatter而不是DataFormatter會(huì)更符合 的Excel行為。
例子:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class CreateExcelEvaluateFormula {
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
CreationHelper creationHelper = workbook.getCreationHelper();
FormulaEvaluator formulaEvaluator = creationHelper.createFormulaEvaluator();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0); cell.setCellValue(21.7);
cell = row.createCell(1); cell.setCellValue(20.0);
cell = row.createCell(2); cell.setCellFormula("(A1-B1)/B1");
formulaEvaluator.evaluateFormulaCell(cell);
double d = cell.getNumericCellValue();
System.out.println(d); //0.08499999999999996
MyDataFormatter dataFormatter = new MyDataFormatter();
String myFormat="0%";
CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, creationHelper.createDataFormat().getFormat(myFormat));
String val = dataFormatter.formatCellValue(cell, formulaEvaluator);
System.out.println(val); //9%
FileOutputStream out = new FileOutputStream("Excel.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
添加回答
舉報(bào)