EasyExcel导出合并单元格并合计

写这篇文章只是为了自己以后参考,

进入正文:

poi版本:4.1.2

easyExcel版本:2.2.3

1.导出的实体类,也就是表头

@Data
@NoArgsConstructor
@JsonInclude
@ApiModel(value = "省级行业党委信息季度报送-导出")
public class CasPartyReportInfoExportVO implements Serializable {
    private static final long serialVersionUID = 1L;
    @ExcelProperty(value = { "数据1" }, index = 0)
    @ApiModelProperty("所在区域")
    private String data1;

    @ExcelProperty(value = { "基本情况", "数据2" }, index = 1)
    @ApiModelProperty("数据2")
    private Integer data2;

    @ExcelProperty(value = { "基本情况", "数据3" }, index = 2)
    @ApiModelProperty("数据3")
    private Integer data3;

    @ExcelProperty(value = { "基本情况", "数据4" }, index = 3)
    @ApiModelProperty("数据4")
    private Integer data4;
    @ExcelProperty(value = {  "数据5" }, index = 3)
    @ApiModelProperty("数据5")
    private Integer data5;
}

2、行合并工具类

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

public class ExcelFillCellMergeStrategyUtils implements CellWriteHandler {

    /**
     * 需要合并列的下标,从0开始
     */
    private int[] mergeColumnIndex;
    /**
     * 从第几行开始合并,表头下标为0
     */
    private int mergeRowIndex;

    public ExcelFillCellMergeStrategyUtils(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {

        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        int curColIndex = cell.getColumnIndex();

        if (curRowIndex > mergeRowIndex) {
            for (int i = 0; i < mergeColumnIndex.length; i++) {
                if (curColIndex == mergeColumnIndex[i]) {
                    mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    break;
                }
            }
        }

    }

    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        //获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并
        Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() :
                cell.getNumericCellValue();
        Row preRow = cell.getSheet().getRow(curRowIndex - 1);
        if (preRow == null) {
            // 当获取不到上一行数据时,使用缓存sheet中数据
            preRow = writeSheetHolder.getCachedSheet().getRow(curRowIndex - 1);
        }
        Cell preCell=preRow.getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :
                preCell.getNumericCellValue();
        // 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
        if (curData.equals(preData)) {
            Sheet sheet = writeSheetHolder.getSheet();
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastRow(curRowIndex);
                    sheet.addMergedRegion(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若上一个单元格未被合并,则新增合并单元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,
                        curColIndex);
                sheet.addMergedRegion(cellRangeAddress);
            }
        }
    }

}

3、列合并的工具类

@Data
@AllArgsConstructor
public class CellLineRange {

    /**
     * 起始列
     */
    private int firstCol;

    /**
     * 结束列
     */
    private int lastCol;
}
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

public class ExcelFillCelMergeStrategyUtils implements CellWriteHandler {

    //自定义合并单元格的列 如果想合并   第4列和第5例 、第6列和第7例: [CellLineRange(firstCol=3, lastCol=4), CellLineRange(firstCol=5, lastCol=6)]
    private List<CellLineRange> cellLineRangeList;

    //自定义合并单元格的开始的行  一般来说填表头行高0 表示从表头下每列开始合并 :如表头行高位为3则 int mergeRowIndex = 2  ;
    private int mergeRowIndex;

    public ExcelFillCelMergeStrategy(List<CellLineRange> cellLineRangeList, int mergeRowIndex) {
        this.cellLineRangeList=cellLineRangeList;
        this.mergeRowIndex=mergeRowIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {

        //当前单元格的行数
        int curRowIndex = cell.getRowIndex();
        // 当前单元格的列数
        int curColIndex = cell.getColumnIndex();
        if (curRowIndex > mergeRowIndex) {
            if (curRowIndex > mergeRowIndex) {
                for (int i = 0; i < cellLineRangeList.size(); i++) {
                    if (curColIndex > cellLineRangeList.get(i).getFirstCol()&&curColIndex<=cellLineRangeList.get(i).getLastCol()) {
                        //单元格数据处理
                        mergeWithLeftLine(writeSheetHolder, cell, curRowIndex, curColIndex);
                        break;
                    }
                }
            }
        }
    }

4、调用工具类,开始合并:

 List<CasPartyReportInfoExportVO> list = casPartyReportInfoDao.partyInfoSummary(casPartyReportInfoBO);

        try {
            String fileName = "信息汇总表";
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName+"_"+casPartyReportInfoBO.getReportQuarter()+".xlsx", "UTF-8"));

            CasPartyReportInfoExportVO capacityPo=new CasPartyReportInfoExportVO();
            capacityPo.setAddress("合计");
            //遍历列表,求各数据汇总
            capacityPo.setDate1(list.stream().filter(Po-> Po.getDate1()!=null).mapToInt(CasPartyReportInfoExportVO::getDate1).sum());
            capacityPo.setDate2(list.stream().filter(Po-> Po.getDate2()!=null).mapToInt(CasPartyReportInfoExportVO::getDate2).sum());
            capacityPo.setDate3(list.stream().filter(Po-> Po.getDate3()!=null).mapToInt(CasPartyReportInfoExportVO::getDate3).sum());
            capacityPo.setDate4(list.stream().filter(Po-> Po.getDate4()!=null).mapToInt(CasPartyReportInfoExportVO::getDate4).sum());
            capacityPo.setDate5(list.stream().filter(Po-> Po.getDate5()!=null).mapToInt(CasPartyReportInfoExportVO::getDate5).sum());

            list.add(capacityPo);

            ArrayList<CellLineRange> cellLineRanges=new ArrayList<>();
            //设置第几列开始合并
            int[] mergeColumnIndex = {0, 0};
            //设置第几行开始合并
            int mergeRowIndex = list.size();


            cellLineRanges.add(new CellLineRange(0,2));
            EasyExcel.write(response.getOutputStream())
                    //设置行合并单元格
                    .registerWriteHandler(new ExcelFillCellMergeStrategyUtils(mergeRowIndex,mergeColumnIndex))
                    //设置行合并单元格
                    .registerWriteHandler(new ExcelFillCelMergeStrategyUtils(cellLineRanges,list.size()-1))
                    .head(CasPartyReportInfoExportVO.class)
                    .sheet("sheet1")
                    .doWrite(list);

        } catch (Exception e) {
            e.printStackTrace();
        }

成果:

 本文参考了EasyExcel导出合并单元格_easyexcel合并单元格_是一个菜鸟程序员啊的博客-CSDN博客EasyExcel模板导出(行和列自动合并)_easyexcel 模板导出_Lzfnemo2009的博客-CSDN博客

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值