【EasyExcel】解决模板导出时,合并单元格样式丢失

        解决使用EasyExcel 模板导出时,列表中的合并单元格列,自动新增时样式异常,不会自动合并。

 导出模板

        在导出示例中,不给备注列设值。

示例代码:

package easyExcel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: DaBing
 * @Create_Date: 2025/11/6 16:36
 */
@Slf4j
@SpringBootTest
public class EasyExcelDemo {

    /**
     * 复杂的填充
     *
     * @since 2.1.1
     */
    @Test
    public void complexFill() {
        //模板路径
        String templateFileName = "模板路径";
        //导出文件保存路径
        String fileName = "导出文件保存路径";

        List<Map> dataList = this.getDataList();

        ExcelWriter excelWriter = EasyExcel.write(fileName)
                .registerWriteHandler(new MyHandler())  //设置策略
                .withTemplate(templateFileName).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
        // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
        // 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
        // 如果数据量大 list不是最后一行 参照下一个
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        excelWriter.fill(dataList, fillConfig, writeSheet);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2019年10月9日13:28:28");
        map.put("total", 1000);
        excelWriter.fill(map, writeSheet);
        excelWriter.finish();
    }
    @Test
    public void complexFill1() {
        PrintSuper printSuper = new PrintSuper();
        List dataList = printSuper.getPrintData();
        Object o = dataList.get(0);
        System.out.println(JSON.toJSONString(o));

        Field[] fields = o.getClass().getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            System.out.println(">>>> " + name);
        }

    }

    public class PrintSuper {


        public List<PrintData> getPrintData() {
            List<PrintData> printDataList = new ArrayList<>();
            for (int i = 0; i < 10; i ++) {
                PrintData printData = new PrintData();
                printData.setIndex(i);
//                printData.setName("name" + i);
                printDataList.add(printData);
            }
            return printDataList;
        }

        private class PrintData {
            private int index;

            private String name;

            public int getIndex() {
                return index;
            }

            public void setIndex(int index) {
                this.index = index;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }
        }
    }

    private static List<Map> getDataList() {
        List<Map> dataList = new ArrayList<>();
        for (int i = 0; i < 5; i ++) {
            Map temp = new HashMap();
            temp.put("index", i);
            temp.put("name", "名称" + i);
            temp.put("number", i * 10);
            temp.put("remarks", "");
            dataList.add(temp);
        }

        return dataList;
    }

    /**
     * 单元格合并策略1
     */
    public class MyHandler extends AbstractMergeStrategy {

        @Override
        protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
            if(relativeRowIndex==null ||relativeRowIndex==0){
                return;
            }

            int rowIndex = cell.getRowIndex();
            int colIndex = cell.getColumnIndex();

            log.debug(">>> 处理第 {} 行数据,第 {} 列数据", rowIndex, colIndex);

            sheet=cell.getSheet();
            Row preRow = sheet.getRow(rowIndex - 1);
            Cell preCell = preRow.getCell(colIndex);//获取上一行的该格
            List<CellRangeAddress> rangeAddressList = sheet.getMergedRegions();
            for (int i = 0; i < rangeAddressList.size(); i++) {
                CellRangeAddress cellRangeAddress = rangeAddressList.get(i);

                if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex()))  {
                    int firstColIndex = cellRangeAddress.getFirstColumn();
                    int lastColIndex = cellRangeAddress.getLastColumn();
                    int firstRowIndex = cellRangeAddress.getFirstRow();

                    log.debug(">>> 第 {} 行 {},第 {} 列至第 {} 列合并。", rowIndex, firstRowIndex, firstColIndex, lastColIndex);

                    CellRangeAddress cra;
                    cra = new CellRangeAddress(rowIndex, rowIndex, firstColIndex, lastColIndex);
                    sheet.addMergedRegion(cra);

                    //设置合并区域cra的边框
                    RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);
                    RegionUtil.setBorderLeft(BorderStyle.THIN, cra, sheet);
                    RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet);
                    RegionUtil.setBorderTop(BorderStyle.THIN, cra, sheet);
                    return;
                }
            }
        }
    }
}

代码执行结果:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值