227 lines
6.8 KiB
Markdown
227 lines
6.8 KiB
Markdown
|
|
# EasyExcel字典下拉框使用说明
|
|||
|
|
|
|||
|
|
## 功能概述
|
|||
|
|
|
|||
|
|
本项目实现了EasyExcel自定义WriteHandler拦截器,可以在生成Excel模板时自动添加基于若依框架字典数据的下拉框。
|
|||
|
|
|
|||
|
|
## 核心组件
|
|||
|
|
|
|||
|
|
### 1. @DictDropdown 注解
|
|||
|
|
|
|||
|
|
位置:`com.ruoyi.common.annotation.DictDropdown`
|
|||
|
|
|
|||
|
|
用于标注需要添加下拉框的字段。
|
|||
|
|
|
|||
|
|
**属性说明:**
|
|||
|
|
| 属性 | 类型 | 默认值 | 说明 |
|
|||
|
|
|-----|------|--------|------|
|
|||
|
|
| dictType | String | 必填 | 字典类型编码,对应若依字典管理中的字典类型 |
|
|||
|
|
| displayType | DisplayType | LABEL | 下拉框显示内容类型(LABEL:显示标签,VALUE:显示值) |
|
|||
|
|
| strict | boolean | true | 是否仅允许选择下拉框中的值 |
|
|||
|
|
| hiddenSheetName | String | "dict_hidden" | 隐藏Sheet名称(用于存储大量下拉选项) |
|
|||
|
|
|
|||
|
|
### 2. DictDropdownWriteHandler 处理器
|
|||
|
|
|
|||
|
|
位置:`com.ruoyi.dpc.handler.DictDropdownWriteHandler`
|
|||
|
|
|
|||
|
|
核心功能:
|
|||
|
|
- 解析实体类中的@DictDropdown注解
|
|||
|
|
- 从若依字典缓存获取字典数据
|
|||
|
|
- 为对应列添加下拉框验证
|
|||
|
|
- 自动处理下拉选项超过Excel字符限制的情况(使用隐藏Sheet)
|
|||
|
|
|
|||
|
|
### 3. EasyExcelUtil 工具类扩展
|
|||
|
|
|
|||
|
|
位置:`com.ruoyi.dpc.utils.EasyExcelUtil`
|
|||
|
|
|
|||
|
|
新增方法:
|
|||
|
|
- `importTemplateWithDictDropdown()` - 下载带字典下拉框的导入模板
|
|||
|
|
- `exportExcelWithDictDropdown()` - 导出带字典下拉框的Excel
|
|||
|
|
|
|||
|
|
## 使用示例
|
|||
|
|
|
|||
|
|
### 步骤1:在实体类上添加注解
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
package com.ruoyi.dpc.domain.excel;
|
|||
|
|
|
|||
|
|
import com.alibaba.excel.annotation.ExcelProperty;
|
|||
|
|
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
|||
|
|
import com.ruoyi.common.annotation.DictDropdown;
|
|||
|
|
import lombok.Data;
|
|||
|
|
|
|||
|
|
@Data
|
|||
|
|
public class DpcEmployeeExcel {
|
|||
|
|
|
|||
|
|
@ExcelProperty(value = "姓名", index = 0)
|
|||
|
|
@ColumnWidth(15)
|
|||
|
|
private String name;
|
|||
|
|
|
|||
|
|
@ExcelProperty(value = "柜员号", index = 1)
|
|||
|
|
@ColumnWidth(15)
|
|||
|
|
private String tellerNo;
|
|||
|
|
|
|||
|
|
// 添加字典下拉框注解
|
|||
|
|
@ExcelProperty(value = "状态", index = 6)
|
|||
|
|
@ColumnWidth(10)
|
|||
|
|
@DictDropdown(dictType = "dpc_employee_status")
|
|||
|
|
private String status;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 步骤2:在Controller中使用
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@RestController
|
|||
|
|
@RequestMapping("/dpc/employee")
|
|||
|
|
public class DpcEmployeeController {
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 下载带字典下拉框的导入模板
|
|||
|
|
*/
|
|||
|
|
@PostMapping("/importTemplateWithDropdown")
|
|||
|
|
public void importTemplateWithDropdown(HttpServletResponse response) {
|
|||
|
|
EasyExcelUtil.importTemplateWithDictDropdown(
|
|||
|
|
response,
|
|||
|
|
DpcEmployeeExcel.class,
|
|||
|
|
"员工信息"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 导出带字典下拉框的Excel
|
|||
|
|
*/
|
|||
|
|
@PostMapping("/exportWithDropdown")
|
|||
|
|
public void exportWithDropdown(HttpServletResponse response) {
|
|||
|
|
List<DpcEmployeeExcel> list = employeeService.selectEmployeeList();
|
|||
|
|
EasyExcelUtil.exportExcelWithDictDropdown(
|
|||
|
|
response,
|
|||
|
|
list,
|
|||
|
|
DpcEmployeeExcel.class,
|
|||
|
|
"员工信息"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 高级用法
|
|||
|
|
|
|||
|
|
### 1. 显示字典键值而非标签
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@DictDropdown(dictType = "dpc_employee_status", displayType = DisplayType.VALUE)
|
|||
|
|
private String status;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 允许手动输入(非严格模式)
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@DictDropdown(dictType = "dpc_employee_status", strict = false)
|
|||
|
|
private String status;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 自定义隐藏Sheet名称
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@DictDropdown(dictType = "dpc_employee_status", hiddenSheetName = "employee_status_dict")
|
|||
|
|
private String status;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **必须指定@ExcelProperty的index属性**
|
|||
|
|
- 字段必须指定@ExcelProperty注解的index值,否则无法正确映射列位置
|
|||
|
|
|
|||
|
|
2. **字典数据必须预先加载到缓存**
|
|||
|
|
- 使用前需要确保字典数据已经加载到Redis缓存中
|
|||
|
|
- 可通过若依系统的字典管理功能预热缓存
|
|||
|
|
|
|||
|
|
3. **下拉选项数量限制**
|
|||
|
|
- 当下拉选项总长度超过255字符时,自动使用隐藏Sheet存储
|
|||
|
|
- 隐藏Sheet在Excel中不可见,但下拉框功能正常
|
|||
|
|
|
|||
|
|
4. **字段必须标注@ExcelProperty注解**
|
|||
|
|
- 只有同时标注了@ExcelProperty和@DictDropdown的字段才会添加下拉框
|
|||
|
|
|
|||
|
|
## 测试验证
|
|||
|
|
|
|||
|
|
### 接口测试
|
|||
|
|
|
|||
|
|
1. 启动项目后,访问Swagger UI:`http://localhost:8080/swagger-ui/index.html`
|
|||
|
|
|
|||
|
|
2. 找到员工信息管理相关接口:
|
|||
|
|
- `POST /dpc/employee/importTemplateWithDropdown` - 下载带字典下拉框的模板
|
|||
|
|
|
|||
|
|
3. 调用接口下载模板,检查Excel中的下拉框是否正常
|
|||
|
|
|
|||
|
|
### 手动验证
|
|||
|
|
|
|||
|
|
1. 打开下载的Excel模板
|
|||
|
|
2. 点击标注了下拉框的列(如"状态"列)
|
|||
|
|
3. 检查是否出现下拉箭头和选项列表
|
|||
|
|
4. 尝试选择和输入,验证验证规则是否生效
|
|||
|
|
|
|||
|
|
## 技术实现细节
|
|||
|
|
|
|||
|
|
### Excel下拉列表限制处理
|
|||
|
|
|
|||
|
|
Excel对下拉列表的直接字符数有限制(约255字符),本项目采用以下策略:
|
|||
|
|
|
|||
|
|
1. **选项较少时(<255字符)**
|
|||
|
|
- 直接使用 `DataValidationHelper.createExplicitListConstraint()` 创建下拉列表
|
|||
|
|
- 下拉选项内联在单元格验证中
|
|||
|
|
|
|||
|
|
2. **选项较多时(≥255字符)**
|
|||
|
|
- 创建隐藏Sheet存储所有选项
|
|||
|
|
- 使用 `DataValidationHelper.createFormulaListConstraint()` 通过公式引用
|
|||
|
|
- 自动隐藏Sheet(`workbook.setSheetHidden()`)
|
|||
|
|
|
|||
|
|
### 字典数据获取
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────┐ 缓存查询 ┌─────────────┐
|
|||
|
|
│ DictDropdown │ ───────────▶ │ DictUtils │
|
|||
|
|
│ 注解 │ │ .getDictCache() │
|
|||
|
|
└─────────────┘ └─────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────┐
|
|||
|
|
│ Redis缓存 │
|
|||
|
|
│ sys_dict:key │
|
|||
|
|
└─────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 列索引映射
|
|||
|
|
|
|||
|
|
通过反射获取字段的@ExcelProperty注解中的index值,确保下拉框添加到正确的列。
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### Q1:下拉框没有显示?
|
|||
|
|
|
|||
|
|
**可能原因:**
|
|||
|
|
1. 字典数据未加载到缓存
|
|||
|
|
2. 字段未指定@ExcelProperty的index值
|
|||
|
|
3. 字典类型编码错误
|
|||
|
|
|
|||
|
|
**解决方法:**
|
|||
|
|
1. 在若依系统字典管理中,进入对应字典类型,刷新缓存
|
|||
|
|
2. 检查实体类字段注解是否正确
|
|||
|
|
3. 确认dictType值与字典管理中的字典类型一致
|
|||
|
|
|
|||
|
|
### Q2:下拉选项显示不完整?
|
|||
|
|
|
|||
|
|
**原因:** 选项字符数超过255字符,但隐藏Sheet创建失败
|
|||
|
|
|
|||
|
|
**解决方法:** 检查日志中的错误信息,确保有权限创建隐藏Sheet
|
|||
|
|
|
|||
|
|
### Q3:可以手动输入非下拉选项的值吗?
|
|||
|
|
|
|||
|
|
**答案:** 可以,通过设置 `strict = false` 允许手动输入
|
|||
|
|
|
|||
|
|
## 更新日志
|
|||
|
|
|
|||
|
|
| 版本 | 日期 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 1.0.0 | 2026-01-29 | 初始版本,支持字典下拉框功能 |
|