6

我正在尝试使用 Java 中的 POI api 创建一个 Excel 工作表。在那个 Excel 工作表中,我想要一个单独包含 TIME 的单元格。通过设置它,我们可以像在数字列中一样将单元格包含在该特定列的总和中。为此,我们需要将单元格格式化为时间 >> 13:30:55。(内部格式为 'h:mm:ss;@' )。我们需要从单元格中删除日期部分。

当我使用 POI 读取单元格值时,它返回为“Sun Dec 31 01:00:00 IST 1899”(当我将值设置为 1:00 时),单元格格式索引为 166,单元格格式字符串是'h:mm:ss;@'。

在将从 excel 读取的格式和样式设置为 1800-December-31 和时间值后,新的 excel 将单元格显示为 '######' (错误)并且设置了单元格值作为'-1'。下面是我使用的代码。我错过了什么吗?是否可以根据需要设置值。

    InputStream is = new BufferedInputStream(new FileInputStream("<FileName>"));
    XSSFWorkbook wb = new XSSFWorkbook(is);
    is.close();

    XSSFSheet sheet = wb.getSheetAt(0);
    XSSFRow row = sheet.getRow(2);

    XSSFCell cell = row.getCell(18);
    System.out.println("ExcelFileReader main cell.getDateCellValue() : '" + cell.getDateCellValue() + "'");
    System.out.println("ExcelFileReader main cell.getCellStyle().getDataFormat() : '" + cell.getCellStyle().getDataFormat() + "'");
    System.out.println("ExcelFileReader main cell.getCellStyle().getDataFormat() : '" + cell.getCellStyle().getDataFormatString() + "'");

    XSSFRow row1 = sheet.createRow(21);
    XSSFCell cell1 = row1.createCell(2);

    cell1.setCellStyle(cell.getCellStyle());
    cell1.setCellValue(cell.getDateCellValue());

    Calendar dummy = Calendar.getInstance();
    dummy.setLenient(false);
    dummy.set(Calendar.YEAR, 1899);
    dummy.set(Calendar.MONTH, Calendar.DECEMBER);
    dummy.set(Calendar.DATE, 31);

    dummy.set(Calendar.HOUR, 00);
    dummy.set(Calendar.MINUTE, 00);
    dummy.set(Calendar.SECOND, 00);
    dummy.set(Calendar.MILLISECOND, 00);

    Calendar cc = Calendar.getInstance();
    XSSFRow row2 = sheet.createRow(25);
    XSSFCell cell2 = row2.createCell(2);

    dummy.set(Calendar.HOUR, cc.get(Calendar.HOUR));
    dummy.set(Calendar.MINUTE, cc.get(Calendar.MINUTE));
    dummy.set(Calendar.SECOND, cc.get(Calendar.SECOND));
    dummy.set(Calendar.MILLISECOND, cc.get(Calendar.MILLISECOND));

    System.out.println("ExcelFileReader main dummy : '" + dummy.getTime() + "'");
    cell2.setCellValue(dummy.getTime());

    CellStyle style = wb.createCellStyle();
    DataFormat df = wb.createDataFormat();
    style.setDataFormat(df.getFormat("[h]:mm:ss;@"));
    cell2.setCellStyle(style);

    FileOutputStream fos = new FileOutputStream(new File("<New Excel file>"));
    wb.write(fos);
    fos.close();
    System.out.println("ExcelFileReader DONE");

以下是程序的输出。

    ExcelFileReader main cell.getDateCellValue() : 'Sun Dec 31 00:15:00 IST 1899'
    ExcelFileReader main cell.getCellStyle().getDataFormat() : '166'
    ExcelFileReader main cell.getCellStyle().getDataFormat() : 'h:mm:ss;@'
    ExcelFileReader main dummy : 'Sun Dec 31 11:32:24 IST 1899'
    ExcelFileReader DONE
4

3 回答 3

5

我使用以下代码在 Excel 中使用 POI 生成时间单元格。而且我可以在

        XSSFRow row2 = sheet.createRow(25);
        XSSFCell cell1 = row2.createCell(4);
        XSSFCell cell2 = row2.createCell(5);

        CellStyle style = wb.createCellStyle();
        DataFormat df = wb.createDataFormat();
        style.setDataFormat(df.getFormat("[h]:mm:ss;@"));

        cell1.setCellFormula("TIME(0,15,00)"); // 00:15:00
        cell1.setCellType(Cell.CELL_TYPE_FORMULA);
        cell1.setCellStyle(style);
        evaluator.evaluateFormulaCell(cell1);

        cell2.setCellFormula("TIME(0,30,00)"); //00:30:00
        cell2.setCellType(Cell.CELL_TYPE_FORMULA);
        evaluator.evaluateFormulaCell(cell2);
        cell2.setCellStyle(style);
于 2012-11-20T03:52:55.743 回答
3

Excel 中的日期和时间通常存储为浮点数,自 1900 年或 1904 年以来的完整天数和小数天数。您可以通过在 Excel 单元格中键入 0.5 并将格式设置为时间来查看这一点 - 它会显示为 12:00:00 , 或设置值 1.5,它将显示为 1900/1904 中的日期作为日期,12:00:00 作为时间,或者 36:00:00 如果允许 >24 小时的时间(这是不同的格式代码)

您要做的是启动 Excel 的副本,输入您想要显示的时间值,然后计算出格式字符串,使其按您的意愿显示。然后,记下该格式代码,并将其作为单元格的数据格式提供给 POI。现在,在 POI 中使用 DateUtil 之类的东西来构建您的 Date 对象,并将其设置为单元格作为值。使用正确的格式字符串,Excel 将只显示时间部分而不是日期

于 2012-11-19T15:30:23.527 回答
2

您可以使用 DateUtil.convertTime(String time) 方法,其中时间类似于“HH:MM”或“HH:MM:SS”。此方法将为您提供一个 double 值,您可以将其设置为单元格中的值 (cell.setCellValue(double value))。

但是 convertTime 方法不适用于 hours > 23。如果您需要这个机会,您可以编写自己的 convertTime 方法,如下所示:

double convertTime(long hours, long minutes, long seconds) {
   double totalSeconds = seconds + (minutes + (hours) * 60) * 60;
   return totalSeconds / (SECONDS_PER_DAY);
}

SECONDS_PER_DAY = 60 * 60 * 24。您可以简单地从 DateUtil 类中获取它。

请记住,您必须正确定义您的单元格格式,以便 Excel 可以在 23 小时以上。

于 2020-08-06T10:55:32.450 回答