背景
应项目的要求,改了订单导出的功能,项目上顺便又改造了导出的导出的框架,从原本的流读取,换成的现在的开源项目EasyExcel。再后来,发现我做的导出少了原本的单元格合并。。。。。。。
效果图
效果如上,就是部分公共信息是合并单元格显示的,到了商品上又不是合并,总价上又是合并的
EasyExcel介绍
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
对于合并单元格,官网是这样的写的:
这样写的比较笼统,不太容易看得懂,但是最后一句很关键:“合并策略可以自己写”
EasyExcel官网地址:https://alibaba-easyexcel.github.io/index.html
实战
由于项目需要合并的复杂程度,这里我们的合并策略肯定要自己写的,但是我百度一下发现。。。。。全是把官网内容拷过来的,就没有一个人去实战的吗?
最后,好在这位老哥帮我充分理解了如何自定义策略:【转】利用阿里研发的easyexcel导入导出excel,避免OOM,并对excel加密保护
下面我们来通过我的操作来一步步讲解如何自定义合并策略
1.合并策略的编写,在如官网所描述的,你要做合并单元格,那么你就得先提供一个合并策略,共用的合并策略有以下两种:LoopMergeStrategy(循环合并),OnceAbsoluteMergeStrategy(一次性合并)
我这里拿一次性合并(OnceAbsoluteMergeStrategy)的源码来说一下:
public class OnceAbsoluteMergeStrategy extends AbstractMergeStrategy {
private int firstRowIndex;
private int lastRowIndex;
private int firstColumnIndex;
private int lastColumnIndex;
public OnceAbsoluteMergeStrategy(int firstRowIndex, int lastRowIndex, int firstColumnIndex, int lastColumnIndex) {
if (firstRowIndex >= 0 && lastRowIndex >= 0 && firstColumnIndex >= 0 && lastColumnIndex >= 0) {
this.firstRowIndex = firstRowIndex;
this.lastRowIndex = lastRowIndex;
this.firstColumnIndex = firstColumnIndex;
this.lastColumnIndex = lastColumnIndex;
} else {
throw new IllegalArgumentException("All parameters must be greater than 0");
}
}
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
if (cell.getRowIndex() == this.firstRowIndex && cell.getColumnIndex() == this.firstColumnIndex) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(this.firstRowIndex, this.lastRowIndex, this.firstColumnIndex, this.lastColumnIndex);
sheet.addMergedRegionUnsafe(cellRangeAddress);
}
}
}
首先,我们要重构类方法和重构merge方法,重构类方法一般是用来做数据处理和数据采集,将采集到的数据供merge方法使用。好像这里,它就是将要合并的行数以及列记录下来,再拿去merge去判断是否需要合并。
然后,merge方法是在写excel表时执行的,所以它这里入参有sheet(哪个sheet页)和cell(单元格),cell这里有重点说一下,EasyExcel写excel表时是一个一个单元格去写的,如这次进merge写的是A1单元格,下次进merge写的是A2单元格,所以merge是每一个单元格写的时候都会执行一次的。(merge会执行多次哦,别写循环了,很容易死循环的。)
说完源码,来看看我写的合并策略
public class OrderAbsoluteMergeStrategy extends AbstractMergeStrategy {
private List<Integer> colMergeList;
//<行号,往下数量>
private Map