# 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 CcdiEmployeeExcel { @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 = "ccdi_employee_status") private String status; } ``` ### 步骤2:在Controller中使用 ```java @RestController @RequestMapping("/ccdi/employee") public class CcdiEmployeeController { /** * 下载带字典下拉框的导入模板 */ @PostMapping("/importTemplateWithDropdown") public void importTemplateWithDropdown(HttpServletResponse response) { EasyExcelUtil.importTemplateWithDictDropdown( response, CcdiEmployeeExcel.class, "员工信息" ); } /** * 导出带字典下拉框的Excel */ @PostMapping("/exportWithDropdown") public void exportWithDropdown(HttpServletResponse response) { List list = employeeService.selectEmployeeList(); EasyExcelUtil.exportExcelWithDictDropdown( response, list, CcdiEmployeeExcel.class, "员工信息" ); } } ``` ## 高级用法 ### 1. 显示字典键值而非标签 ```java @DictDropdown(dictType = "ccdi_employee_status", displayType = DisplayType.VALUE) private String status; ``` ### 2. 允许手动输入(非严格模式) ```java @DictDropdown(dictType = "ccdi_employee_status", strict = false) private String status; ``` ### 3. 自定义隐藏Sheet名称 ```java @DictDropdown(dictType = "ccdi_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 /ccdi/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 | 初始版本,支持字典下拉框功能 |