说明:此文章是对ruoyi分离版后台功能,导出excel文件,导出对象的子列表的补充
若依文档:
导出文件结果
:::color4
补充文档场景:
如上图所示,角色中的字段“角色编号”,“角色名称”,“角色字符”作为子集填充到用户中,改变角色子集的显示顺序,将子集放到“用户名称”和“邮箱”中间时,导出的文件为空
:::
在自定义注解 Excel 中添加字段
/**
* 是否需要合并行 与 needMerge 以及 子列表不兼容
*/
public boolean lineMerge() default false;
/**
* 合并行的依据的主键
*/
public boolean lineMergeId() default false;
修改 ExcelUtil.fillExcelData方法
public void fillExcelData(int index, Row row) {
int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size());
int rowNo = (1 + rownum) - startNo;
String objIdValve = "";//注解中 lineMergeId 为true的value 合并单元格使用
int mergeStartRow = 0;//合并单元格 起始行
for (int i = startNo; i < endNo; i++) {
rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo;
row = sheet.createRow(rowNo);
// 得到导出对象.
T vo = (T) list.get(i);
Collection<?> subList = null;
if (isSubList()) {
if (isSubListValue(vo)) {
subList = getListCellValue(vo);
subMergedLastRowNum = subMergedLastRowNum + subList.size();
} else {
subMergedFirstRowNum++;
subMergedLastRowNum++;
}
}
int column = 0;
boolean mergeCells = false;//合并单元格 当前单元格是否需要合并
for (Object[] os : fields) {
Field field = (Field) os[0];
Excel excel = (Excel) os[1];
/**
* 合并单元格判断条件处理
*/
if (excel.lineMergeId()) {
try {
Object value = getTargetValue(vo, field, excel);
if (!objIdValve.equals(value.toString())) {
objIdValve = value.toString();
mergeCells = false;
mergeStartRow = rowNo;
} else {
mergeCells = true;
}
} catch (Exception e) {
log.error("合并单元格导出主键获取失败,导出Excel失败{}", e);
}
}
if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) {
boolean subFirst = false;
for (Object obj : subList) {
if (subFirst) {
rowNo++;
row = sheet.createRow(rowNo);
}
List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class);
int subIndex = 0;
for (Field subField : subFields) {
if (subField.isAnnotationPresent(Excel.class)) {
subField.setAccessible(true);
Excel attr = subField.getAnnotation(Excel.class);
this.addCell(attr, row, (T) obj, subField, column + subIndex);
}
subIndex++;
}
subFirst = true;
}
this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size();
} else {
this.addCell(excel, row, vo, field, column++);
}
/**
* 合并单元格操作
*/
if (excel.lineMerge() && mergeCells) {
if (rowNo - mergeStartRow > 1) {
List<CellRangeAddress> cellList = new ArrayList<>(sheet.getMergedRegions());
for (int i1 = 0; i1 < cellList.size(); i1++) {
CellRangeAddress ca = cellList.get(i1);
if (mergeStartRow == ca.getFirstRow() && rowNo - 1 == ca.getLastRow() && column - 1 == ca.getFirstColumn() && column - 1 == ca.getLastColumn()) {
sheet.removeMergedRegion(i1);
}
}
}
sheet.addMergedRegion(new CellRangeAddress(mergeStartRow, rowNo, column - 1, column - 1));
}
}
}
}
具体使用方式
在用户编号 @Excel注解中添加 lineMergeId = true,合并单元格的行以此为合并依据,没有此标记则不会执行合并单元格
在需要合并的列中的@Excel注解中添加 lineMerge = true
注:自定义注解 Excel中原有 needMerge字段 以及 ExcelUtil中的子列表不兼容
@Data
public class SysUser{
@Excel(name = "用户编号", lineMergeId = true, width = 20, lineMerge = true)
private String userId;
@Excel(name = "用户名称", width = 20, lineMerge = true)
private String userName;
@Excel(name = "邮箱", width = 20, lineMerge = true)
private String email;
@Excel(name = "角色编号")
private String roleId;
@Excel(name = "角色名称")
private String roleName;
@Excel(name = "角色字符")
private String roleKey;
}