Open PhysicalOptics opened 5 months ago
同求
+1
LGTM
@Test public void listFill() { // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"{","}"代替 // 填充list 的时候还要注意 模板中{.} 多了个点 表示list // 如果填充list的对象是map,必须包涵所有list的key,哪怕数据为null,必须使用map.put(key,null) File templateFileName = new File("D:\不加密\simple.xlsx"); File exportFile = FileUtils.createNewFile("D:\不加密\simple" + System.currentTimeMillis() + ".xlsx");
Map<Integer, Integer> mergeMap=new HashMap<>();
mergeMap.put(3,1);
mergeMap.put(10,5);
MergeRowWriteHandler mergeRowWriteHandler = new MergeRowWriteHandler(mergeMap);
// 方案2 分多次 填充 会使用文件缓存(省内存)
try (ExcelWriter excelWriter = EasyExcel.write(exportFile).withTemplate(templateFileName)
.registerWriteHandler(mergeRowWriteHandler)
.build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
excelWriter.fill(data(), writeSheet);
}
}
private List<FillData> data() {
List<FillData> list = ListUtils.newArrayList();
for (int i = 0; i < 20; i++) {
FillData fillData = new FillData();
fillData.setName("张三");
fillData.setNumber(5.2);
fillData.setDate(new Date());
list.add(fillData);
if (i< 3) {
fillData.setId(6L);
}else {
fillData.setId(7L);
}
}
return list;
}
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress;
import java.util.HashMap; import java.util.Map;
public class MergeRowWriteHandler implements RowWriteHandler { // 假设这是你在写入数据之前构建的映射,key是行号(从0开始),value表示该行与上几行合并 private final Map<Integer, Integer> mergeMap = new HashMap<>();
// 构造器,你可以在这里传入合并逻辑或合并映射
public MergeRowWriteHandler(Map<Integer, Integer> mergeMap) {
this.mergeMap.putAll(mergeMap);
}
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
if (isHead) {
return;
}
// 获取当前行的行号(注意:这里的行号是从0开始的,但在Excel中通常是从1开始的)
int rowIndex = relativeRowIndex;
// 注意:我们实际上是在决定当前行与“之前的”已写入行是否应该合并,但在这里我们假设mergeMap已经根据业务逻辑设置好了
if (mergeMap.containsKey(rowIndex)) {
Integer lineNumber = mergeMap.get(rowIndex);
Sheet sheet = writeSheetHolder.getSheet();
int boforeRowNum = rowIndex - lineNumber;
System.out.println("需要合并行:" + boforeRowNum + " 到 " + rowIndex);
// 合并单元格,注意:Excel中的行和列都是从0开始的
CellRangeAddress addressList = new CellRangeAddress(
boforeRowNum, relativeRowIndex, 0, 0); // 合并1列
sheet.addMergedRegion(addressList);
CellRangeAddress addressList2 = new CellRangeAddress(
boforeRowNum, relativeRowIndex, 1, 1); // 合并2列
sheet.addMergedRegion(addressList2);
// 注意:在实际应用中,你可能需要存储这些合并信息,并在写入完成后应用它们
}
// 注意:上面的逻辑并不实际合并单元格,因为当afterRowDispose被调用时,下一行可能还没有被写入
}
}
临时解决方案,提前计算要合并的行,和向上合并几行。
同求
能不能出一个和easyPOI中类似@ExcelCollection来解决一对多的问题
在easyPOI 中导入和导出可以用@ExcelCollection 来解决一对多导出时主数据一行已经自动合并,子数据多行正常导出