Java poi计算的日期公式值错误
我有以下代码Java poi计算的日期公式值错误,java,apache-poi,Java,Apache Poi,我有以下代码 public boolean processCell(boolean hasData, StringBuffer rowData, Cell cell) { switch (cell.getCellType()) { case Cell.CELL_TYPE_FORMULA: { try { this.evaluator.clearAllCachedResultValues(); switch (this.evaluator.
public boolean processCell(boolean hasData, StringBuffer rowData, Cell cell)
{
switch (cell.getCellType())
{
case Cell.CELL_TYPE_FORMULA:
{
try
{
this.evaluator.clearAllCachedResultValues();
switch (this.evaluator.evaluateFormulaCell(cell))
{
case XSSFCell.CELL_TYPE_NUMERIC:
{
if (DateUtil.isCellDateFormatted(cell))
{
logger.warn(cell.getCellFormula());
rowData.append(dateFormat.format(cell.getDateCellValue()));
hasData = true;
}
else
{
rowData.append(numberFormat.format(cell.getNumericCellValue()));
hasData = true;
}
break;
}
case XSSFCell.CELL_TYPE_STRING:
{
String stringVal = cell.getStringCellValue().trim().replaceAll("\n", "");
if (stringVal.trim().equalsIgnoreCase("Total MoU/active customer"))
{
logger.warn("Last - KPI ::" + stringVal);
this.finalRecord = true;
}
rowData.append(stringVal);
hasData = true;
break;
}
case XSSFCell.CELL_TYPE_BOOLEAN:
{
rowData.append(cell.getBooleanCellValue());
hasData = true;
break;
}
case XSSFCell.CELL_TYPE_ERROR:
{
int eval = cell.getErrorCellValue();
if (eval == DIVIDE_BY_ZERO)
rowData.append("0");
hasData = true;
break;
}
case XSSFCell.CELL_TYPE_BLANK:
{
rowData.append("");
hasData = true;
break;
}
}
}
catch (java.lang.IllegalArgumentException e)
{
logger.error(" Formula [ " + (cell.getRowIndex() + 1) + "," + (cell.getColumnIndex() + 1) + " ] "
+ e.getMessage());
rowData.append("CellError");
this.STATUS = FAILURE;
hasData = true;
break;
}
catch (java.lang.IllegalStateException e)
{
logger.error(" Formula [ " + (cell.getRowIndex() + 1) + "," + (cell.getColumnIndex() + 1) + " ] "
+ e.getMessage());
rowData.append("CellError");
this.STATUS = FAILURE;
hasData = true;
break;
}
catch (java.lang.RuntimeException e)
{
this.STATUS = FAILURE;
logger.error(" Formula [ " + (cell.getRowIndex() + 1) + "," + (cell.getColumnIndex() + 1) + " ] "
+ e.getMessage());
rowData.append("MissingFileError");
hasData = true;
break;
}
break;
}
case XSSFCell.CELL_TYPE_BLANK:
{
rowData.append("");
hasData = true;
break;
}
case XSSFCell.CELL_TYPE_NUMERIC:
{
if (DateUtil.isCellDateFormatted(cell))
{
rowData.append(dateFormat.format(cell.getDateCellValue()));
hasData = true;
}
else
{
rowData.append(numberFormat.format(cell.getNumericCellValue()));
hasData = true;
}
break;
}
// Formula evaluation ends here
case XSSFCell.CELL_TYPE_STRING:
{
String stringVal = cell.getStringCellValue().trim().replaceAll("\n", "");
if (stringVal.trim().equalsIgnoreCase("Total MoU/active customer"))
{
logger.warn("Last - KPI ::" + stringVal);
this.finalRecord = true;
;
}
rowData.append(stringVal);
hasData = true;
break;
}
case XSSFCell.CELL_TYPE_ERROR:
{
int eval = cell.getErrorCellValue();
if (eval == DIVIDE_BY_ZERO)
rowData.append("0");
hasData = true;
break;
}
case XSSFCell.CELL_TYPE_BOOLEAN:
{
rowData.append(cell.getBooleanCellValue());
hasData = true;
break;
}
}
rowData.append(FIELD_SEPARATOR);
return hasData;
}
当我运行程序时。在日期列中,我有一系列的日期。最后一个没有公式的日期是2009年12月31日,其单元格参考oj在excel表中的oj+1我有2010年1月1日,但在excel表中我有2009年4月29日,我已在该单元格上打印了公式,并发现poi 3.6在此单元格上有错误的单元格参考。而不是oj+1,它给出了NE+1
请帮助我解决问题由于您的示例不完整,我无法重现您的结果。以下是产生预期结果的示例:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.hssf.usermodel.HSSFSheet;
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.DateUtil;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
public class POIExcelReader {
public static void main(String[] args) throws IOException {
InputStream myxls = new FileInputStream("test.xls");
HSSFWorkbook book = new HSSFWorkbook(myxls);
FormulaEvaluator eval =
book.getCreationHelper().createFormulaEvaluator();
HSSFSheet sheet = book.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
printCell(cell, eval);
System.out.print("; ");
}
System.out.println();
}
myxls.close();
}
private static void printCell(Cell cell, FormulaEvaluator eval) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
System.out.print("EMPTY");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(cell.getDateCellValue());
} else {
System.out.print(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
System.out.print(cell.getCellFormula());
CellValue cellValue = eval.evaluate(cell);
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
double v = cellValue.getNumberValue();
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(" = "
+ DateUtil.getJavaDate(v, true));
} else {
System.out.print(" = " + v);
}
break;
}
break;
default:
System.out.print("DEFAULT");
}
}
}
美国东部时间2010年1月10日星期日00:00:00;1+1 = 2.0; 123.1; 第1条;是的;
A1+1=美国东部时间2010年1月11日星期一00:00:00;2+2 = 4.0; 123.2; 第2条;虚假的;
A2+1=美国东部时间2010年1月12日星期二00:00:00;3+3 = 6.0; 123.3; 第3条;是的;
附录:使用Apache POI 3.8b3验证的结果。由于您的示例不完整,我无法重现您的结果。以下是产生预期结果的示例:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.hssf.usermodel.HSSFSheet;
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.DateUtil;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
public class POIExcelReader {
public static void main(String[] args) throws IOException {
InputStream myxls = new FileInputStream("test.xls");
HSSFWorkbook book = new HSSFWorkbook(myxls);
FormulaEvaluator eval =
book.getCreationHelper().createFormulaEvaluator();
HSSFSheet sheet = book.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
printCell(cell, eval);
System.out.print("; ");
}
System.out.println();
}
myxls.close();
}
private static void printCell(Cell cell, FormulaEvaluator eval) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
System.out.print("EMPTY");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(cell.getDateCellValue());
} else {
System.out.print(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
System.out.print(cell.getCellFormula());
CellValue cellValue = eval.evaluate(cell);
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
double v = cellValue.getNumberValue();
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(" = "
+ DateUtil.getJavaDate(v, true));
} else {
System.out.print(" = " + v);
}
break;
}
break;
default:
System.out.print("DEFAULT");
}
}
}
美国东部时间2010年1月10日星期日00:00:00;1+1 = 2.0; 123.1; 第1条;是的;
A1+1=美国东部时间2010年1月11日星期一00:00:00;2+2 = 4.0; 123.2; 第2条;虚假的;
A2+1=美国东部时间2010年1月12日星期二00:00:00;3+3 = 6.0; 123.3; 第3条;是的;
附录:使用Apache POI 3.8b3验证结果。我遇到了一个类似的问题,我正在读取的工作簿从硬编码值切换到相互依赖的评估日期值,如E7+7和下一个单元格F7+7。它会突然上升5年 我通过在每个单元格上使用evalInCell修复了它,然后读取如下值:
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA)
{
cell = eval.evaluateInCell(cell);
}
希望这有帮助 我遇到了一个类似的问题,我正在阅读的工作簿从硬编码值切换到相互依赖的评估日期值,如E7+7和下一个单元格F7+7。它会突然上升5年 我通过在每个单元格上使用evalInCell修复了它,然后读取如下值:
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA)
{
cell = eval.evaluateInCell(cell);
}
希望这有帮助 是的,它在大多数情况下产生正确的结果,但当我编写相同的代码并将其用于XSSFWorkBook时,我有时得到错误的结果,但在大多数情况下得到正确的结果,我无法理解这个问题。我在使用XSSFWorkBook时没有发现异常,如本文所述,间歇性故障可能很难在sscce中确定。您可能需要考虑同步问题的可能性。如何检测同步问题的可能性。我这里没有线索。我不知道为什么会这样,因为我的代码和上面提到的代码非常匹配。所以它可能是POI bugyes,它在大多数情况下产生正确的结果,但当我编写相同的代码并将其用于XSSFWorkBook时,我有时得到错误的结果,但在大多数情况下得到正确的结果,我无法理解这个问题。我在使用XSSFWorkBook时没有看到异常,如本文所述,间歇性故障可能难以在sscce中确定。您可能需要考虑同步问题的可能性。如何检测同步问题的可能性。我这里没有线索。我不知道为什么会这样,因为我的代码和上面提到的代码非常匹配。所以它可能是POI错误