alibaba / easyexcel

快速、简洁、解决大文件内存溢出的java处理Excel工具
https://easyexcel.opensource.alibaba.com
Apache License 2.0
32.09k stars 7.5k forks source link

读取多sheet文件时,只获取了第一个sheet 版本:3.2.1 #3930

Closed vnsun closed 1 month ago

vnsun commented 1 month ago

读取多个sheet文件时,只能获取第一个sheet数据 以下是读取代码,第二个监听器方法没有回调执行 image 下面是我的文件,几经确认sheet名称无错。且指定下标执行结果依旧读取不到第二个sheet image

debug image image

只读取一个指定的sheet正常获取数据 版本3.2.1 升级版本3.3.4、4.0.1 依然没有解决此问题

vnsun commented 1 month ago

image 指定读取第二个sheet情况,由于本地代码库拉不下来,导致定位debug混乱 没继续往下了。望解答此问题

psxjoy commented 1 month ago

Please provide a minimal reproducible demo. 麻烦提供最小复现代码和对应的文件。

vnsun commented 1 month ago

复现代码

  1. 执行

    String path = "C:\\Users\\vn_su\\Desktop\\acc.xlsx";
        File file = new File(path);
        FileInputStream inputStream = new FileInputStream(file);
        ExcelReader reader = EasyExcel.read(inputStream).build();
    
        CreativeQuotationAccFeeTmpDeliverablesListener deliverablesListener = new CreativeQuotationAccFeeTmpDeliverablesListener(1L);
        ReadSheet sh1 = EasyExcel.readSheet("By Deliverables martix").head(CvQuotationAccFeeTmpDeliverablesExcel.class)
                .headRowNumber(3).registerReadListener(deliverablesListener).build();
        CreativeQuotationAccFeeTmpMediaInnoListener mediaInnoListener = new CreativeQuotationAccFeeTmpMediaInnoListener(1L);
        ReadSheet sh2 = EasyExcel.readSheet("Media inno OLB").head(CvQuotationAccFeeTmpMediaInnoExcel.class)
                .headRowNumber(3).registerReadListener(mediaInnoListener).build();
        reader.read(sh1, sh2);
        List<CvQuotationAccFeeTmpDeliverablesExcel> deliverablesList = deliverablesListener.list;
        List<CvQuotationAccFeeTmpMediaInnoExcel> mediaInnoList = mediaInnoListener.list;
  2. 监听

    
    @Slf4j
    public class CreativeQuotationAccFeeTmpDeliverablesListener extends AnalysisEventListener<CvQuotationAccFeeTmpDeliverablesExcel> {
    
    public final List<CvQuotationAccFeeTmpDeliverablesExcel> list = new ArrayList<>();
    public BigDecimal totalCost = BigDecimal.ZERO;
    private CvQuotationAccFeeTmpDeliverablesExcel prev;
    private boolean nextBreakFlag = true;
    private final Long naId;
    
    public CreativeQuotationAccFeeTmpDeliverablesListener(Long naId) {
        this.naId = naId;
    }
    
    @Override
    public void invoke(CvQuotationAccFeeTmpDeliverablesExcel cvQuotationAccFeeTmpDeliverablesExcel, AnalysisContext analysisContext) {
        String deliverables = cvQuotationAccFeeTmpDeliverablesExcel.getDeliverables();
        // 中断
        if (StrUtil.isBlank(deliverables)) {
            nextBreakFlag = false;
            totalCost = cvQuotationAccFeeTmpDeliverablesExcel.getCost() == null ? BigDecimal.ZERO : cvQuotationAccFeeTmpDeliverablesExcel.getCost();
            return;
        }
        processNull(prev, cvQuotationAccFeeTmpDeliverablesExcel);
        cvQuotationAccFeeTmpDeliverablesExcel.setCostMergeAnnex(String.valueOf(cvQuotationAccFeeTmpDeliverablesExcel.getCost()));
        // 判断是否合并
        if (prev != null && prev.getProjectTypeAnnex().equals(cvQuotationAccFeeTmpDeliverablesExcel.getProjectTypeAnnex())
            && cvQuotationAccFeeTmpDeliverablesExcel.getCost().compareTo(BigDecimal.ZERO) == 0) {
            cvQuotationAccFeeTmpDeliverablesExcel.setCostMergeAnnex(StrUtil.DASHED);
        }
        prev = cvQuotationAccFeeTmpDeliverablesExcel;
        list.add(cvQuotationAccFeeTmpDeliverablesExcel);
    }
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("CvQuotationAccFeeTmpDeliverablesExcel解析完毕");
    }
    
    @Override
    public boolean hasNext(AnalysisContext context) {
        return nextBreakFlag;
    }
    
    /**
     * 处理空值
     * @param prev 上一个实例
     * @param current 当前实例
     */
    private void processNull(CvQuotationAccFeeTmpDeliverablesExcel prev, CvQuotationAccFeeTmpDeliverablesExcel current) {
        if (prev == null) {
            return;
        }
        if (StrUtil.isBlank(current.getNumber())) {
            current.setNumber(prev.getNumber());
        }
    }

}

@Slf4j public class CreativeQuotationAccFeeTmpMediaInnoListener extends AnalysisEventListener {

public final List<CvQuotationAccFeeTmpMediaInnoExcel> list = new ArrayList<>();
public BigDecimal totalCost = BigDecimal.ZERO;
private boolean nextBreakFlag = true;
private final Long naId;

public CreativeQuotationAccFeeTmpMediaInnoListener(Long naId) {
    this.naId = naId;
}

@Override
public void invoke(CvQuotationAccFeeTmpMediaInnoExcel cvQuotationAccFeeTmpMediaInnoExcel, AnalysisContext analysisContext) {
    String projectType = cvQuotationAccFeeTmpMediaInnoExcel.getProjectType();
    // 中断
    if (StrUtil.isBlank(projectType)) {
        nextBreakFlag = false;
        totalCost = cvQuotationAccFeeTmpMediaInnoExcel.getCost() == null ? BigDecimal.ZERO : cvQuotationAccFeeTmpMediaInnoExcel.getCost();
        return;
    }
    list.add(cvQuotationAccFeeTmpMediaInnoExcel);
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    log.info("CreativeQuotationAccFeeTmpMediaInnoListener解析完毕");
}

@Override
public boolean hasNext(AnalysisContext context) {
    return nextBreakFlag;
}

}


3. 实体

@Data public class CvQuotationAccFeeTmpDeliverablesExcel {

@ExcelIgnore
private Long creativeNaId;
@ExcelProperty(index = 0)
private String number;
@ExcelProperty(index = 1)
private String projectType;
@ExcelProperty(index = 2)
private String projectTypeAnnex;
@ExcelProperty(index = 3)
private String deliverables;
@ExcelProperty(index = 4)
private String deliverablesMilestone;
@ExcelProperty(index = 5)
private BigDecimal cost;
@ExcelProperty(index = 6)
private String remark;
@ExcelIgnore
private String costMergeAnnex;
@ExcelIgnore
private Integer sort;

}

@Data public class CvQuotationAccFeeTmpMediaInnoExcel {

@ExcelIgnore
private Long creativeNaId;
@ExcelProperty("No")
private String number;
@ExcelProperty("Project Type")
private String projectType;
@ExcelProperty("Deliverables")
private String deliverables;
@ExcelProperty("Cost (w/o tax)")
private BigDecimal cost;
@ExcelProperty("Remark")
private String remark;
@ExcelIgnore
private Integer sort;

}



4. 文件
[acc.xlsx](https://github.com/user-attachments/files/16674504/acc.xlsx)
vnsun commented 1 month ago

另外还发现一个问题 代码同上 读取额外信息时 读不到(批注、合并单元格信息)

以下是不同代码

EasyExcel.read(inputStream)
                    .extraRead(CellExtraTypeEnum.COMMENT).sheet("By Deliverables martix").head(CvQuotationAccFeeTmpDeliverablesExcel.class)
                    .headRowNumber(3).registerReadListener(deliverablesListener).build();

CreativeQuotationAccFeeTmpDeliverablesListener监听器重写此代码没有进行调用

@Override
    public void extra(CellExtra extra, AnalysisContext context) {
        extra.getFirstColumnIndex();
    }
vnsun commented 1 month ago

@zhuangjiaju @psxjoy

vnsun commented 1 month ago

没有人来解答 或者看下这个问题么? @zhuangjiaju @psxjoy @frankggyy @clevertension

psxjoy commented 1 month ago

I couldn't reproduce the issue. It's recommended to remove the business code and check step by step. 无法复现。建议剔除业务代码,一步步排查。

image

vnsun commented 1 month ago

@psxjoy 我大概知道原因了 处理两个sheet的Listener类中重写了hasNext方法,第一个 处理程序执行完重写的hasNext方法返回false。影响到了第二个处理类没有执行。这应该算是bug。 注释掉重写的hasNext 执行正常 image

psxjoy commented 1 month ago

Nice try!Very happy with your information. I will check it and discuss whether fix it or add suggestion on website. Thank you for debuging.

获取 Outlook for iOShttps://aka.ms/o0ukef


发件人: vnsun @.> 发送时间: Monday, August 26, 2024 5:51:11 PM 收件人: alibaba/easyexcel @.> 抄送: Black Pan @.>; Mention @.> 主题: Re: [alibaba/easyexcel] 读取多sheet文件时,只获取了第一个sheet 版本:3.2.1 (Issue #3930)

@psxjoyhttps://github.com/psxjoy 我大概知道原因了 处理两个sheet的Listener类中重写了hasNext方法,第一个 处理程序执行完重写的hasNext方法返回false。影响到了第二个处理类没有执行。这应该算是bug。 注释掉重写的hasNext 执行正常 image.png (view on web)https://github.com/user-attachments/assets/11061931-51ea-42e5-bcf7-d878743116d8

― Reply to this email directly, view it on GitHubhttps://github.com/alibaba/easyexcel/issues/3930#issuecomment-2309809183, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACRXFDVDJEHTJZP374SW32DZTL3A7AVCNFSM6AAAAABMN57AOOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMBZHAYDSMJYGM. You are receiving this because you were mentioned.Message ID: @.***>

vnsun commented 1 month ago

OK,很期待