完整解决方案
1. 在 Excel
注解中添加 groups
属性
修改 com.dataview.common.annotation.Excel
注解类,添加 groups
属性:
public @interface Excel {
// 其他属性...
Class<?>[] groups() default {}; // 新增分组属性
}
[ 在 createExcelField
方法中接收分组参数]
修改 createExcelField
,使其接收分组参数并传递给 getFields
。
private void createExcelField(Class<?>... groups) {
this.fields = getFields(groups);
this.fields = this.fields.stream()
.sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort()))
.collect(Collectors.toList());
this.maxHeight = getRowHeight();
}
[ 在 exportExcel
方法中添加分组参数]
修改 exportExcel
方法,允许传入分组参数。
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title, Class<?>... groups) {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, Type.EXPORT);
this.createExcelField(groups); // 传入分组参数
exportExcel(response);
}
2. 修改 ExcelUtil
工具类的字段过滤逻辑
在 ExcelUtil.java
的 getFields
方法中,添加分组过滤逻辑:
// ExcelUtil.java 部分关键修改
public class ExcelUtil<T> {
// ... 其他代码不变
/**
* 获取字段注解信息(支持分组过滤)
*/
public List<Object[]> getFields(Class<?>... groups) {
List<Object[]> fields = new ArrayList<>();
List<Field> tempFields = new ArrayList<>();
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
for (Field field : tempFields) {
if (!ArrayUtils.contains(this.excludeFields, field.getName())) {
// 单注解处理
if (field.isAnnotationPresent(Excel.class)) {
Excel attr = field.getAnnotation(Excel.class);
// 检查分组是否匹配
boolean groupMatch = (groups.length == 0) ||
Arrays.stream(attr.groups()).anyMatch(g -> Arrays.asList(groups).contains(g));
if (attr != null && (attr.type() == Type.ALL || attr.type() == type) && groupMatch) {
field.setAccessible(true);
fields.add(new Object[] { field, attr });
}
// 处理集合字段...
}
// 多注解处理(略,需类似逻辑)
}
}
return fields;
}
/**
* 初始化字段(支持分组)
*/
private void createExcelField(Class<?>... groups) {
this.fields = getFields(groups);
this.fields = this.fields.stream()
.sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort()))
.collect(Collectors.toList());
this.maxHeight = getRowHeight();
}
/**
* 导出Excel(新增分组参数)
*/
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title, Class<?>... groups) {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, Type.EXPORT);
this.createExcelField(groups); // 传入分组参数
exportExcel(response);
}
// ... 其他方法保持不变
}
3. 在实体类中使用 groups
属性
在 OutboundAmount.java
中为字段指定分组:
public class OutboundAmount extends BaseEntity {
// TOB 导出字段
@Excel(name = "日期", groups = {TobExport.class})
private String dayTime;
@Excel(name = "用户ID", groups = {TobExport.class, TocExport.class})
private String customerid;
@Excel(name = "销售金额", groups = {TobExport.class})
private BigDecimal zje;
// TOC 导出字段
@Excel(name = "打包箱数", groups = {TocExport.class})
private Integer packagBox;
// 定义分组类
public static class TobExport {}
public static class TocExport {}
}
4. 在控制器中调用分组导出
在 OutboundAmountController.java
中指定分组参数:
@PostMapping("/exportb")
public void exportb(
HttpServletResponse response,
@RequestParam(required = false) List<String> customerid,
OutboundAmount outboundAmount,
@RequestParam(required = false) Long[] ids
) {
// ... 数据查询逻辑
ExcelUtil<OutboundAmount> util = new ExcelUtil<>(OutboundAmount.class);
util.exportExcel(response, listb, "出库金额数据(TOB)", "TOB报表", OutboundAmount.TobExport.class);
}
@PostMapping("/exportc")
public void exportc(
HttpServletResponse response,
@RequestParam(required = false) List<String> customerid,
OutboundAmount outboundAmount,
@RequestParam(required = false) Long[] ids
) {
// ... 数据查询逻辑
ExcelUtil<OutboundAmount> util = new ExcelUtil<>(OutboundAmount.class);
util.exportExcel(response, listc, "出库金额数据(TOC)", "TOC报表", OutboundAmount.TocExport.class);
}
验证步骤
-
编译项目:确保所有修改后的代码编译通过。
-
导出测试:
-
调用
/exportb
接口,导出的 Excel 应仅包含日期
、用户ID
、销售金额
。 -
调用
/exportc
接口,导出的 Excel 应仅包含用户ID
、打包箱数
。
-
-
无分组测试:不传分组参数时,导出所有
@Excel
注解字段。
注意事项
-
注解同步更新:确保所有使用
@Excel
注解的字段都已正确添加groups
属性。 -
兼容性:旧代码若无分组参数,默认导出所有字段。
补充:
导出报表的title会合并所有添加了@Excel注解的字段对应数量的单元格,如果使用分组筛选出字段的话,导出的excel会对出几个单元格
修改方法:
删除title(不使用title)对应代码修改如下:
// 导出 Excel
ExcelUtil<OutboundAmount> util = new ExcelUtil<>(OutboundAmount.class);
util.exportExcel(response, listc, "出库金额数据(TOC)", OutboundAmount.TocExport.class);
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, Class<?>... groups) {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, Type.EXPORT);
this.createExcelField(groups); // 传入分组参数
exportExcel(response);
}