EasyExcel解析并分割Excel、Excel分割

在日常写解析Excel业务中,可能会遇到在解析一个Excel表时,表中的数据不能全被一个对象接收,这时候可能需要定义一个大对象去接收数据,但是我们知道,Excel中一行数据就是一个对象,所以这种方式是行不通的。

如下图:圈出来的数据是不能被一个对象接收并解析的
在这里插入图片描述
解决办法:可以将Excel内容进行分割
思路:比如表格中的“指标名称”字符串内容是固定的,我就可以以它为分割行进行划分

项目用到的依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.1.4</version>
</dependency>

Excel 数据监听类:

public class ExcelDataListener<T> extends AnalysisEventListener<T> {

    private List<T> dataList = new ArrayList<>();

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        dataList.add(t);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }

    public List<T> getDataList() {
        return this.dataList;
    }
}

输入流读取Excel数据

public class ExcelParse {

    public static <T> List<T> simpleRead(InputStream inputStream) {
        // sheet文件流会自动关闭
        ExcelDataListenerdataListener = new ExcelDataListener();
        EasyExcel.read(inputStream, dataListener).sheet().doRead();
        return dataListener.getDataList();
    }


	// 如果传入类,会自动映射
	public static <T> List<T> simpleRead(InputStream inputStream, Class<T> clazz) {
        ExcelDataListener<T> dataListener = new ExcelDataListener<>();
        EasyExcel.read(inputStream, clazz, dataListener).sheet().doRead();
        return dataListener.getDataList();
    }
}

分割处理(这里只是演示,建议封装成工具类更好)

@PostMapping("/parseExcel")
public void getExcelContent(@RequestParam("file") MultipartFile file) throws IOException {
    InputStream is = file.getInputStream();
    List<Map<Integer, String>> all = ExcelParse.simpleRead(is);
    Map<Integer, String> map = null;

    // 从哪一行进行分割,因为是要在lambda读取splitHeadNum原子操作
    AtomicInteger splitHeadNum = new AtomicInteger();
    AtomicInteger splitTailNum = new AtomicInteger();

    // 将Excel进行分割(企业信息与内容进行分割)
    for (int i = 0; i < all.size(); i++) {
        int temp = i;
        map = all.get(i);
        map.forEach((k, v) -> {
            if (v != null) {
                if ("指标名称".equals(v)) {
                    // 获取头部要分割的行数
                    splitHeadNum.set(temp);
                }
                if ("负责人".contains(v)) {
                    // 获取尾部要分割的行数
                    splitTailNum.set(temp);
                }
            }
        });
    }

    // Excel头信息解析
    for (int i = 0; i < splitHeadNum.get(); i++) {
        map = all.get(i);
        // 删除null元素(导入的时候表格如有null列,只能这样删除null元素了。。。有好方法再TODO)
        map.entrySet().removeIf(entry -> entry.getValue() == null);
        System.out.println(map);
    }
    System.out.println("=================================");
    // 解析Excel数据
    for (int i = splitHeadNum.get(); i < splitTailNum.get(); i++) {
        map = all.get(i);
        // 删除null元素(导入的时候表格如有null列,只能这样删除null元素了。。。有好方法再TODO)
        map.entrySet().removeIf(entry -> entry.getValue() == null);
        System.out.println(map);
    }
}

成功分割~
在这里插入图片描述

<think>好的,我现在需要帮助用户解决如何使用EasyExcel读取Excel文件中的日期格式的问题。首先,我需要回顾用户提供的引用内容,确保信息准确。根据用户提供的引用[1]和[2],EasyExcel处理Excel文件的方法和示例代码可能已经涉及到了数据读取和导出,但具体到日期格式可能需要更详细的配置。 用户的问题是关于读取日期格式的方法及配置示例。日期在Excel中通常以数字形式存储,例如日期值可能被保存为自1900年1月1日以来的天数,时间则是小数部分。因此,在读取时需要进行正确的转换,否则可能会得到数值而不是日期对象。 首先,我需要确定EasyExcel如何处理日期单元格。根据经验,EasyExcel可能提供了注解或自定义转换器来处理特定格式。例如,使用@DateTimeFormat注解来指定日期格式。或者,可能需要自定义转换器,将读取到的数值转换为Java的Date对象或LocalDateTime等。 接下来,用户需要一个配置示例。我需要确保示例代码正确,包括如何定义模型类,使用注解,以及可能的自定义转换器。同时,需要说明如何处理不同的日期格式,比如"yyyy-MM-dd"或"yyyy/MM/dd HH:mm:ss"等。 另外,考虑到时区问题,是否需要设置时区?可能在某些情况下,日期解析需要考虑时区,因此注解中可能需要设置timezone属性。 还需要注意EasyExcel的版本,不同版本可能有不同的配置方式。但用户提供的引用中没有提到具体版本,所以需要给出通用的方法,适用于大多数情况。 可能的步骤是: 1. 在模型类的字段上使用@DateTimeFormat注解,指定日期格式。 2. 使用自定义转换器处理特殊的日期格式或异常情况。 3. 在读取时注册自定义转换器或配置读取参数。 需要验证这些步骤是否正确,确保示例代码符合这些步骤。例如,模型类中的注解是否正确,读取监听器是否处理了日期字段,以及是否需要自定义转换器。 此外,用户可能遇到的问题是日期读取为数字,或者格式不匹配导致解析失败。因此,示例中需要涵盖这些情况的处理方式,比如使用自定义转换器进行转换,或者在注解中指定正确的格式。 最后,总结这些方法,确保回答结构清晰,步骤明确,代码示例正确,能够帮助用户正确配置EasyExcel来读取日期格式。</think>使用EasyExcel读取Excel日期格式时,需要通过模型类注解或自定义转换器实现日期解析。以下是具体方法及配置示例: ### 一、基础配置方法 1. **实体类字段添加日期格式注解** ```java public class DemoData { @DateTimeFormat("yyyy-MM-dd HH:mm:ss") // 强制匹配该格式 private Date createTime; @DateTimeFormat("yyyy/MM/dd") // 支持斜杠分割格式 private Date updateDate; } ``` 2. **注册全局日期格式(application.properties)** ```properties easyexcel.converter.date-format=yyyy-MM-dd ``` ### 二、自定义日期转换器(应对复杂格式) ```java public class CustomDateConverter implements Converter<Date> { @Override public Date convertToJavaData(ReadConverterContext<?> context) { String stringValue = context.getReadCellData().getStringValue(); try { return new SimpleDateFormat("dd/MM/yyyy").parse(stringValue); } catch (ParseException e) { log.error("日期格式解析异常", e); return null; } } } // 注册转换器 EasyExcel.read(file, DemoData.class, new PageReadListener<...>()) .registerConverter(new CustomDateConverter()) .sheet().doRead(); ``` ### 三、读取监听器处理 ```java public class DemoDataListener extends AnalysisEventListener<DemoData> { @Override public void invoke(DemoData data, AnalysisContext context) { // 自动完成Date类型转换 System.out.println(data.getCreateTime()); } } ``` ### 四、注意事项 1. **时区配置**:若日期显示异常,可在注解添加时区属性 ```java @DateTimeFormat(value = "yyyy-MM-dd", timezone = "GMT+8") ``` 2. **格式优先级**:字段注解 > 全局配置 > Excel原生格式识别[^1] 3. **容错处理**:建议在转换器中添加异常捕获,避免因格式错误中断读取[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值