Java实现EasyExcel读取前几行前几列

原文地址

原文地址:Java实现EasyExcel读取前几行前几列

背景

在当前的项目中,有一个需求是数据集文件的预览操作,既然是数据集,大数据量Excel文件也是不可避免的,几百列几万行数据那都是很正常的,因此需要做一个限定行列的都区方案。

因为只读前几行前几列,资源占用和读取时长都很短,因此想要直接同步读进行处理,但是EsayExcel同步读的时候,除了自己重写一些类之外,是默认注册了同步读监听器的,因此之前考虑用同步读一直没实现。

后来在Github下给作者大佬发了个ISSUES,JiaJu Zhuang 大佬给出提示,抛出ExcelAnalysisStopException异常,因此顺着这个思路来搞一下。

实现

监听器

因为同步读存在的制约,因此还是使用异步读,首先定义一个监听器类,实现异步读时的行列限制,这里定义LimitExcelReadListener并继承AnalysisEventListener;

因为我做的是数据集预览,行列均不固定,只能使用Map来接收行,代码不复杂,我直接给出完整代码:

public class LimitExcelReadListener extends AnalysisEventListener<Map<Integer, String>> {
    // 定义变量,分别表示限制列数和行数
    private Integer limitColSize;
    private Integer limitRowSize;
    // 定义变量,存储表头信息和表数据
    private List<Map<Integer, String>> headList = new ArrayList<>();
    private List<Map<Integer, String>> dataList = new ArrayList<>();
    // 构造函数
    LimitExcelReadListener() {

    }
    // 带参构造函数,直接赋值限制行列
    LimitExcelReadListener(Integer limitColSize, Integer limitRowSize) {
        this.limitColSize = limitColSize;
        this.limitRowSize = limitRowSize;
    }
    
    /**
     * 工具方法,根据传入的列限制来保留数据,也就是只取前几个Key,如果有需求,可以自己添加KeySet排序之后再取,我这里没这个需求
     * @param oldMap 未限制列前的Map
     * @return 限制列后的Map
     */
    private Map<Integer, String> getLimitColMap(Map<Integer, String> oldMap) {
        Integer size = oldMap.keySet().size();
        Map<Integer, String> newMap = new HashMap<>();
        for (int i = 0; i < (size >= this.limitColSize ? this.limitColSize : size); i++) {
            newMap.put(i, oldMap.get(i));
        }
        return newMap;
    }

    @Override
    public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
        // 获取限制列之后的Map,并存入dataList
        Map<Integer, String> newMap = this.getLimitColMap(integerStringMap);
        dataList.add(newMap);
        
        // 判断行数已达到限制行数,抛出ExcelAnalysisException
        if (dataList.size() >= this.limitRowSize) {
            throw new ExcelAnalysisException(this.limitRowSize + "行" + this.limitColSize + "列读取完成");
        }
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 获取限制列之后的表头Map,并存入headList
        Map<Integer, String> newMap = this.getLimitColMap(headMap);
        headList.add(newMap);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }


}

读取工具类

接着是读取的工具类,代码也很简单,这里直接贴出来:

public class EExcelPrevUtils {
    /**
     * @param path         要读取文件的路径
     * @param limitColSize 要限制的列数
     * @param limitRowSize 要限制的行数
     * @return 读取到的数据
     * @throws FileNotFoundException
     */
    public static Map<String, Object> readLimitExcel(String path, Integer limitColSize, Integer limitRowSize) throws Exception {
        //定义一个Map保存表头和数据
        Map<String, Object> result = new HashMap<>();
        //声明读取所需FileInputStream
        FileInputStream inputStream = new FileInputStream(new File(path));
        //初始化一个监听器
        LimitExcelReadListener dataListener = new LimitExcelReadListener(limitColSize, limitRowSize);
        //读取文件数据
        try {
            EasyExcel.read(inputStream, dataListener).sheet().doRead();
        } catch (ExcelAnalysisException a) {
            System.out.println("读取完成");
            result.put("headList", dataListener.getHeadList());
            result.put("dataList", dataListener.getDataList());
        } catch (Exception a) {
            System.out.println("读取失败");
            throw a;
        }
        return result;
    }
}

其他说明

以上代码都是基于一个Sheet的前提下做的,如果是多个sheet,就根据自己的需求重新搞下读取工具类即可

鸣谢

Alibaba EasyExcel

JiaJu Zhuang

原文地址

原文地址:Java实现EasyExcel读取前几行前几列

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很高兴为您解答这个问题!关于 Java 实现 easyexcel 读取数据导入数据库的例子,我可以提供一些参考: 1. 您可以先在项目中引入 easyexcel 的相关依赖,例如: <!-- 引入 easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.10</version> </dependency> 2. 创建一个实体类来存储 Excel 中的数据,例如: @Data public class ExcelData { @ExcelProperty(index = 0) private String name; @ExcelProperty(index = 1) private Integer age; @ExcelProperty(index = 2) private String gender; // 省略 getter 和 setter 方法 } 3. 在代码中使用 easyexcel 进行读取 Excel 数据,例如: public void readExcelData() throws IOException { InputStream inputStream = new FileInputStream("data.xlsx"); EasyExcel.read(inputStream, ExcelData.class, new ExcelDataListener()).sheet().doRead(); } 4. 实现一个监听器来处理读取到的数据,例如: public class ExcelDataListener extends AnalysisEventListener<ExcelData> { @Override public void invoke(ExcelData data, AnalysisContext context) { // 处理读取到的数据,可以写入数据库等操作 } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 读取完成后的操作 } } 5. 在 invoke 方法中可以将读取到的数据写入数据库等操作,例如: @Override public void invoke(ExcelData data, AnalysisContext context) { // 将读取到的数据写入数据库 jdbcTemplate.update("INSERT INTO user (name, age, gender) VALUES (?, ?, ?)", data.getName(), data.getAge(), data.getGender()); } 希望以上内容能够对您有所帮助!如果您还有其他问题,欢迎提出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FENGYU406

赏杯咖啡喝~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值