首先我们在合并的时候,自己在心中有一个想法,特定的区域,那么肯定就是从第几行到第几行,以及第几列到第几列这个区域,然后一般我们合并都是对重复的数据这一部分区域进行合并。
也就是需要一个“正方形”区域。
一般情况下如果我们excel的数据是有主从关系的,那么当我们left join之后查询出来的数据,如果从表有多条
那么打平之后的数据行主表肯定是重复的。那么对于这种情况,肯定需要多个“正方形”区域,那么我们就需要进行分组,按照主表的比如“编码”进行分组,然后看看重复的从表有多少行,这样我们就可以确定从哪一行到哪一行需要合并了。
那么我们可以借助map,key是code编码,value是需要合并的行数。比如:
Map<String,Integer> rowsMap = new LinkedHashMap();
Integer number = rowsMap.get("code字段");
rowsMap.put("code字段",number == null ? 1 : number ++);
这个rowsMap的value代表的是行数,并非结束行的下标,因为我们需要的是一个“正方形”,也就是从开始行到结束行下标。
所以我们解下来的操作就是开始按照下标1开始然后按照一定的补步长,构造开始行,结束行这么一个结构,所以我们还是用到map,key是开始行下标,value是结束行下标。
Map<Integer,Integer> startEndRowMap = new HashMap();
然后构造的思路代码:
//第1行为表头,所以下标从1开始
int startRow1 = 1;
for (Integer rowSize : rowSizeList1) {
if (rowSize == 1) {
++startRow1;
} else {
startEndRowMap1.put(startRow1, startRow1 + rowSize - 1);
startRow1 += rowSize;
}
}
这样我们就得到一个从开始行到结束行的map集合。
然后接下来我们就需要有开始列和结束列,也就是startColumn和endColumn。
那么这些前置动作做好了,就要开始我们的合并核心代码了。
合并:
1、继承AbstractMergeStrategy
2、重写merge(Sheet sheet,Cell cell,Head head,Integer relativeRowIndex);
代码如下:
public class CustomMergeStrategy extends AbstractMergeStrategy {
private final Set<Integer> rowSet;//需要合并的开始行的集合
private final Map<Integer, Integer> startEndRowMap;//需要合并的开始行~结束行的map集合
private final Integer startColumn;//需要合并的开始列
private final Integer endColumn;//需要合并的结束列
public CustomMergeStrategy1(Map<Integer, Integer> startEndRowMap, Integer startColumn, Integer endColumn) {
this.rowSet = startEndRowMap.keySet();
this.startEndRowMap = startEndRowMap;
this.startColumn = startColumn;
this.endColumn = endColumn;
}
/**
* merge
*
* @param sheet sheet
* @param cell cell
* @param head head
* @param relativeRowIndex relativeRowIndex
*/
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
Row row = sheet.getRow(cell.getRowIndex());//获取整个sheet表的行下标集合
int rowIndex = cell.getRowIndex();
int colIndex = cell.getColumnIndex();
//从第startColumn到endColumn列,每列的指定行合并
if (rowSet.contains(rowIndex) && colIndex >= startColumn && colIndex <= endColumn) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(rowIndex, startEndRowMap.get(rowIndex), colIndex, colIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}
合并的核心代码写完了,那么最后一步就是注册这个策略到ExcelWriteBuilder里面去,
//我这里导出是通过流写出去的,所以参数用的是outputStream
ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(outputStream)
//字体居中
.registerWriteHandler(new CustomMergeStrategy());
那么如果我们要合并的excel数据,就是单纯固定要对哪几列以及哪几行组成的这个“正方形”进行合并,那么就没有太多的代码,也就是说只有一个“正方形”,那么这种情况一般就是导出单表到一个sheet的情况,那么我们就可以省去那些分组的逻辑。
直接写死既可。这种情况的改造就自己去改造,很简单的。我这里就不多加赘述。
总结:
1、构造“正方形”,第几行到第几行,第几列到第几列。
2、分组
3、合并
4、使用ExcelWriteBuilder注册自定义的合并策略
最后:
如果大家觉得这篇文章对你们有所帮助的话,麻烦点个免费的赞赞,谢谢,也祝各位码农在未来的IT道路上越走越远!