Java读取Excel日期内容

发布于:2025-07-15 ⋅ 阅读:(12) ⋅ 点赞:(0)
private static Map<String, Object> parseRow(Row row, List<String> headers) {
        Map<String, Object> rowData = new LinkedHashMap<>();
        DataFormatter formatter = new DataFormatter();

        for (int i = 0; i < headers.size(); i++) {
            String header = headers.get(i);
            Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);

            // 根据单元格类型处理数据
            switch (cell.getCellType()) {
                case STRING:
                    rowData.put(header, cell.getStringCellValue().trim());
                    break;
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        // 日期类型处理
                        rowData.put(header, cell.getDateCellValue().toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDateTime());
                    } else {
                        // 数值类型处理
                        double value = cell.getNumericCellValue();
                        if (value == (int) value) {
                            rowData.put(header, (int) value);
                        } else {
                            rowData.put(header, value);
                        }
                    }
                    break;
                case BOOLEAN:
                    rowData.put(header, cell.getBooleanCellValue());
                    break;
                case FORMULA:
                    // 公式单元格处理
                    rowData.put(header, evaluateFormulaCell(cell));
                    break;
                default:
                    rowData.put(header, formatter.formatCellValue(cell));
            }
        }
        return rowData;
    }
/**
     * 读取excel文件数据列表
     * @param file excel文件
     * @return 返回列表数据 List<List<String>>
     */
    public List<List<String>> createLists(MultipartFile file) throws Exception {
        if (file == null){
            log.info("文件对象为空!");
            // 返回空集合
            return new ArrayList<>();
        }
        // 存储文件(本地存储),返回文件的绝对路径名称
        String filePathName = fileSaveUtils.uploadLocalhost(file);

        // 解析文件
        // 创建一个文件输入流,用于读取指定路径的Excel文件
        FileInputStream fileIn = new FileInputStream(filePathName);

        // 获取后缀名(不带.),如:xlsx
        // 方法1
        // 将文件的绝对路径名称按.进行分割分组
        // String[] str = filePathName.split("\\.");
        // 获取后缀名,最后分组的内容便是后缀名,如:xlsx
        // String extName = str[str.length - 1];
        // 方法2
        // 利用字符串函数 substring 获取后缀名(不带.),如:xlsx
        String extName = filePathName.substring(filePathName.lastIndexOf(".") + 1);

        // 获取后缀名(带.),利用字符串函数 substring 获取后缀名(带.),如:.xlsx
        // String extName = filePathName.substring(filePathName.lastIndexOf("."));

        // 工作簿
        Workbook workbook;

        // 2003版的excel
        if (extName.equals("xls")) {
            // 使用文件输入流创建一个HSSFWorkbook对象,该对象代表整个Excel工作簿
            workbook = new HSSFWorkbook(fileIn);
        }
        // 2007版的excel
        else if (extName.equals("xlsx")){
            // 使用文件输入流创建一个XSSFWorkbook对象,该对象代表整个Excel工作簿
            workbook = new XSSFWorkbook(fileIn);
        }
        // 其他格式的文件
        else {
            // 抛出异常,退出方法
            throw new Exception("不是有效的excel文件,请检查!");
        }

        // 从工作簿中获取第一个工作表,索引为0
        Sheet sheet = workbook.getSheetAt(0);

        // 获取数据行数,获取工作表中最后一行的编号,再加1,就是数据行数
        int dataRowCount = sheet.getLastRowNum();
        if (dataRowCount < 0) {
            log.info("文件内容为空!");
            // 返回空集合
            return new ArrayList<>();
        }
        dataRowCount = dataRowCount + 1;

        // 获取数据列数
        // 工作表中的首行(标题行)
        Row titleRow = sheet.getRow(0);
        /*
        // 单元格的类型是数字
        if (row.getCell(4).getCellType() == CellType.NUMERIC) {
            // 这样处理会遇到单元格内容是整数的话,最终结果会补上.0,如:单元格内容为 1,最终结果为 1.0
            sampleItemResult.setResult(String.valueOf(row.getCell(4).getNumericCellValue()));
        }
        else {
            sampleItemResult.setResult(row.getCell(4).getStringCellValue());
        }
        */
        // 先对单元格进行格式化,再取值,这样最终结果就不会有偏差,a是a,1是1,2.1是2.1,检出是检出,无内容就是无内容
        DataFormatter formatter = new DataFormatter();
        // 单元格的内容
        String cellVal;
        // 获取单元格的内容,工作表中的首行(标题行),从左到右遍历,遇到单元格没有内容就停止,该单元格的最左列就是最大列数
        int col = 0;
        cellVal = formatter.formatCellValue(titleRow.getCell(col));
        while (!cellVal.isEmpty()) {
            col += 1;
            cellVal = formatter.formatCellValue(titleRow.getCell(col));
        }
        // 数据列数
        int dataColCount = col;

        // 数据列表,将excel文件中的数据列表转换成数据列表
        List<List<String>> dataLists = new ArrayList<>();
        // 获取数据,遍历工作表中的所有行
        for(int i = 0; i < dataRowCount; i++) {
            // 获取指定编号的行
            Row row = sheet.getRow(i);
            List<String> dataList = new ArrayList<>();

            // 如果行不为空,增加信息
            if(row != null) {
                for(int j = 0; j < dataColCount; j++) {
                    Cell cell = row.getCell(j);
                    // 处理日期类型,统一格式化为 yyyy-MM-dd
                    if (cell != null && cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
                        LocalDateTime dateTimeValue = cell.getLocalDateTimeCellValue();
                        cellVal = dateTimeValue.format(DATE_FORMATTER);
                    } else {
                        cellVal = formatter.formatCellValue(row.getCell(j));
                    }
                    dataList.add(cellVal);
                }
            }

            dataLists.add(dataList);
        }

        // 关闭文件输入流,释放资源
        fileIn.close();
        // 关闭workbook对象,释放资源
        workbook.close();

        // 返回列表数据
        return dataLists;
    }

 

在Java中读取Excel表中的日期内容,通常使用Apache POI库处理。Excel将日期存储为数值(从1900/1/1或1904/1/1开始的天数),需要特殊处理。以下是详细步骤:

1. 添加Maven依赖

xml

<dependencies>
    <!-- Apache POI核心库 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    <!-- 处理xlsx格式 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
</dependencies>

2. 读取日期内容的代码示例

java

import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
import java.util.Date;

public class ExcelDateReader {
    public static void main(String[] args) {
        String filePath = "your_excel_file.xlsx"; // 文件路径

        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = WorkbookFactory.create(fis)) {

            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表

            for (Row row : sheet) {
                for (Cell cell : row) {
                    // 处理日期单元格
                    if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
                        // 方法1:直接获取Date对象
                        Date dateValue = cell.getDateCellValue();
                        System.out.println("日期值: " + dateValue);

                        // 方法2:转换为LocalDateTime(Java 8+)
                        // LocalDateTime localDateTime = dateValue.toInstant()
                        //     .atZone(ZoneId.systemDefault())
                        //     .toLocalDateTime();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键说明:

  1. 日期判断逻辑

    java

    if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell))
    • DateUtil.isCellDateFormatted() 是关键方法,用于识别日期格式的单元格

  2. 获取日期值

    • cell.getDateCellValue() 直接返回java.util.Date对象

    • 推荐Java 8+用户转换为LocalDateTime处理(示例中已注释)

  3. 处理旧版Excel(.xls)

    • 代码兼容.xls.xlsx格式

    • 旧版Excel使用HSSFWorkbook,新版用XSSFWorkbook,但WorkbookFactory自动处理

常见问题处理:

  • 数值误判为日期:检查Excel单元格的实际格式设置

  • 时区问题getDateCellValue()使用系统默认时区,必要时手动调整

  • 自定义日期格式:若日期存储为字符串,需用cell.getStringCellValue()配合SimpleDateFormat解析

日期字符串处理示例:

java

if (cell.getCellType() == CellType.STRING) {
    String dateString = cell.getStringCellValue();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date = sdf.parse(dateString); // 按格式解析
}

提示:使用Java 8的java.time包(如LocalDate)可更安全地处理日期,推荐替代java.util.Date

通过以上方法,可准确读取Excel中的日期内容。实际应用中请添加异常处理逻辑。


网站公告

今日签到

点亮在社区的每一天
去签到