huliguo
2 天以前 5d7b65670282a4fad015e37d567cfa171b162052
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 
package com.ruoyi.common.easyExcel;
 
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.DateUtils;
import com.ruoyi.common.exception.GlobalException;
import org.apache.poi.ss.usermodel.DateUtil;
import org.springframework.format.annotation.DateTimeFormat;
 
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
import java.util.List;
import java.util.Arrays;
 
public class DateConverter implements Converter<Date> {
    private static final List<String> DEFAULT_DATE_FORMATS = Arrays.asList(
            "yyyy/M/d","dd-M-yyyy", "M/d/yyyy", "yyyy-MM-dd","yyyy-MM",
            "yyyy.MM.dd","yyyy.MM","yyyy","yyyy年MM月dd日","yyyy年MM月","yyyy年"
    );
 
    @Override
    public Class<Date> supportJavaTypeKey() {
        return Date.class;
    }
 
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }
 
    /**
     * 这里读的时候会调用
     *
     * @param cellData            excel数据 (NotNull)
     * @param contentProperty     excel属性 (Nullable)
     * @param globalConfiguration 全局配置 (NotNull)
     * @return 读取到内存中的数据
     */
    @Override
    public Date convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        try {
            String stringValue = "";
            // 1. Excel 单元格是数字类型(如 40969),代表日期
            if (cellData.getType() == CellDataTypeEnum.NUMBER) {
                //这里有可能是 2025年,是数字类型,也可能是2025.08也是数字,有可能是2025/08/01(这种excel读取是数字类型)
                //2000以后都是5位数
                if(cellData.getNumberValue().toString().contains(".")
                || cellData.getNumberValue().compareTo(new BigDecimal("2050")) <= 0){
                    stringValue = cellData.getNumberValue().toString();
                }else {
                    double numericDate = cellData.getNumberValue().doubleValue();
                    Date date = DateUtil.getJavaDate(numericDate, false); // HSSF 日期基准是 1900-01-01
//                    System.out.println(cn.hutool.core.date.DateUtil.format(date, "yyyy-MM-dd"));
                    return date;
                }
            }else {
                 stringValue = cellData.getStringValue();
            }
            try {
                Date parsedDate = parseDate(stringValue);
                if (parsedDate != null) {
//                    System.out.println(cn.hutool.core.date.DateUtil.format(parsedDate, "yyyy-MM-dd"));
                    return parsedDate;
                } else {
                    throw new ParseException("日期格式不匹配", 0);
                }
            } catch (Exception e) {
                throw new ParseException("日期格式不匹配", 0);
            }
        } catch (Exception e) {
            throw new GlobalException("日期格式错误,请保证时间格式为:yyyy/m/d, yyyy-MM-dd, dd-M-yyyy, M/d/yyyy");
        }
    }
 
    private Date parseDate(String dateStr) throws ParseException {
        for (String defaultFormat : DEFAULT_DATE_FORMATS) {
            SimpleDateFormat sdf = new SimpleDateFormat(defaultFormat, Locale.getDefault());
            sdf.setTimeZone(TimeZone.getDefault());
            try {
                return sdf.parse(dateStr);
            } catch (ParseException e) {
                // 继续尝试下一个格式
            }
        }
        return null;
    }
 
    public boolean isValidDate(Date date) {
        if (date == null) {
            return false;
        }
 
        // 定义日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        sdf.setLenient(false); // 关闭宽松模式,严格校验日期
 
        // 将 Date 转换成字符串,再转换回 Date,确保格式正确
        String dateStr = sdf.format(date);
        return cn.hutool.core.date.DateUtil.parse(dateStr) == null ? false:true;
    }
 
    /**
     * 写的时候会调用
     *
     * @param value               java value (NotNull)
     * @param contentProperty     excel属性 (Nullable)
     * @param globalConfiguration 全局配置 (NotNull)
     * @return 写出到excel文件的数据
     */
    @Override
    public WriteCellData<Date> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        DateTimeFormat annotation = contentProperty.getField().getAnnotation(DateTimeFormat.class);
        String format = Objects.nonNull(annotation) ? annotation.pattern() : "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
        sdf.setTimeZone(TimeZone.getDefault());
        String result = sdf.format(value);
        return new WriteCellData<>(result);
    }
}