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()));
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
EasyExcel是一款基于阿里巴巴开源的Excel解析工具,可以轻松地读取和写入Excel文件。它提供了一个监听器接口,可以在读取或写入Excel文件时对数据进行处理。 具体来说,在读取Excel文件时,可以通过实现`AnalysisEventListener`接口来自定义监听器,例如: ```java public class ExcelListener extends AnalysisEventListener<User> { private List<User> userList = new ArrayList<>(); @Override public void invoke(User user, AnalysisContext context) { // 每读取一行数据,都会调用该方法 userList.add(user); } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 所有数据都已读取完毕后,会调用该方法 // 可以在该方法中对数据进行处理 } public List<User> getUserList() { return userList; } } ``` 在该监听器中,通过覆盖`invoke`方法和`doAfterAllAnalysed`方法来实现对Excel数据的处理。 在写入Excel文件时,可以通过实现`WriteHandler`接口来自定义监听器,例如: ```java public class ExcelHandler implements WriteHandler { @Override public void sheet(int sheetNo, Sheet sheet) { // 写入Excel文件的每个Sheet都会调用该方法 // 可以在该方法中对Sheet进行自定义设置 sheet.setColumnWidth(0, 20 * 256); sheet.setColumnWidth(1, 10 * 256); } @Override public void row(int rowNum, Row row) { // 写入Excel文件的每行数据都会调用该方法 // 可以在该方法中对行进行自定义设置 row.setHeightInPoints(20); } @Override public void cell(int cellNum, Cell cell) { // 写入Excel文件的每个单元格都会调用该方法 // 可以在该方法中对单元格进行自定义设置 if (cellNum == 1) { CellStyle cellStyle = cell.getCellStyle(); Font font = cell.getSheet().getWorkbook().createFont(); font.setBold(true); cellStyle.setFont(font); cell.setCellStyle(cellStyle); } } } ``` 在该监听器中,通过覆盖`sheet`方法、`row`方法和`cell`方法来实现对Excel文件的自定义设置。 最后,在读取或写入Excel文件时,可以通过EasyExcel提供的API来注册监听器,例如: ```java // 读取Excel文件并注册监听器 ExcelListener listener = new ExcelListener(); EasyExcel.read(file, User.class, listener).sheet().doRead(); // 写入Excel文件并注册监听器 ExcelHandler handler = new ExcelHandler(); EasyExcel.write(file, User.class).registerWriteHandler(handler).sheet().doWrite(userList); ``` 通过注册监听器,可以实现对Excel数据的自定义处理和设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值