当前位置: 代码网 > it编程>编程语言>Java > Java easyExcel实现导入多sheet的Excel

Java easyExcel实现导入多sheet的Excel

2025年06月27日 Java 我要评论
1.官网easyexcel官网2.excel样式3.代码@slf4jpublic class dynamicimportlistener implements readlistener<map&

1.官网

easyexcel官网

2.excel样式

3.代码

@slf4j
public class dynamicimportlistener implements readlistener<map<integer, string>> {

    /**
     * 从哪一行开始读数据
     */
    private final int headrownumber;
    /**
     * 公司信息列
     */
    private final int companyinfonumber;
    /**
     * 数据列
     */
    private final int headnumber;
    private final map<integer, map<integer, string>> rawrowsmap = new hashmap<>();
    private final list<cellextra> extramergeinfolist = new arraylist<>();
    private final map<integer, string> headermap = new linkedhashmap<>();
    private final navigablemap<integer, string> companyinfomap = new treemap<>();

    public dynamicimportlistener(int headrownumber, int companyinfonumber, int headnumber) {
        this.headrownumber = headrownumber;
        this.companyinfonumber = companyinfonumber;
        this.headnumber = headnumber;
    }

    @override
    public void invoke(map<integer, string> rowmap, analysiscontext context) {
        int rowindex = context.readrowholder().getrowindex();

        if (rowindex == companyinfonumber) {
            string company = rowmap.get(0);
            if (strutil.isnotblank(company)) {
                companyinfomap.put(rowindex, company.trim());
            }
        } else if (rowindex == headnumber) {
            for (map.entry<integer, string> e : rowmap.entryset()) {
                string v = e.getvalue();
                if (strutil.isnotblank(v)) {
                    headermap.put(e.getkey(), v.trim());
                }
            }
        }else {
            rawrowsmap.put(rowindex, rowmap);
        }
    }

    @override
    public void extra(cellextra extra, analysiscontext context) {
        if (extra.gettype() == cellextratypeenum.merge
                && extra.getfirstrowindex() >= headrownumber - 1) {
            extramergeinfolist.add(extra);
        }
    }

    @override
    public void doafterallanalysed(analysiscontext context) {
        log.info("读取完毕:数据总行 {},表头列 {},合并单元格 {} 条",
                rawrowsmap.size(), headermap.size(), extramergeinfolist.size());
    }

    /**
     * 获取首条公司信息
     */
    public string getcompanyinfo() {
        return companyinfomap.isempty() ? null : companyinfomap.firstentry().getvalue();
    }

    /**
     * 获取所有合并单元格元数据
     */
    public list<cellextra> getmergedregions() {
        return collections.unmodifiablelist(extramergeinfolist);
    }

    /**
     * 回填合并单元格数据
     */
    public void fillmergedcells() {
        if (extramergeinfolist.isempty()) return;
        for (cellextra extra : extramergeinfolist) {
            int r1 = extra.getfirstrowindex();
            int r2 = extra.getlastrowindex();
            int c1 = extra.getfirstcolumnindex();
            string init = rawrowsmap.get(r1).get(c1);
            for (int rr = r1; rr <= r2; rr++) {
                map<integer, string> row = rawrowsmap.get(rr);
                if (row == null) continue;
                for (int cc = c1; cc <= extra.getlastcolumnindex(); cc++) {
                    row.put(cc, init);
                }
            }
        }
    }

    /**
     * 构建 vo 列表,固定字段 + extrafields
     */
    public <t> list<t> buildvolist(class<t> voclass) {
        list<t> result = new arraylist<>();
        int headeridx = headnumber;
        int maxrow = rawrowsmap.keyset().stream().max(integer::compareto).orelse(headeridx);

        for (int idx = headeridx + 1; idx <= maxrow; idx++) {
            map<integer, string> rowmap = rawrowsmap.get(idx);
            if (rowmap == null) continue;
            try {
                t vo = voclass.getdeclaredconstructor().newinstance();
                // 填充列
                for (map.entry<integer, string> head : headermap.entryset()) {
                    string headername = head.getvalue();
                    string cellval = rowmap.get(head.getkey());
                    string value = (cellval == null) ? "" : cellval.trim();
                    boolean matched = false;
                    for (field f : voclass.getdeclaredfields()) {
                        excelproperty prop = f.getannotation(excelproperty.class);
                        if (prop != null && arrays.aslist(prop.value()).contains(headername)) {
                            f.setaccessible(true);
                            f.set(vo, converttype(f.gettype(), value));
                            matched = true;
                            break;
                        }
                    }
                    if (!matched) {
                        method m = voclass.getmethod("getextrafields");
                        @suppresswarnings("unchecked")
                        map<string, string> extra = (map<string, string>) m.invoke(vo);
                        extra.put(headername, value);
                    }
                }

                result.add(vo);
            } catch (exception e) {
                log.error("行 {} 构建 vo 失败: {}", idx + 1, e.getmessage());
            }
        }
        return result;
    }

    /**
     * @param targettype 目标类型
     * @param text 文本
     * @return java.lang.object
     * @description 数据类型转换
     * @author zhaohuaqing
     * @date 2025/6/26 11:42
     */
    private object converttype(class<?> targettype, string text) {
        if (text == null) {
            return null;
        }
        string trimmed = text.trim();

        // 字符串
        if (targettype == string.class) {
            return trimmed;
        }
        // 原生数字类型
        if (targettype == integer.class || targettype == int.class) {
            return integer.valueof(trimmed);
        }
        if (targettype == long.class    || targettype == long.class) {
            return long.valueof(trimmed);
        }
        if (targettype == double.class  || targettype == double.class) {
            return double.valueof(trimmed);
        }
        if (targettype == float.class   || targettype == float.class) {
            return float.valueof(trimmed);
        }
        if (targettype == short.class   || targettype == short.class) {
            return short.valueof(trimmed);
        }
        if (targettype == byte.class    || targettype == byte.class) {
            return byte.valueof(trimmed);
        }
        // bigdecimal
        if (targettype == bigdecimal.class) {
            return new bigdecimal(trimmed);
        }
        // 布尔
        if (targettype == boolean.class || targettype == boolean.class) {
            // 支持 "true"/"false",也支持 "1"/"0"
            if ("1".equals(trimmed) || "0".equals(trimmed)) {
                return "1".equals(trimmed);
            }
            return boolean.valueof(trimmed);
        }
        // java 8 日期时间
        if (targettype == localdate.class) {
            // 默认 iso 格式,或自定义
            return localdate.parse(trimmed, datetimeformatter.iso_local_date);
        }
        if (targettype == localtime.class) {
            return localtime.parse(trimmed, datetimeformatter.iso_local_time);
        }
        if (targettype == localdatetime.class) {
            return localdatetime.parse(trimmed, datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss"));
        }
        if (targettype == offsetdatetime.class) {
            return offsetdatetime.parse(trimmed, datetimeformatter.iso_offset_date_time);
        }
        if (targettype == zoneddatetime.class) {
            return zoneddatetime.parse(trimmed, datetimeformatter.iso_zoned_date_time);
        }
        // 旧版 java.util.date
        if (targettype == java.util.date.class) {
            try {
                // 你可以根据 excel 导出格式,调整 simpledateformat
                return new simpledateformat("yyyy-mm-dd hh:mm:ss").parse(trimmed);
            } catch (parseexception e) {
                throw new runtimeexception("日期解析失败: " + trimmed, e);
            }
        }
        return trimmed;
    }
}

如何使用

@data
@builder
@allargsconstructor
@noargsconstructor
@accessors(chain = false) // 设置 chain = false,避免excel导入有问题
public class sopextractmdsavo {

   
    @excelproperty(value = "一级xxx")
    private string firstlevel;

  
    @excelproperty(value = "二级xxx")
    private string secondlevel;


    @excelproperty(value = "三级xxx")
    private string thirdlevel;
    
    @excelproperty(value = "xxx")
    private string formula;
    
    @excelproperty(value = "xxx")
    private string factor;
    
    @excelproperty(value = "xxx")
    private string referencevalue;
    
    @excelproperty(value = "xxx")
    private string element;
    
    @excelproperty(value = "xxx")
    private string scheme;
    
    @excelproperty(value = "超链接1")
    private string hyperlink1;
    
    @excelproperty(value = "超链接2")
    private string hyperlink2;
    
    @excelproperty(value = "超链接3")
    private string hyperlink3;

    /**
     * 动态列:所有未在 vo 明确定义的列
     */
    private map<string, string> extrafields = new linkedhashmap<>();

    /**
     * 管控方案ids
     */
    private string controlplanids;

    /**
     * 输出物ids
     */
    private string outputmaterialids;

    /**
     * @return 非空的 hyperlink 列表
     */
    public list<string> nonblankhyperlinks() {
        list<string> list = new arraylist<>(10);
        if (strutil.isnotblank(hyperlink1)) list.add(hyperlink1);
        if (strutil.isnotblank(hyperlink2)) list.add(hyperlink2);
        if (strutil.isnotblank(hyperlink3)) list.add(hyperlink3);
        return list;
    }
}
        inputstream inputstream = file.getinputstream();
        int headrownumber = 0;  // 表头在 excel 的第 2 行(从 1 开始计)
        dynamicimportlistener listener = new dynamicimportlistener(headrownumber, 0, 1);

        // 1) 读数据、收集表头 & 合并单元格 & 公司信息
        easyexcel.read(inputstream, listener)
                .extraread(cellextratypeenum.merge)
                .sheet("test")
                .headrownumber(headrownumber)
                .doread();

        // 2) 外部拿公司信息
        string company = listener.getcompanyinfo();
        // 3) 回填合并单元格
        listener.fillmergedcells();
        // 4) 构建 vo 列表(包含固定字段 + extrafields)
        list<sopextractmdsavo> rows = listener.buildvolist(sopextractmdsavo.class);

到此这篇关于java easyexcel实现导入多sheet的excel的文章就介绍到这了,更多相关java easyexcel导入excel内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com