• Easypoi map方式导入数据 ,List<Map<String, String>> 日期项数据为空(null)解决办法


    前言

    在使用easypoi map的方式解析excel文件,若文件中的某列数据格式是日期类型,那么它这个工具是读取不到,因为它的源码读取到某列为日期格式,数据必须为字符串类型,它才会处理

    switch (cell.getCellType()) {
                    case STRING:
                        result = cell.getRichStringCellValue() == null ? ""
                                : cell.getRichStringCellValue().getString();
                        break;
                    case NUMERIC:
                        if (DateUtil.isCellDateFormatted(cell)) {
                            if ("class java.lang.String".equals(classFullName)) {
                                result = formateDate(entity, cell.getDateCellValue());
                            }
                        } else {
                            result = readNumericCell(cell);
                        }
                        break;
                    case BOOLEAN:
                        result = Boolean.toString(cell.getBooleanCellValue());
                        break;
                    case BLANK:
                        break;
                    case ERROR:
                        break;
                    case FORMULA:
                        try {
                            result = readNumericCell(cell);
                        } catch (Exception e1) {
                            try {
                                result = cell.getRichStringCellValue() == null ? ""
                                        : cell.getRichStringCellValue().getString();
                            } catch (Exception e2) {
                                throw new RuntimeException("获取公式类型的单元格失败", e2);
                            }
                        }
                        break;
                    default:
                        break;
                }
    
    • 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

    解决办法

    来个简单粗暴的,既然源码无法满足,那就直接扩展它的源码,在它 case NUMERIC 下加个任意类型都可以进去的判断方法,在项目main java包路径下定义一个跟源码一样的路径,一样的类,若那位大佬有更好的办法,还望留言指导一下呢

    if("class java.lang.Object".equals(classFullName)){
     	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
     	return format.format(cell.getDateCellValue());
    }
    
    • 1
    • 2
    • 3
    • 4

    main路径 java 路径下定义包路径

    cn.afterturn.easypoi.excel.imports
    
    • 1

    处理类:

    /**
     * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com)
     * 

    * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

    * http://www.apache.org/licenses/LICENSE-2.0 *

    * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.afterturn.easypoi.excel.imports; import cn.afterturn.easypoi.excel.entity.params.ExcelImportEntity; import cn.afterturn.easypoi.excel.entity.sax.SaxReadCellEntity; import cn.afterturn.easypoi.exception.excel.ExcelImportException; import cn.afterturn.easypoi.exception.excel.enums.ExcelImportEnum; import cn.afterturn.easypoi.handler.inter.IExcelDataHandler; import cn.afterturn.easypoi.handler.inter.IExcelDictHandler; import cn.afterturn.easypoi.util.PoiPublicUtil; import cn.afterturn.easypoi.util.PoiReflectorUtil; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.math.BigDecimal; import java.sql.Time; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.ZoneId; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Map; /** * Cell 取值服务 * 判断类型处理数据 1.判断Excel中的类型 2.根据replace替换值 3.handler处理数据 4.判断返回类型转化数据返回 * * @author JueYue * 2014年6月26日 下午10:42:28 */ public class CellValueService { private static final Logger LOGGER = LoggerFactory.getLogger(CellValueService.class); private List<String> handlerList = null; /** * 获取单元格内的值 * * @param cell * @param entity * @return */ private Object getCellValue(String classFullName, Cell cell, ExcelImportEntity entity) { if (cell == null) { return ""; } Object result = null; if ("class java.util.Date".equals(classFullName) || "class java.sql.Date".equals(classFullName) || ("class java.sql.Time").equals(classFullName) || ("class java.time.Instant").equals(classFullName) || ("class java.time.LocalDate").equals(classFullName) || ("class java.time.LocalDateTime").equals(classFullName) || ("class java.sql.Timestamp").equals(classFullName)) { //FIX: 单元格yyyyMMdd数字时候使用 cell.getDateCellValue() 解析出的日期错误 if (CellType.NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)) { result = DateUtil.getJavaDate(cell.getNumericCellValue()); } else { String val = ""; try { val = cell.getStringCellValue(); } catch (Exception e) { return null; } result = getDateData(entity, val); if (result == null) { return null; } } if (("class java.time.Instant").equals(classFullName)) { result = ((Date) result).toInstant(); } else if (("class java.time.LocalDate").equals(classFullName)) { result = ((Date) result).toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); } else if (("class java.time.LocalDateTime").equals(classFullName)) { result = ((Date) result).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); } else if (("class java.time.OffsetDateTime").equals(classFullName)) { result = ((Date) result).toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime(); } else if (("class java.time.ZonedDateTime").equals(classFullName)) { result = ((Date) result).toInstant().atZone(ZoneId.systemDefault()); } else if (("class java.sql.Date").equals(classFullName)) { result = new java.sql.Date(((Date) result).getTime()); } else if (("class java.sql.Time").equals(classFullName)) { result = new Time(((Date) result).getTime()); } else if (("class java.sql.Timestamp").equals(classFullName)) { result = new Timestamp(((Date) result).getTime()); } } else { switch (cell.getCellType()) { case STRING: result = cell.getRichStringCellValue() == null ? "" : cell.getRichStringCellValue().getString(); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { if ("class java.lang.String".equals(classFullName)) { result = formateDate(entity, cell.getDateCellValue()); } if("class java.lang.Object".equals(classFullName)){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); return format.format(cell.getDateCellValue()); } } else { result = readNumericCell(cell); } break; case BOOLEAN: result = Boolean.toString(cell.getBooleanCellValue()); break; case BLANK: break; case ERROR: break; case FORMULA: try { result = readNumericCell(cell); } catch (Exception e1) { try { result = cell.getRichStringCellValue() == null ? "" : cell.getRichStringCellValue().getString(); } catch (Exception e2) { throw new RuntimeException("获取公式类型的单元格失败", e2); } } break; default: break; } } return result; } private Object readNumericCell(Cell cell) { Object result = null; double value = cell.getNumericCellValue(); if (((int) value) == value) { result = (int) value; } else { result = value; } return result; } /** * 获取日期类型数据 * * @param entity * @param value * @return * @author JueYue * 2013年11月26日 */ private Date getDateData(ExcelImportEntity entity, String value) { if (StringUtils.isNotEmpty(entity.getFormat()) && StringUtils.isNotEmpty(value)) { SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); try { return format.parse(value); } catch (ParseException e) { try { return DateUtil.getJavaDate(Double.parseDouble(value)); } catch (NumberFormatException ex) { LOGGER.error("时间格式化失败,格式化:{},值:{}", entity.getFormat(), value); throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); } } } return null; } private String formateDate(ExcelImportEntity entity, Date value) { if (StringUtils.isNotEmpty(entity.getFormat()) && value != null) { SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); return format.format(value); } return null; } /** * 获取cell的值 * * @param object * @param cell * @param excelParams * @param titleString * @param dictHandler */ public Object getValue(IExcelDataHandler<?> dataHandler, Object object, Object cell, Map<String, ExcelImportEntity> excelParams, String titleString, IExcelDictHandler dictHandler) throws Exception { ExcelImportEntity entity = excelParams.get(titleString); String classFullName = "class java.lang.Object"; Class clazz = null; if (!(object instanceof Map)) { Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); Type[] ts = setMethod.getGenericParameterTypes(); classFullName = ts[0].toString(); clazz = (Class) ts[0]; } Object result = null; if(cell instanceof Cell){ result = getCellValue(classFullName, (Cell) cell, entity); }else{ result = cell; } if (entity != null) { result = handlerSuffix(entity.getSuffix(), result); result = replaceValue(entity.getReplace(), result); result = replaceValue(entity.getReplace(), result); if (dictHandler != null && StringUtils.isNoneBlank(entity.getDict())) { result = dictHandler.toValue(entity.getDict(), object, entity.getName(), result); } } result = handlerValue(dataHandler, object, result, titleString); return getValueByType(classFullName, result, entity, clazz); } /** * 获取cell值 * * @param dataHandler * @param object * @param cellEntity * @param excelParams * @param titleString * @return */ public Object getValue(IExcelDataHandler<?> dataHandler, Object object, SaxReadCellEntity cellEntity, Map<String, ExcelImportEntity> excelParams, String titleString) { ExcelImportEntity entity = excelParams.get(titleString); Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); Type[] ts = setMethod.getGenericParameterTypes(); String classFullName = ts[0].toString(); Object result = cellEntity.getValue(); result = handlerSuffix(entity.getSuffix(), result); result = replaceValue(entity.getReplace(), result); result = handlerValue(dataHandler, object, result, titleString); return getValueByType(classFullName, result, entity, (Class) ts[0]); } /** * 把后缀删除掉 * * @param result * @param suffix * @return */ private Object handlerSuffix(String suffix, Object result) { if (StringUtils.isNotEmpty(suffix) && result != null && result.toString().endsWith(suffix)) { String temp = result.toString(); return temp.substring(0, temp.length() - suffix.length()); } return result; } /** * 根据返回类型获取返回值 * * @param classFullName * @param result * @param entity * @param clazz * @return */ private Object getValueByType(String classFullName, Object result, ExcelImportEntity entity, Class clazz) { try { //过滤空和空字符串,如果基本类型null会在上层抛出,这里就不处理了 if (result == null || StringUtils.isBlank(result.toString())) { return null; } if ("class java.util.Date".equals(classFullName) && result instanceof String) { return DateUtils.parseDate(result.toString(), entity.getFormat()); } if ("class java.lang.Boolean".equals(classFullName) || "boolean".equals(classFullName)) { return Boolean.valueOf(String.valueOf(result)); } if ("class java.lang.Double".equals(classFullName) || "double".equals(classFullName)) { return Double.valueOf(String.valueOf(result)); } if ("class java.lang.Long".equals(classFullName) || "long".equals(classFullName)) { try { return Long.valueOf(String.valueOf(result)); } catch (Exception e) { //格式错误的时候,就用double,然后获取Int值 return Double.valueOf(String.valueOf(result)).longValue(); } } if ("class java.lang.Float".equals(classFullName) || "float".equals(classFullName)) { return Float.valueOf(String.valueOf(result)); } if ("class java.lang.Integer".equals(classFullName) || "int".equals(classFullName)) { try { return Integer.valueOf(String.valueOf(result)); } catch (Exception e) { //格式错误的时候,就用double,然后获取Int值 return Double.valueOf(String.valueOf(result)).intValue(); } } if ("class java.math.BigDecimal".equals(classFullName)) { return new BigDecimal(String.valueOf(result)); } if ("class java.lang.String".equals(classFullName)) { //针对String 类型,但是Excel获取的数据却不是String,比如Double类型,防止科学计数法 if (result instanceof String) { return result; } // double类型防止科学计数法 if (result instanceof Double) { return PoiPublicUtil.doubleToString((Double) result); } return String.valueOf(result); } if (clazz != null && clazz.isEnum()) { if (StringUtils.isNotEmpty(entity.getEnumImportMethod())) { return PoiReflectorUtil.fromCache(clazz).execEnumStaticMethod(entity.getEnumImportMethod(), result); } else { return Enum.valueOf(clazz, result.toString()); } } return result; } catch (Exception e) { LOGGER.error(e.getMessage(), e); throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); } } /** * 调用处理接口处理值 * * @param dataHandler * @param object * @param result * @param titleString * @return */ @SuppressWarnings({"unchecked", "rawtypes"}) private Object handlerValue(IExcelDataHandler dataHandler, Object object, Object result, String titleString) { if (dataHandler == null || dataHandler.getNeedHandlerFields() == null || dataHandler.getNeedHandlerFields().length == 0) { return result; } if (handlerList == null) { handlerList = Arrays.asList(dataHandler.getNeedHandlerFields()); } if (handlerList.contains(titleString)) { return dataHandler.importHandler(object, titleString, result); } return result; } /** * 替换值 * * @param replace * @param result * @return */ private Object replaceValue(String[] replace, Object result) { if (replace != null && replace.length > 0) { String temp = String.valueOf(result); String[] tempArr; for (int i = 0; i < replace.length; i++) { tempArr = replace[i].split("_"); if (temp.equals(tempArr[0])) { return tempArr[1]; } } } return result; } }

    • 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
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
  • 相关阅读:
    ThreadLocal源码解析 1.运行原理
    Mongodb单机、复制集Replica Sets、分片集群Shard Cluster安装详解
    Arm功耗管理精讲与实战
    多目标水循环优化算法附Matlab代码
    H3C 交换机配置SSH
    IDA动态调试apk
    【虚幻引擎UE】UE4/UE5 环境构建插件推荐及使用介绍
    Docker CMD和ENTRYPOINT的区别
    Java 线程的几种状态
    T-SQL——将字符串转为单列
  • 原文地址:https://blog.csdn.net/QQ_hoverer/article/details/134322464