1. 程式人生 > 其它 >Poi(二)- excel新增多級選單級聯候選框

Poi(二)- excel新增多級選單級聯候選框

技術標籤:poijavaexcelpoi

1 級聯(多級選單)excel是怎麼新增的

  • 1 先說一下資料
    在這裡插入圖片描述
    第一行 parent 所有的第一層父級選單(遼,吉,黑)
    剩下的每一行,都是一個父級資料對應它所包含的子集(比如:遼{大連,瀋陽})
    另外,第一列為所有有子集的父級(遼,吉,黑,大連,瀋陽)
  • 2 然後給建立名稱管理器,選中公式->名稱管理器,新建,名稱就是每行首列的值,引用位置就選則當前行除了首列的其餘列
  • 3 新建另一個sheet頁,選中某一列(比如說A )的單元格(一級選單),選擇資料->資料驗證,條件 選擇序列,來源輸入=parent
  • 4 選中下一列(B)的單元格(二級選單)選擇資料->資料驗證,條件 選擇序列,來源輸入=INDIRECT(A1)
  • 5 如果多級選單以此類推,具體可以參考如下的動圖
    在這裡插入圖片描述

2 java程式碼怎麼插入級聯(多級選單)

核心程式碼

public static void cascade(final Workbook workbook, final List<String> mainParent, final List<String> allParent,
            final Map<String, List<String>> children,
            final ArrayList<Integer> columns, Sheet sheet,
final int startRow, final int endRow) { String hideSheetName = "area"; while (workbook.getSheet(hideSheetName) != null) { hideSheetName = hideSheetName + new Random().nextInt(100); } final Sheet hideSheet = workbook.createSheet(hideSheetName)
; //這一行作用是將此sheet隱藏 workbook.setSheetHidden(workbook.getSheetIndex(hideSheet), true); int rowId = 0; // 設定第一行,存省的資訊 final String parentNameKey = "parent"; final Row provinceRow = hideSheet.createRow(rowId++); provinceRow.createCell(0).setCellValue(parentNameKey); for (int i = 0; i < mainParent.size(); i++) { final Cell provinceCell = provinceRow.createCell(i + 1); provinceCell.setCellValue(mainParent.get(i)); } // 新增父級別的名稱管理器 final String parentRange = EasyPoiCascadeUtil.getRange(1, rowId, mainParent.size()); final Name parentName = workbook.createName(); //key不可重複 parentName.setNameName(parentNameKey); final String parentFormula = hideSheetName + "!" + parentRange; parentName.setRefersToFormula(parentFormula); // 將具體的資料寫入到每一行中,行開頭為父級區域,後面是子區域。 for (final String key : allParent) { final String[] son = children.get(key).toArray(new String[1]); final Row row = hideSheet.createRow(rowId++); row.createCell(0).setCellValue(key); for (int j = 0; j < son.length; j++) { final Cell cell = row.createCell(j + 1); cell.setCellValue(son[j]); } // 新增名稱管理器 final String range = EasyPoiCascadeUtil.getRange(1, rowId, son.length); final Name name = workbook.createName(); //key不可重複 name.setNameName(key); final String formula = hideSheetName + "!" + range; System.out.println(formula); name.setRefersToFormula(formula); } if (sheet.getSheetName().equals(hideSheetName)) { return; } final XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper((XSSFSheet) sheet); //最外層的規則 載入資料,將名稱為hidden的sheet中的資料轉換為List形式 final XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint(parentNameKey); // 四個引數分別是:起始行、終止行、起始列、終止列 final CellRangeAddressList provRangeAddressList = new CellRangeAddressList(startRow, endRow, columns.get(0), columns.get(0)); final XSSFDataValidation provinceDataValidation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, provRangeAddressList); //驗證 provinceDataValidation.createErrorBox("error", "請選擇正確的資料"); provinceDataValidation.setShowErrorBox(true); provinceDataValidation.setSuppressDropDownArrow(true); sheet.addValidationData(provinceDataValidation); for (int j = 0; j < (columns.size() - 1); j++) { final String column = EasyPoiCascadeUtil.getColumn(columns.get(j)); EasyPoiCascadeUtil.setDataValidation(column, (XSSFSheet) sheet, startRow, endRow, columns.get(j + 1)); } } /** * 載入下拉列表內容 * * @param formulaString * @param naturalRowIndex * @param naturalColumnIndex * @param dvHelper * @return */ private static DataValidation getDataValidationByFormula( final String formulaString, final int firstRow, final int lastRow, final int naturalColumnIndex, final XSSFDataValidationHelper dvHelper) { // 載入下拉列表內容 // 舉例:若formulaString = "INDIRECT($A$2)" 表示規則資料會從名稱管理器中獲取key與單元格 A2 值相同的資料, //如果A2是江蘇省,那麼此處就是江蘇省下的市資訊。 final XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint(formulaString); // 設定資料有效性載入在哪個單元格上。 // 四個引數分別是:起始行、終止行、起始列、終止列 final CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, naturalColumnIndex, naturalColumnIndex); // 資料有效性物件 // 繫結 final XSSFDataValidation data_validation_list = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, regions); data_validation_list.setEmptyCellAllowed(false); if (data_validation_list instanceof XSSFDataValidation) { data_validation_list.setSuppressDropDownArrow(true); data_validation_list.setShowErrorBox(true); } else { data_validation_list.setSuppressDropDownArrow(false); } // 設定輸入資訊提示資訊 data_validation_list.createPromptBox("下拉選擇提示", "請使用下拉方式選擇合適的值!"); return data_validation_list; } /** * 設定有效性 * * @param offset 主影響單元格所在列,即此單元格由哪個單元格影響聯動 * @param sheet * @param rowNum 行數 * @param colNum 列數 */ public static void setDataValidation(final String offset, final XSSFSheet sheet, final int startRow, final int endRow, final int colNum) { final XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet); DataValidation data_validation_list; data_validation_list = EasyPoiCascadeUtil.getDataValidationByFormula( "INDIRECT($" + offset + (2) + ")", startRow, endRow, colNum, dvHelper); sheet.addValidationData(data_validation_list); } /** * 計算formula * * @param offset 偏移量,如果給0,表示從A列開始,1,就是從B列 * @param rowId 第幾行 * @param colCount 一共多少列 * @return 如果給入1,1,10. 表示從B1-K1。最終返回 $B$1:$K$1 */ public static String getRange(final int offset, final int rowId, final int colCount) { return "$" + EasyPoiCascadeUtil.getColumn(offset) + "$" + rowId + ":$" + EasyPoiCascadeUtil.getColumn(((offset + colCount) - 1)) + "$" + rowId; } //根據輸入的數字,轉換成excel中相應的列,0->A, 26->AA public static String getColumn(int col) { if (col < 0) { return null; } String columnStr = ""; do { if (columnStr.length() > 0) { col--; } columnStr = ((char) ((col % 26) + 'A')) + columnStr; col = col / 26; } while (col > 0); return columnStr; }

完整程式碼實際例子參考 cascade包
https://github.com/ws378894183/hope/tree/master/easypoi-validation