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

在导出示例中,不给备注列设值。
示例代码:
java
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;
}
}
}
}
}
代码执行结果:
