【问题标题】:Read excel (xlsx) file in java using Apoche POI (getting weird numbers)使用Apache POI在java中读取excel(xlsx)文件(得到奇怪的数字)
【发布时间】:2018-05-22 17:56:45
【问题描述】:

我必须为一个学校项目开一个测试日期。此 testdate 是一个包含数字、字母、日期和时间的 excel(xlsx) 文件。但使用下面的代码读取 excel 文件,但我得到奇怪的数字,如 42538.01.153481443E9。日期之后。

public class Page4_Controller implements Initializable {

    @FXML
    private Button button1;

    public void Button1Action(ActionEvent event) throws IOException {
        //Initialize excel file
        FileChooser fc = new FileChooser();
        fc.getExtensionFilters().addAll(
                new ExtensionFilter("Excel Files", "*.xlsx"));
        File selectedFile = fc.showOpenDialog(null);

        // Read file
        readXLSXFile(selectedFile.getAbsolutePath());
    }

    public static void readXLSXFile(String excelFilePath) throws IOException {
        FileInputStream fys = new FileInputStream(new File(excelFilePath));

        //Create workbook instance that refers to .xlsx file
        XSSFWorkbook wb = new XSSFWorkbook(fys);

        //Create a sheet object to retrive the sheet
        XSSFSheet sheet = wb.getSheetAt(0);

        //That is for evalueate the cell type
        FormulaEvaluator forlulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
        DataFormatter df = new DataFormatter();

        //Default data for database (comes later)
        //String airport = sheet.getRow(1).getCell(1).getStringCellValue();
        //Date date = sheet.getRow(2).getCell(1).getDateCellValue();

        for (Row row : sheet) {
            for (Cell cell : row) {
                switch (forlulaEvaluator.evaluateInCell(cell).getCellType()) {
                    //If cell is a numeric format
                    case Cell.CELL_TYPE_NUMERIC:
                        System.out.print(cell.getNumericCellValue() + "\t");
                        System.out.print(df.formatCellValue(cell) + "\t");
                        break;
                    //If cell is a string format
                    case Cell.CELL_TYPE_STRING:
                        System.out.print(cell.getRichStringCellValue() + "\t");
                        break;
                }

            }
            System.out.println();
        }
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
    }

}

【问题讨论】:

  • 42538.0 可能是一个日期 (2016-06-17 00:00)。您需要检查单元格类型是否为 DATE,如果是则进行相应处理。
  • 日期是这样写的:Date Found: 17-Jun-2016,cell type是date。

标签: java excel date apache-poi xlsx


【解决方案1】:

日期在 Excel 内部存储为双精度值,DataFormatter.formatCellValue(Cell cell) 无论单元格类型如何,都将单元格的格式化值作为字符串返回。因此,当您调用 df.formatCellValue(cell) 时,您将作为字符串返回单元格的双精度值。

要将单元格值打印为日期,代码如下:

switch (cell.getCellType()) {
    // ...
    case CellType.NUMERIC:
        // Check if a cell contains a date. Since dates are stored internally in Excel as double values we infer it is a date if it is formatted as such.
        if (DateUtil.isCellDateFormatted(cell)) {
            // Get the value of the cell as a date. Returns a java.util.Date.
            System.out.println(cell.getDateCellValue());
        } else {
            System.out.println(cell.getNumericCellValue());
        }
    // ...
}

来源:

编辑

仅包含时间的 Excel 单元格的日期部分固定为 1899 年 12 月 31 日。您可以使用此信息来检查单元格是时间还是日期:提取年份,如果是 1899 则为时间单元格。

SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");

switch (cell.getCellType()) {

  case CellType.NUMERIC:
    if (DateUtil.isCellDateFormatted(cell)) {
        Date dateCellValue = cell.getDateCellValue();
        String year = yearFormat.format(dateCellValue);
        if (year.equals("1899")) 
          System.out.println(timeFormat.format(dateCellValue));
        else
          System.out.println(dateFormat.format(dateCellValue));
    } else {
        System.out.println(cell.getNumericCellValue());
    }

}

【讨论】:

  • 我用你的代码得到这个:日期:2016 年 9 月 10 日星期六 00:00:00 CEST,我想要得到的是:日期:2016 年 9 月 10 日,但我得到了什么这是:日期:42623.0 10-sep-2016,上面有我的代码。
  • 那么你得到了正确的日期,你只需要根据需要格式化它。您可以使用 SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); System.out.println(sdf.format(cell.getDateCellValue()));
  • 谢谢它像我想要的那样读取日期,但现在它也像日期一样读取时间,例如 19:25。所以它必须是 19:25,但它给了我 1899 年 12 月 31 日。
  • @ÖmerUyar 编辑回答这个问题。
【解决方案2】:

Excel 中的日期表示为“序列号”,其中小数点前面的部分是自 1-1-1900 以来的天数,小数点后的部分是当天的小数部分,所以中午是0.5。因此,如果您自己获取数字,则必须手动进行转换。

POI 可以为您进行转换。示例见How to read Excel cell having Date with Apache POI?

【讨论】:

  • 我的英语不太好,所以我是编程新手,你能在我的代码中更改它并发布它。将不胜感激:)
  • 不。我发布的链接有一个很好的例子来说明如何做到这一点。编辑:代码不在这里格式化。请参阅链接帖子中接受的答案。
  • 您发布的链接与我的代码无关,它适用于特定行,但这不是我想要的.....
  • 它完全满足您的需求。它需要一个您已经拥有的 Cell 对象。查看接受的答案。或查看@Luke 的回答。
【解决方案3】:

这是我必须用java读取的excel文件

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 2015-06-30
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    相关资源
    最近更新 更多