如何使用Apache POI读取具有Date的Excel单元格?


73

我正在使用Apache POI 3.6,我想读取一个具有这样日期的Excel文件8/23/1991

 switch (cell.getCellType()) {

   ...
   ...

   case HSSFCell.CELL_TYPE_NUMERIC:
     value = "NUMERIC value=" + cell.getNumericCellValue();
     break;

   ...

 }

但是它采用数值类型并返回像这样的值33473.0

我尝试使用数字单元格类型,但是没有运气。

dbltemp=row.getCell(c, Row.CREATE_NULL_AS_BLANK).getNumericCellValue();

if (c == 6 || c == 9) {
    strTemp= new String(dbltemp.toString().trim());

    long tempDate = Long.parseLong(strTemp);
    Date date = new Date(tempDate);

    strVal = date.toString();
}

我该如何解决我的问题?

Answers:


114

注意:不建议使用HSSFDateUtil

如果您知道哪个单元格(即列位置)中的每一行都为0,则可以row.getCell(0).getDateCellValue()直接输入日期 。
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFCell.html#getDateCellValue()

更新:这是一个示例-您可以在上面的开关案例代码中应用此示例。我正在检查并打印数字以及日期值。在这种情况下,工作表的第一列有日期,因此我使用row.getCell(0)。

您可以if (HSSFDateUtil.isCellDateFormatted ..在开关盒中直接使用代码块。

if (row.getCell(0).getCellType() == HSSFCell.CELL_TYPE_NUMERIC)
    System.out.println ("Row No.: " + row.getRowNum ()+ " " +
        row.getCell(0).getNumericCellValue());

    if (HSSFDateUtil.isCellDateFormatted(row.getCell(0))) {
        System.out.println ("Row No.: " + row.getRowNum ()+ " " + 
            row.getCell(0).getDateCellValue());
    }
}

输出是

Row No.: 0 39281.0
Row No.: 0 Wed Jul 18 00:00:00 IST 2007
Row No.: 1 39491.0
Row No.: 1 Wed Feb 13 00:00:00 IST 2008
Row No.: 2 39311.0
Row No.: 2 Fri Aug 17 00:00:00 IST 2007

我无法获取任何值...如果您可以指定代码段,那将非常好...
Venkat 2010年

14
调用DateUtil.isCellDateFormatted()将是从HSSF和XSSF中释放代码的第一步。通过使用全局父代而不是依赖XLS / XLSX的HSSF / XSSF子代,可以使代码更加通用。
Aram Paronikyan 2014年

请调整或删除第二个链接。它返回404错误。
丹尼尔·T·索布罗萨

1
HSSFDateUtil在版本4.1.2中已弃用
Aldo Canepa

1
取而代之的是HSSFDateUtil,只需使用DateUtil(的父类HSSFDateUtil
Remigius Stalder

19

是的,我了解您的问题。如果难以识别,则单元格具有数值或数据值。

如果希望数据以Excel中显示的格式显示,则只需使用DataFormatter类格式化单元格即可。

DataFormatter dataFormatter = new DataFormatter();
String cellStringValue = dataFormatter.formatCellValue(row.getCell(0));
System.out.println ("Is shows data as show in Excel file" + cellStringValue);  // Here it automcatically format data based on that cell format.
// No need for extra efforts 

如何将其格式化为ISO格式?(YYYY-MM-DD)
golimar

1
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;


Row row = sheet.getRow(0);
Cell cell = row.getCell(0);
if(cell.getCellTypeEnum() == CellType.NUMERIC||cell.getCellTypeEnum() == CellType.FORMULA)
   {
    

 String cellValue=String.valueOf(cell.getNumericCellValue());
     if(HSSFDateUtil.isCellDateFormatted(cell))
      {
          DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
          Date date = cell.getDateCellValue();
          cellValue = df.format(date);
       }
          System.out.println(cellValue);
    }

请为您的答案添加更多上下文。对于正在阅读您答案的每个人来说,仅仅编写代码作为答案可能并不十分清楚。
乌兹兰

它使用getDateCellValue作为此处的其他答案,但也使用SimpleDateFormat来格式化大多数用户想要的Date值
golimar

0

您可以使用CellDateFormatter以与Excel单元格相同的格式获取日期。请参阅以下代码:

CellValue cv = formulaEv.evaluate(cell);
double dv = cv.getNumberValue();
if (HSSFDateUtil.isCellDateFormatted(cell)) {
    Date date = HSSFDateUtil.getJavaDate(dv);

    String df = cell.getCellStyle().getDataFormatString();

    strValue = new CellDateFormatter(df).format(date); 
}

0

您需要DateUtils:有关详细信息,请参阅本文

或者,更好的是,使用Andy Khan的JExcel代替POI。


我在POI几乎实现很多东西,我很抱歉,我不能去任何只为这个..一定有什么..然而,谢谢duffymo
Venkat

1
如果您无法切换到JExcel,DateUtils将为您解决
duffymo 2010年

该链接已死,尽管WayBack仍然可以访问。即使这样,我也没有提到DateUtils。
beldaz '18

我想,HSSFDateUtil是DateUtil的意思。
Evgeny Semionov '18

0

如果您知道单元格号,那么我建议使用getDateCellValue()方法。这是对我有用的示例-java.util.Date date = row.getCell()。getDateCellValue(); System.out.println(date);


0

试试这个代码。

XSSFWorkbook workbook = new XSSFWorkbook(new File(result));
    XSSFSheet sheet = workbook.getSheetAt(0);

    // Iterate through each rows one by one
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        // For each row, iterate through all the columns
        Iterator<Cell> cellIterator = row.cellIterator();

        while (cellIterator.hasNext()) {
            Cell cell = cellIterator.next();
            switch (cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC:
                if (cell.getNumericCellValue() != 0) {
                    //Get date
                    Date date = row.getCell(0).getDateCellValue();



                    //Get datetime
                    cell.getDateCellValue()


                    System.out.println(date.getTime());
                }
                break;
            }
        }
    }

希望是帮助。


-1

到目前为止,对于读取日期单元格,该方法已被证明是可靠的:

private LocalDate readCellAsDate(final Row row, final int pos) {
    if (pos == -1) {
        return null;
    }
    final Cell cell = row.getCell(pos - 1);
    if (cell != null) {
        cell.setCellType(CellType.NUMERIC);
    } else {
        return null;
    }
    if (DateUtil.isCellDateFormatted(cell)) {
        try {
            return cell.getDateCellValue().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        } catch (final NullPointerException e) {
            logger.error(e.getMessage());
            return null;
        }
    }
    return null;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.