【问题标题】:poi wrong date formula value calculatedpoi 错误日期公式值计算
【发布时间】:2010-01-16 12:07:59
【问题描述】:

我有以下代码

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;
 }

当我运行程序时。在日期列中,我有一系列日期。没有公式的最后一个日期是 31/12/2009 它的单元格引用 oj 在 excel 表中的 oj+1 我有 1/1/2010 但在 excel 表中我得到了 29/04/2009 我已经在这个单元格上打印了公式并找到出 poi 3.6 对此有错误的单元格引用。而不是 oj+1 它给 NE+1

请帮我解决问题

【问题讨论】:

    标签: java apache-poi


    【解决方案1】:

    由于您的示例不完整,我无法重现您的结果。这是产生预期结果的sscce

    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 EST; 1+1 = 2.0; 123.1;字符串1;真的; A1+1 = 2010 年 1 月 11 日星期一 00:00:00 EST; 2+2 = 4.0; 123.2;字符串2;错误的; A2+1 = 2010 年 1 月 12 日星期二 00:00:00 EST; 3+3 = 6.0; 123.3;字符串3;真的;

    附录:使用 Apache POI 3.8b3 验证的结果。

    【讨论】:

    • 是的,它在大多数情况下都会产生正确的结果,但是当我编写相同的代码并将其用于 XSSFWorkBook 时,我有时会得到错误的结果,但大多数时候得到正确的结果我无法理解那个问题。
    • 我在使用 XSSFWorkBook 时没有发现异常,如此处所述poi.apache.org/spreadsheet/converting.html
    • 间歇性故障可能很难在 sscce 中确定。您可能需要考虑同步问题的可能性。
    • 如何检测同步问题的可能性。我这里没有线索。我不知道为什么会这样,因为我的代码和上面提到的代码非常匹配。所以它可能是 POI 错误
    【解决方案2】:

    我遇到了类似的问题,我正在阅读的工作簿从硬编码值切换到相互依赖的评估日期值,例如 E7+7 和下一个单元格 F7+7 。一下子就涨了5年……

    在读取这样的值之前,我通过在每个单元格上使用 evalInCell 来修复它:

    if (cell.getCellType() == Cell.CELL_TYPE_FORMULA)
    {
         cell = eval.evaluateInCell(cell);
    }
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 2015-10-22
      相关资源
      最近更新 更多