之前也有写过EasyExcel的文章,这次大致整合一下常用功能,并升级到了2.2.6的版本,模板实体无需再继承BaseRowModel,先构建Springboot项目再引入easyExcel相关的依赖,项目中其它的依赖就不贴出来了,主要是swagger和mybatisplus那些,之前的文章中也有写过
com.alibaba
easyexcel
2.2.6
简单编写一个Excel的工具类EasyExcelUtil
/**
* EasyExcel工具类
*
* @author: YuanXing on 2020/12/03
*/
public class EasyExcelUtil {
/**
* 读取 Excel(多个 sheet)
*
* @param excel 文件
* @param rowModel 实体类映射
* @return Excel 数据 list
*/
public static List
单元格合并处理器ExcelFillCellMergeHandler
/**
* 合并单元格处理类
*
* @author: YuanXing on 2020/12/23
*/
public class ExcelFillCellMergeHandler implements CellWriteHandler {
//需要合并的列
private int[] mergeColumnIndex;
//从哪一列开始合并
private int mergeRowIndex;
public ExcelFillCellMergeHandler() {
}
public ExcelFillCellMergeHandler(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
int curRowIndex = cell.getRowIndex();
int curColIndex = cell.getColumnIndex();
if (curRowIndex > mergeRowIndex) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}
/**
* 当前单元格向上合并
*
* @param writeSheetHolder
* @param cell 当前单元格
* @param curRowIndex 当前行
* @param curColIndex 当前列
*/
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
// 将当前单元格数据与上一个单元格数据比较
Boolean dataBool = preData.equals(curData);
Boolean bool = cell.getRow().getCell(0).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue());
if (dataBool && bool) {
Sheet sheet = writeSheetHolder.getSheet();
List mergeRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergeRegions.get(i);
// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
sheet.removeMergedRegion(i);
cellRangeAddr.setLastRow(curRowIndex);
sheet.addMergedRegion(cellRangeAddr);
isMerged = true;
}
}
// 若上一个单元格未被合并,则新增合并单元
if (!isMerged) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}
}
读取Excel数据的监听器ExcelListener
/**
* 解析监听器,
* 每解析一行会回调invoke()方法。
* 整个excel解析结束会执行doAfterAllAnalysed()方法
*
* @author: YuanXing on 2020/12/03
*/
public class ExcelListener extends AnalysisEventListener {
private List
准备一个实体ExcelSysUser
@ContentRowHeight(25)
@HeadRowHeight(15)
@ColumnWidth(25)
@HeadFontStyle(fontHeightInPoints=9)
@ContentStyle(horizontalAlignment= HorizontalAlignment.CENTER)
@Data
public class ExcelSysUser {
public ExcelSysUser(){
}
public ExcelSysUser(String loginName, String userName, String userPwd){
this.loginName = loginName;
this.userName = userName;
this.userPwd = userPwd;
}
@ExcelProperty(value = "登录名",index = 0)
private String loginName;
@ExcelProperty(value = "用户名",index = 1)
private String userName;
@ExcelProperty(value = "密码",index = 2)
private String userPwd;
}
编写EasyExcelLoadsController来测试功能
@Api(tags = {"Excel导出管理"})
@RestController
@RequestMapping("/excel")
public class EasyExcelLoadsController {
@Autowired
private SysUserMapper sysUserMapper;
/**
* 用户信息导出Excel
*/
@ApiOperation(value="用户信息导出")
@RequestMapping(value = "/exportSysUser",method = RequestMethod.GET)
public void exportSysUser(HttpServletResponse response){
QueryWrapper queryWrapper = null;
List sysUsers = sysUserMapper.selectList(queryWrapper);
if (sysUsers != null && sysUsers.size() > 0){
List excelSysUsers = sysUsers.stream().map(sysUser -> {
ExcelSysUser excelSysUser = new ExcelSysUser();
excelSysUser.setLoginName(sysUser.getLoginName());
excelSysUser.setUserName(sysUser.getUserName());
excelSysUser.setUserPwd(sysUser.getUserPwd());
return excelSysUser;
}).collect(Collectors.toList());
EasyExcelUtil.writeExcel(response, excelSysUsers,"用户信息","用户信息", new ExcelSysUser());
}
}
/**
* 用户信息导出Excel(合并单元格)
*/
@ApiOperation(value="用户信息导出(合并单元格)")
@RequestMapping(value = "/exportMergeSysUser",method = RequestMethod.GET)
public void exportMergeSysUser(HttpServletResponse response){
List excelSysUsers = new ArrayList<>();
ExcelSysUser excelSysUser1 = new ExcelSysUser("张三", "zhangsan002", "zsmm123");
ExcelSysUser excelSysUser2 = new ExcelSysUser("张三", "zhangsan003", "zsmm456");
ExcelSysUser excelSysUser3 = new ExcelSysUser("张三", "zhangsan001", "zsmm789");
ExcelSysUser excelSysUser4 = new ExcelSysUser("李四", "zhangsan001", "zsmm123");
ExcelSysUser excelSysUser5 = new ExcelSysUser("李四", "zhangsan001", "zsmm456");
excelSysUsers.add(excelSysUser1);
excelSysUsers.add(excelSysUser2);
excelSysUsers.add(excelSysUser3);
excelSysUsers.add(excelSysUser4);
excelSysUsers.add(excelSysUser5);
int[] mergeColumnIndex = {0,1};
int mergeRowIndex = 0;
EasyExcelUtil.writeMergeExcel(response, excelSysUsers,"用户信息","用户信息", new ExcelSysUser(), mergeColumnIndex, mergeRowIndex);
}
@ApiOperation(value="用户信息导入")
@RequestMapping(value = "/importSysUser",method = RequestMethod.POST)
public void importSysUser(MultipartFile excel){
List dataList = null;
try {
dataList = EasyExcelUtil.readExcel(excel, new ExcelSysUser());
} catch (IOException e) {
e.printStackTrace();
}
if (dataList!= null && dataList.size() > 0){
dataList.stream().map(o -> {
SysUser sysUser = new SysUser();
sysUser.setLoginName(((ExcelSysUser) o).getLoginName());
sysUser.setUserName(((ExcelSysUser) o).getUserName());
sysUser.setUserPwd(((ExcelSysUser) o).getUserPwd());
return sysUser;
}).forEach(sysUser -> {
sysUserMapper.insert(sysUser);
});
}
}
}
打开swagger地址来测试调用,准备一个有两个sheet的Excel测试导入接口,导出这里演示一下合并单元格的结果