首页 > 其他分享 >EasyExcel单元格合并策略

EasyExcel单元格合并策略

时间:2022-09-26 11:34:48浏览次数:46  
标签:int EasyExcel 单元格 合并 cell writeSheetHolder import curRowIndex

EasyExcel单元格合并策略

自定义策略

package cn.most.rsgzglxt.utils;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.Data;
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;

/**
 * EasyExcel单元格合并策略
 */
@Data
public class ExcelFillCellMergeStrategy implements CellWriteHandler {
    
    /**
     * 合并字段的下标
     */
    private int[] mergeColumnIndex;
    
    /**
     * 合并几行
     */
    private int mergeRowIndex;

    public ExcelFillCellMergeStrategy() {
    }

    public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeColumnIndex = mergeColumnIndex;
        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) {

    }


    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<WriteCellData<?>> 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);
            }
        }
    }
}

Controller

String fileName = "xxxx.xlsx";
        try {
            List<XX> xxs = xxService.selectForExport();
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/vnd.ms-excel");
		   
		   // 对第几列执行合并策略
            int[] mergeColumeIndex = {0};
            // 从第几行开始执行合并策略
            int mergeRowIndex = 2;

            ExcelWriter excelWriter = EasyExcelFactory.write(response.getOutputStream())
                    .withTemplate(new ClassPathResource("moban/template.xlsx").getInputStream())
                    .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex, mergeColumeIndex))
                    .build();

            WriteSheet writeSheet = EasyExcel.writerSheet().build();

            excelWriter.fill(xxs, writeSheet);
            excelWriter.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }

标签:int,EasyExcel,单元格,合并,cell,writeSheetHolder,import,curRowIndex
From: https://www.cnblogs.com/yoojyn/p/yoojyn_easyexcel01.html

相关文章

  • SDN第一次实验报告(第1、2次合并)
    第一次实验报告一、实验目的能够使用源码安装Mininet;能够使用Mininet的可视化工具生成拓扑;能够使用Mininet的命令行生成特定拓扑;能够使用Mininet交互界面管理SDN拓......
  • Git 合并代码遇到冲突如何解决
    Git合并代码遇到冲突如何解决根据这个视频记录的笔记【git合并代码遇到冲突如何解决】https://www.bilibili.com/video/BV1hb4y1e7p9?share_source=copy_web背景实......
  • 合并石子
    这个就强调一点:一定要分清是线性排列还是环形排列,如果是环形的话,只需要将n+1--2n重新赋一遍值,但是:!!!s[i]要继续s[i]=s[i-1]+a[i],而且别忘了给f[n+1][n+1]---f[2n][......
  • 实际工作中 GIT 如何创建合并推送分支
    实际工作中GIT的分支合并是如何操作的?根据这个视频记录的笔记【实际工作中GIT如何创建合并推送分支】https://www.bilibili.com/video/BV1eD4y1F7Kt?share_source=cop......
  • DataGridViewComboBoxCell单元格内容变化后立即引发事件
    原文(C#):(38条消息)C#DataGridView中DataGridViewComboBoxCell下拉列表选择事件_HEALER..的博客-CSDN博客_c#combobox选择事件PrivateSubDataGridView2_EditingCon......
  • 力扣23(java)-合并k个升序链表(困难)
    题目:给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4......
  • 环形合并石子
    #include<iostream>#include<cstring>intf[1000][1000],s[10000],a[10000];intk,n,maxn,miny=100000000;usingnamespacestd;intmain(){cin>>n;mems......
  • 合并两个顺序表
    合并两个顺序表已知有两个顺序表LA和LB(代码如下所示),并且两个表的储存的两个相邻元素,后者要大于或等于前者。合并这两个表。LA,LB的初始化#include<stdio.h>#defineMaxS......
  • 88. 合并两个有序数组
    题目给你两个按非递减顺序排列的整数数组 nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你合并nums2到nums1中,使合并后的数组同......
  • m3u8文件后缀jpg,png等处理方法及视频合并
    处理#解析伪装成png的tsdefresolve_ts(src_path,dst_path):'''如果m3u8返回的ts文件地址为https://p1.eckwai.com/ufile/adsocial/7ead0935-dd4f-4d2......