[alibaba/easyexcel]重写hasNext后doReadAll无法读取下一个sheet

2024-04-25 337 views
7
建议先去看文档

快速开始常见问题

异常代码
   class YourListener(
    // key: sheet name ;value: list of field name
    val headNames: LinkedHashMap<String, List<String>>,
) : AnalysisEventListener<Map<Int, String>?>() {
    private val dataList = ArrayList<Map<Int, String>?>()

    companion object {
        private val logger: Logger = LoggerFactory.getLogger(YourListener::class.java)
    }

    override fun doAfterAllAnalysed(context: AnalysisContext?) {
        logger.info("doAfterAllAnalysed...")
    }

    override fun invoke(data: Map<Int, String>?, context: AnalysisContext?) {
        if (dataList.size < EXCEL_READ_ROW_NUM) {
            return
        }
        dataList.add(data)
        logger.info("条数:${dataList.size}")
    }

    // 解析表头
    override fun invokeHeadMap(headMap: MutableMap<Int, String>?, context: AnalysisContext?) {
        // 当前sheet页名
        val currentSheetName = context?.readSheetHolder()?.sheetName
        println(currentSheetName)
        if (!currentSheetName.isNullOrBlank()) {
            headNames[currentSheetName] = headMap?.values?.toList() ?: emptyList()
        }
    }
}
异常提示 问题描述

版本:easyexcel:3.3.1 问题:当重写hasNext()后,doReadAll失效 需求:读取每个sheet页的前n行, 详细:一开始使用的是【invoke()方法增加判断后返回return】但发现有性能问题;该用【重写hasNext】的方式后发现无法读取下一个sheet页,即listener中的回调方法只执行了一次

回答

5
3163 这个pr是解决这个问题的,不过有冲突了 我去解决一下再重新提交 等待合并这个问题就解决了

那请问fix版本大概会什么时候release

3

@zhuangjiaju
可能要等发版本。 目前解决这个问题可能需要你在逻辑里面判断

6

@zhuangjiaju 可能要等发版本。 目前解决这个问题可能需要你在逻辑里面判断

请问要如何增加判断,我试了【不重写hasNext,直接在invoke方法增加条数的判断后return】,但从耗时来看,依然会继续调用invoke方法。有没有什么办法可以提前终止读取第一页sheet、开始读取第二页

6

加一个卫语句

if(!hasNext){ return; }

8

加一个卫语句

if(!hasNext){ return; }

class YourListener(
    // key: sheet name ;value: list of field name
    val headNames: LinkedHashMap<String, List<String>>,
) : AnalysisEventListener<Map<Int, String>?>() {
    private val dataList = ArrayList<Map<Int, String>?>()

    companion object {
        private val logger: Logger = LoggerFactory.getLogger(YourListener::class.java)
    }

    override fun doAfterAllAnalysed(context: AnalysisContext?) {
        logger.info("条数:${dataList.size}")
    }

    override fun invoke(data: Map<Int, String>?, context: AnalysisContext?) {
        if (!hasNext(context)) {
            return
        }
        logger.info("invoke...")
        dataList.add(data)
    }

    // 解析表头
    override fun invokeHeadMap(headMap: MutableMap<Int, String>?, context: AnalysisContext?) {
        // 当前sheet页名
        val currentSheetName = context?.readSheetHolder()?.sheetName
        println(currentSheetName)
        if (!currentSheetName.isNullOrBlank()) {
            headNames[currentSheetName] = headMap?.values?.toList() ?: emptyList()
        }
    }

    override fun hasNext(context: AnalysisContext?): Boolean {
        return context!!.readSheetHolder()!!.rowIndex <= 20
    }
}

// mian()
val doReadAllSync = EasyExcel.read(file.inputStream).readCache(MapCache())
                .readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA)
                .ignoreEmptyRow(true)
                .registerReadListener(YourListener(headMap)).headRowNumber(1).doReadAllSync<Map<Integer, Any>>()

中断后第二页sheet不会读取

8

已解决。获取sheetList,调用reader.read(),但实在想不明白有啥差别,望指教

val reader = EasyExcel.read(storageFile).readCache(MapCache())
                .readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA)
                .ignoreEmptyRow(true)
                .registerReadListener(SheetAndColumnTypeAnalyseListener(headMap)).headRowNumber(1).build()
            val sheetList = reader.excelExecutor().sheetList()
            reader.read(sheetList)
            reader.close()