EasyExcel---监听器

概念

  • 监听器

    • 帮助我们获取到excel中每一行的数据,并循环调用invoke方法去获得每一行的数据
    • 数据异常时定位到具体的行和列
    • 批量导入,控制内存中数据量,达到一定量就导入到数据库(这篇没有用到批量导入)

思路

在开发中我们需要将excel中的数据和数据库中的数据进行比对,如果一样,不进行操作,不一样更新数据库

代码

package cn.testin.Listener;

import cn.testin.api.cfg.bean.AdditionalConfig;
import cn.testin.api.devicecontrol.DeviceAssetsApi;
import cn.testin.common.pojo.GeneralException;
import cn.testin.common.util.log.Logit;
import cn.testin.pojo.device.DeviceInfoExcel;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;

public class DeviceInfoExcelListener extends AnalysisEventListener<DeviceInfoExcel> {

    /**
     * 因为SubjectExcelListener不能交给spring进行管理,需要自己new,不能注入其他对象,如果哦我们想要通过service层获得数据库的数据,我们就需要注入某个service(deviceAssetsApi,这个虽然不是service层,但是性质一样,都是从数据库获取数据)
     */
    public DeviceAssetsApi deviceAssetsApi;
    public DeviceInfoExcelListener(DeviceAssetsApi deviceAssetsApi){
        this.deviceAssetsApi=deviceAssetsApi;
    }


    /**
     * 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据
     * 读取excel内容,一行一行进行读取,会循环调用
     */
    @Override
    public void invoke(DeviceInfoExcel deviceInfoExcel, AnalysisContext analysisContext)   {
        // 取到更改过的数据
        DeviceInfoExcel deviceInfoExcels = savaAssetsInfo(deviceInfoExcel);

        // 如果有数据,更新最新资产信息和增加资产信息记录
        if(deviceInfoExcels != null) {
            try {
            	//数据库更新数据
                deviceAssetsApi.update();
            } catch (Exception e) {
                Logit.errorLog(e.getMessage(), new Throwable(e));
            }
        }
    }

    /**
     * 判断数据是否没有改变,取到更改过的数据
     */
    private DeviceInfoExcel savaAssetsInfo(DeviceInfoExcel deviceInfoExcel) {

        try{
            // 获取到原来数据库中单个用户信息
            DeviceInfoExcel assetInfoExcel= deviceAssetsApi.getAssetInfo(deviceInfoExcel.getDeviceid());
            // 数据库信息和excel信息比对
            if (StringUtils.equalsIgnoreCase(assetInfoExcel.getDeviceid(), deviceInfoExcel.getDeviceid())) {
                if (assetInfoExcel.equals(deviceInfoExcel)) {
                    // 数据一样,不操作
                   return null;
                } else {
                    // 数据不一样,更新
                    return deviceInfoExcel;
                }
            }
        } catch (GeneralException e) {
            Logit.errorLog(e.getMessage(), new Throwable());
        }
        return null;
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }

    /**
     * 监听器实现这个方法就可以在读取数据的时候获取到异常信息Logit.errorLog
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        Logit.errorLog("解析失败,但是继续解析下一行:", new Throwable(exception.getMessage()));
        // 如果是某一个单元格的转换异常 能获取到具体行和列
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;
            Logit.errorLog("错误在这行:", new Throwable(String.valueOf(excelDataConvertException.getRowIndex())));
            Logit.errorLog("错误在这列:", new Throwable(String.valueOf(excelDataConvertException.getColumnIndex())));
        }
    }
}

这里我们重写了DeviceInfoExcel的equals方法,来对比两个对象中的值是否相同

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DeviceInfoExcel that = (DeviceInfoExcel) o;
        return Objects.equals(deviceid, that.deviceid) &&
                Objects.equals(brandName, that.brandName) &&
                Objects.equals(modelName, that.modelName) &&
                Objects.equals(assetsNum, that.assetsNum) &&
                Objects.equals(owner, that.owner) &&
                Objects.equals(descr, that.descr) &&
                Objects.equals(operator, that.operator) &&
                Objects.equals(region, that.region) &&
                Objects.equals(additionalConfig == null ? 0 : String.valueOf(additionalConfig.getPrice()), that.additionalConfig == null ? 0 : String.valueOf(that.getAdditionalConfig().getPrice()));
    }
### EasyExcel监听器使用方法详解 #### 易于理解的监听器概念 监听器EasyExcel框架中用于实时处理读取的数据,使得开发者可以在每次读取一行数据时执行特定逻辑。这种方式不仅提高了程序灵活性,还能够有效减少内存占用。 #### 实现自定义监听器 为了创建一个监听器来处理每一行被解析后的对象,在Java类中继承`AnalysisEventListener<T>`泛型接口,并重写其中的方法。这里T代表要映射的目标实体类型[^2]。 ```java public class UserListener extends AnalysisEventListener<User> { /** * 这个每一条数据解析都会来调用 * * @param data one row value. Is is same as {@link AnalysisSheet#head()} */ @Override public void invoke(User data, AnalysisContext context) { System.out.println("解析到一条数据:" + JSON.toJSONString(data)); } /** * 所有数据解析完成了 都会来调用 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 当所有数据都解析完成之后的操作 System.out.println("所有数据解析完成!"); } } ``` 上述代码展示了如何构建一个简单的监听器实例,它会在每次成功解析一行记录后打印该条目详情;当整个文件全部解析完毕,则输出提示信息表示结束[^4]。 #### 将监听器应用于实际场景 下面给出一段完整的示例代码片段,展示怎样利用之前定义好的监听器去读取并处理Excel文档中的内容: ```java String fileName = "path/to/your/excel/file.xlsx"; // 这里需要指定读用哪个class去接收数据源 EasyExcel.read(fileName).sheet().doRead(new UserListener()); ``` 这段代码说明了如何配置读取路径、关联目标模型以及启动监听机制以响应事件触发的行为[^5]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值