定义下拉注解
@Target ( ElementType . FIELD)
@Retention ( RetentionPolicy . RUNTIME)
public @interface ExcelDropDown { String [ ] source ( ) default { } ; String sourceMethod ( ) default "" ; int firstRow ( ) default 1 ; int lastRow ( ) default 10000 ;
}
实现CellWriteHandler 接口
@Slf4j
public class DynamicDropDownHandler implements CellWriteHandler { private final ApplicationContext applicationContext; public DynamicDropDownHandler ( ApplicationContext applicationContext) { this . applicationContext = applicationContext; } @Override public void beforeCellCreate ( WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { } @Override public void afterCellCreate ( WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { Class clazz = writeSheetHolder. getClazz ( ) ; try { String fieldName = head. getFieldName ( ) ; Field field = clazz. getDeclaredField ( fieldName) ; ExcelDropDown dropDown = field. getAnnotation ( ExcelDropDown . class ) ; if ( dropDown != null ) { String [ ] source = dropDown. source ( ) ; if ( source. length == 0 ) { String method = dropDown. sourceMethod ( ) ; if ( null != method && ! "" . equals ( method) ) { source = applicationContext. getBean ( method, String [ ] . class ) ; } if ( source. length == 0 ) { return ; } } Sheet sheet = writeSheetHolder. getSheet ( ) ; Workbook workbook = sheet. getWorkbook ( ) ; String optionSheetName = fieldName+ "_options" ; Sheet optionsSheet = workbook. getSheet ( optionSheetName) ; if ( optionsSheet == null ) { optionsSheet = workbook. createSheet ( optionSheetName) ; workbook. setSheetHidden ( workbook. getSheetIndex ( optionsSheet) , true ) ; } int optionCol = 0 ; for ( int i = 0 ; i < source. length; i++ ) { Row row = optionsSheet. getRow ( i) ; if ( row == null ) { row = optionsSheet. createRow ( i) ; } row. createCell ( optionCol) . setCellValue ( source[ i] ) ; } String rangeName = "DROP_DOWN_" + fieldName. toUpperCase ( ) ; Name namedRange = workbook. getName ( rangeName) ; if ( namedRange == null ) { namedRange = workbook. createName ( ) ; namedRange. setNameName ( rangeName) ; } namedRange. setRefersToFormula ( String . format ( optionSheetName+ "!$A$1:$A$%d" , source. length) ) ; DataValidationHelper helper = sheet. getDataValidationHelper ( ) ; DataValidationConstraint constraint = helper. createFormulaListConstraint ( rangeName) ; int columnIndex = cell. getColumnIndex ( ) ; CellRangeAddressList addressList = new CellRangeAddressList ( 1 , 2 , columnIndex, columnIndex) ; DataValidation validation = helper. createValidation ( constraint, addressList) ; validation. setSuppressDropDownArrow ( true ) ; validation. setShowErrorBox ( true ) ; sheet. addValidationData ( validation) ; } } catch ( Exception e) { log. error ( e. getMessage ( ) ) ; } } @Override public void afterCellDispose ( WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List < CellData > cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { }
}
使用下载模板接口
public void downloadTemplate ( HttpServletResponse response) { try { response. setContentType ( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) ; response. setCharacterEncoding ( "utf-8" ) ; String fileName = URLEncoder . encode ( "模板" , "UTF-8" ) . replaceAll ( "\\+" , "%20" ) ; response. setHeader ( "Content-disposition" , "attachment;filename*=utf-8''" + fileName + ".xlsx" ) ; EasyExcel . write ( response. getOutputStream ( ) , ImportVo . class ) . autoCloseStream ( true ) . registerWriteHandler ( new DynamicDropDownHandler ( applicationContext) ) . sheet ( "Sheet" ) . doWrite ( Collections . singletonList ( Collections . emptyList ( ) ) ) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } }
实体类
public class ImportVo { @ExcelProperty ( value = "动态数据下拉" ) @ExcelDropDown ( sourceMethod = "getNameList" ) private String name; @ExcelProperty ( value = "性别" ) @ExcelDropDown ( source = { "男" , "女" } ) private String sex;
}