使用poi导出excel生成复杂多级表头通用方法

使用poi导出excel生成复杂多级表头通用方法 话不多说,直接上代码,需要用的的实体类如下


话不多说,直接上代码,需要用的的实体类如下

package com.test;

public class UnioExcel {
    private Integer firstCol;//合并单元格的起始列坐标
    private Integer firstRol;//合并单元格的起始行坐标

    private Integer finalCol;//合并单元格的起始的终点列坐标
    private Integer finalRol;//合并单元格的起始终点行坐标

    public Integer getFirstCol() {
        return firstCol;
    }
    public void setFirstCol(Integer firstCol) {
        this.firstCol = firstCol;
    }
    public Integer getFirstRol() {
        return firstRol;
    }
    public void setFirstRol(Integer firstRol) {
        this.firstRol = firstRol;
    }
    public Integer getFinalCol() {
        return finalCol;
    }
    public void setFinalCol(Integer finalCol) {
        this.finalCol = finalCol;
    }
    public Integer getFinalRol() {
        return finalRol;
    }
    public void setFinalRol(Integer finalRol) {
        this.finalRol = finalRol;
    }
}

实现多级复杂表头的方法如下(为了方便理解,代码未做优化)

//上面其实还有建立excel等一些基础的代码没有写
//具体思路就是将表头的数据写出来形成二维数组,需要合并的单元格写一样的内容,然后再进行合并操作
   String[][] oldDates = {{"1", "1", "2", "3", "3", "1"}, //多级表头的第一行
   						  {"11", "11", "2", "21", "21", "1"}, //第二行
						  {"11", "11", "2", "31", "32", "1"}, //第三行
						  {"1", "1", "2", "31", "32", "1"}};//第四行
        // 多级表头填充
        for (int i = 0; i < oldDates.length; i++) {
            HSSFRow row = sheet.createRow(i);
            for (int j = 0; j < oldDates[i].length; j++) {
                HSSFCell cell = row.createCell(j);

                cell.setCellValue(oldDates[i][j]);
            }
        }
        String key;
        //利用双层map存需要合并的单元格的开始坐标和终止坐标(将一个需要合并的开始坐标和结束坐标作为一个指针,即一个UnioExcel对象)
        Map<String,Map<String,UnioExcel>>mapFa=new HashMap<String, Map<String, UnioExcel>>();
        for(int i=0;i<oldDates.length;i++){
            for (int j=0;j<oldDates[0].length;j++){
                if(j>0 && oldDates[i][j].equals(oldDates[i][j-1])){
                    //与左一个单元格相同
                    key=oldDates[i][j-1];//获取左边key
                    Integer tempj=j-1;
                    if(mapFa.containsKey(key)){
                        Map<String, UnioExcel> tempmap = mapFa.get(key);
                        //需要进行判断是否存在的指针
                        String tempstr=oldDates[i][j-1]+i+tempj;
                        if (tempmap.containsKey(tempstr)){
                            //判断是否与左一个相同
                            UnioExcel un = tempmap.get(tempstr);
                            un.setFinalRol(i);
                            un.setFinalCol(j);
                            //移动指针到本单元格
                            tempmap.put(oldDates[i][j]+i+j,un);
                            tempmap.remove(tempstr);

                        }else if(i>0){
                            Integer tempi=i-1;
                            String tempstr2=oldDates[i-1][j]+tempi+j;
                            //判断指针是否在同一列的上一行的位置,有则移动,没有则证明,此时需要合并的单元格还不是完整的矩形
                            if(tempmap.containsKey(tempstr2)){
                                UnioExcel unioExcel = tempmap.get(tempstr2);
                                unioExcel.setFinalCol(j);
                                unioExcel.setFinalRol(i);
                                //移动指针到本单元格
                                tempmap.put(oldDates[i][j]+i+j,unioExcel);
                                tempmap.remove(tempstr2);
                            }
                        }
                    }
                }else if(i>0 && oldDates[i][j].equals(oldDates[i-1][j])) {
                    //判断是否和同列上一行的内容是否相同
                    key=oldDates[i-1][j];
                    Integer tempi=i-1;
                    String tempkeyi=oldDates[i-1][j]+tempi+j;
                    Map<String, UnioExcel> tempmap = mapFa.get(key);
                    if(tempmap.containsKey(tempkeyi)){
                        UnioExcel uniotemp = tempmap.get(tempkeyi);
                        uniotemp.setFinalRol(i);
                        uniotemp.setFinalCol(j);
                        //移动指针到本单元格
                        tempmap.put(oldDates[i][j]+i+j,uniotemp);
                        tempmap.remove(tempkeyi);
                    }
                }else {
                    //与其他内容都不相同
                    if(mapFa.containsKey(oldDates[i][j])){
                        //关键部分,在不相连的单元格的地方出现了重复内容,新建一个指针
                        Map<String, UnioExcel> map = mapFa.get(oldDates[i][j]);
                        UnioExcel temunio = new UnioExcel();
                        temunio.setFinalCol(j);
                        temunio.setFinalRol(i);
                        temunio.setFirstRol(i);
                        temunio.setFirstCol(j);
                        map.put(oldDates[i][j]+i+j,temunio);
                        mapFa.put(oldDates[i][j],map);
                    }else {
                        UnioExcel temunio = new UnioExcel();
                        temunio.setFinalCol(j);
                        temunio.setFinalRol(i);
                        temunio.setFirstRol(i);
                        temunio.setFirstCol(j);
                        Map<String,UnioExcel> tempmap=new HashMap<String, UnioExcel>();
                        tempmap.put(oldDates[i][j]+i+j,temunio);
                        mapFa.put(oldDates[i][j],tempmap);
                    }

                }

            }
        }
        //遍历循环,合并单元格
        Iterator<Map.Entry<String, Map<String, UnioExcel>>> it = mapFa.entrySet().iterator();
        while (it.hasNext()){
            Map<String, UnioExcel> value = it.next().getValue();
            Iterator<Map.Entry<String, UnioExcel>> iterator = value.entrySet().iterator();
            while (iterator.hasNext()){
                UnioExcel value1 = iterator.next().getValue();
                //合并具体的单元格
                sheet.addMergedRegion(new CellRangeAddress( value1.getFirstRol() , value1.getFinalRol(), value1.getFirstCol(), value1.getFinalCol()));
            }
        }
	//......后面就是将填充表格数据和写到本地,或者通过网页下载到本地,这些代码网上有大把资料,我就不重复了
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值