背景:由于需要下载模板,模板包含下拉选择框,但是下拉选择框不想手写,并且需要从数据库读取,由于直接设置excel会有单元格最大255个字符长度限制,所以用到以下部分代码。
思路:由于数据模板在sheet1,所以将数据库数据读取,写到sheet2里第一行第一列,然后开启数据验证,选取数据列指向sheet1的下拉列表列位置,最后隐藏sheet2页。
实现:
@Value(value = "${spring.importTemplateFileLocation}")private String importTemplateFileLocation;@GetMapping("/loadTemplateFile")
@Operation(summary = "下载项目导入模板")
public void loadTemplateFile(HttpServletResponse response) {demoService.loadTemplateFile(response);
}
@Overridepublic void loadTemplateFile(HttpServletResponse response) {response.setContentType("application/vnd.ms-excel.sheet.macroEnabled.12");response.setCharacterEncoding("utf-8");Workbook wb = null;ServletOutputStream out = null;try (InputStream in = this.getClass().getResourceAsStream(importTemplateFileLocation)) {out = response.getOutputStream();wb = new XSSFWorkbook(in);// 获取第一个sheetSheet sheet = wb.getSheetAt(0);// 获取第二个sheetSheet sheet2 = wb.getSheetAt(1);// 获取第二个sheet的第一行第一列int auxColIndex = 0;// 获取第二个sheet的第一行第一列int auxRowIndex = 0;//查询数据库数据List<String> dataList = new ArrayList<>(););});//将下拉数据写入sheet2for (String option : dataList ) {Row auxRow = sheet2.createRow(auxRowIndex++);Cell auxCell = auxRow.createCell(auxColIndex);auxCell.setCellValue(option);}//数据验证选取范围String dataRange = new CellReference(0, auxColIndex, false, false).formatAsString() + ":" +new CellReference(leafCategoryList.size() - 1, auxColIndex, false, false).formatAsString();// 数据验证DataValidationHelper dvHelper = new XSSFDataValidationHelper((XSSFSheet) sheet);// 加载下拉列表内容DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint("INDIRECT(\"" + sheet2.getSheetName() + "!" + dataRange + "\")");// 加载下拉列表验证区域CellRangeAddressList addressList = new CellRangeAddressList(1, 65535, 1, 1); // 假设列 B(1, 1)// 数据有效性对象DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);validation.setSuppressDropDownArrow(true);validation.setShowErrorBox(true);sheet.addValidationData(validation);List<String> programTypeList = new ArrayList<>();dictDataApi.getAllData("program_type").getData().forEach(data -> {programTypeList.add(data.getLabel() + ":" + data.getValue());});String[] programTypeArr = new String[programTypeList.size()];programTypeList.toArray(programTypeArr);ExcelUtils.setValidationData(wb.getSheetAt(0), 1, 65535, 4, 4, programTypeArr);//隐藏sheet2页wb.setSheetHidden(wb.getSheetIndex(sheet2), true);wb.write(out);} catch (Exception e) {log.error(e.toString());} finally {IOUtils.closeQuietly(wb);IOUtils.closeQuietly(out);}}
效果: