Java - 基于AnalysisEventListener实现对Excel的多线程处理

实现Listener

package com.lky.common;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.lky.domain.TestTable;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class TestExportListener extends AnalysisEventListener<TestTable> {

    // 内置计数变量时, 不要static
    private int count = 0;

    private List<TestTable> testTableList;

    @Getter
    private List<TestTable> testTableResList;

    public TestExportListener() {
        this.testTableList = new ArrayList<>();
        this.testTableResList = new ArrayList<>();
    }

    private static TestService testService;
    @Autowired
    public void setComponent(TestService testService){
        TestExportListener.testService = testService;
    }

    @Override
    public void invoke(TestTable testTable, AnalysisContext analysisContext) {
        if (count >= 1001) {
            throw new RuntimeException("Excel文件过大, 最大支持1000条");
        }
        Integer rowIndex = analysisContext.readRowHolder().getRowIndex();
        // 跳过首行标题
        if (rowIndex == 0) {
            return;
        }
        // 封装数据
        testTableList.add(testTable);
        count++;
    }

    /**
     * 所有线程执行完毕后的最后执行方法
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        this.testTableResList.addAll(testTableList);
        // testService.test();
    }

}

实现调用

public static List<TestTable> easyExcelTemplateHandler(InputStream inputStream, String fileName) {
    TestExportListener listener = new TestExportListener();
    EasyExcel.read(inputStream, TestTable.class, listener)
            .excelType(getExcelType(fileName))
            .sheet()
            .doRead();
    return listener.getAllowInvoiceAmountReqList();
}

线程池调用

// 最大处理数量
private static final int BATCH_EXCEL_MAX_SIZE = 3;

// 系统CPU数量
public static final int CPUS = Runtime.getRuntime().availableProcessors();

// 创建线程池
private static ThreadPoolExecutor excelParsePoolExecutor = new ThreadPoolExecutor(
        BATCH_EXCEL_MAX_SIZE * CPUS,
        BATCH_EXCEL_MAX_SIZE * CPUS, 
        1L, 
        HOURS, 
        new LinkedBlockingDeque<>(6000),
        new ThreadFactoryBuilder().setNameFormat("test-excel-parse-pool-%d").build()
);

// 调用
try {
    excelParsePoolExecutor.execute(() -> {
        // Excel文件处理
        TestExportListener listener = new TestExportListener();
	    EasyExcel.read(inputStream, TestTable.class, listener)
	            .excelType(getExcelType(fileName))
	            .sheet()
	            .doRead();
	    });
} catch (Exception e) {
    throw e;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值