【问题标题】:How to create a dependent drop down list using [Apache POI]如何使用 [Apache POI] 创建依赖下拉列表
【发布时间】:2018-12-03 05:32:24
【问题描述】:

在这里,我使用[Apache POI] 创建一个excel 模板,用户可以填写数据。在这两个下拉列表中。想要创建一个依赖于前一个单元格的下拉列表的下拉列表。 例如: 如果我在单元格 3 中选择蔬菜类别,“米饭、凝乳、牛奶”项目将出现在单元格 4 的相关下拉列表中。代码如下。

在这里收集数据

   List<InternetItemResponse> internetItems = internetItemService.getAllByHotelId(hotelId);
    if (CollectionUtils.isNotEmpty(internetItems)) {
    String[] itemsName = new String[internetItems.size()];
    String[] itemsCategory = new String[internetItems.size()];
    String itemName;
    String itemCategory;
    Map<String, Set<String>> categoryVsItemName = new HashMap<>();
    Set<String> itemList;
    for (int i = 0; i < internetItems.size(); i++) {
        InternetItemResponse itemResponse = internetItems.get(i);
        if (itemResponse != null) {
            itemCategory = itemResponse.getCategory();
            if (!StringUtils.isEmpty(itemCategory)) {
                itemsCategory[i] = itemCategory;
                itemName = itemResponse.getTitle();
                itemsName[i] = itemName;
                if (CollectionUtils.isEmpty(categoryVsItemName.get(itemCategory))) {
                    itemList = new HashSet<>();
                    itemList.add(itemName);
                    categoryVsItemName.put(itemCategory, itemList);
                } else {
                    categoryVsItemName.get(itemCategory).add(itemName);
                }
            }
        }
    }
}

在下拉列表中分配数据

// Setting drop down values
    for (int i = 0; i < headerColumns.length; i++) {
        if (i == 3) {
            XSSFDataValidationHelper mealdvHelper = new XSSFDataValidationHelper((XSSFSheet) sheet);
            XSSFDataValidationConstraint mealdvConstraint = (XSSFDataValidationConstraint) mealdvHelper
                    .createExplicitListConstraint(itemsCategory);
            // CellRangeAddressList(int firstRow, int lastRow, int firstCol, int lastCol)
            CellRangeAddressList addressListmeal = new CellRangeAddressList(1, 99, i, i);
            XSSFDataValidation categoryDataValidation = (XSSFDataValidation) mealdvHelper
                    .createValidation(mealdvConstraint, addressListmeal);
            categoryDataValidation.setShowErrorBox(true);
            categoryDataValidation.setSuppressDropDownArrow(true);
            categoryDataValidation.setShowPromptBox(true);
            sheet.addValidationData(categoryDataValidation);
        } else if (i == 4) {
            XSSFDataValidationHelper rmCategorydvHelper = new XSSFDataValidationHelper((XSSFSheet) sheet);
            XSSFDataValidationConstraint rmCategorydvConstraint = (XSSFDataValidationConstraint) rmCategorydvHelper
                    .createExplicitListConstraint(itemsName);
            CellRangeAddressList addressListrmCategory = new CellRangeAddressList(1, 99, i, i);
            XSSFDataValidation itemNameValidation = (XSSFDataValidation) rmCategorydvHelper
                    .createValidation(rmCategorydvConstraint, addressListrmCategory);
            itemNameValidation.setShowErrorBox(true);
            itemNameValidation.setSuppressDropDownArrow(true);
            itemNameValidation.setShowPromptBox(true);
            sheet.addValidationData(itemNameValidation);
        }
    }

【问题讨论】:

    标签: java excel apache-poi


    【解决方案1】:

    apache poi 无法做到创建相关下拉列表。 apache poi 库用于创建 Excel 文件。下拉列表的依赖关系必须在运行生成文件的Excels GUI 中管理。Apache poi 只能创建Excel 文件,这样才有可能。

    一种方法是为数据验证列表使用命名范围,然后使用INDIRECT 获取谁的名字。所以主列表包含依赖列表的命名范围的名称。并且依赖列表使用=INDIRECT([cell of main list])然后获取从主列表中选择名称的依赖列表。

    如何使用apache poi 创建它的示例:

    import java.io.FileOutputStream;
    
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import org.apache.poi.ss.util.*;
    
    import java.util.Map;
    import java.util.HashMap;
    
    class CreateExcelDependentDataValidationListsUsingNamedRanges {
    
     public static void main(String[] args) throws Exception {
    
       //some data
       Map<String, String[]> categoryItems = new HashMap<String, String[]>();
       categoryItems.put("Countries", new String[]{"France", "Germany", "Italy"});
       categoryItems.put("Capitals", new String[]{"Paris", "Berlin", "Rome"});
       categoryItems.put("Fruits", new String[]{"Apple", "Peach", "Banana", "Orange"});
    
       Workbook workbook = new XSSFWorkbook();
    
       //hidden sheet for list values
       Sheet sheet = workbook.createSheet("ListSheet");
    
       Row row;  
       Name namedRange;
       String colLetter;
       String reference;
    
       int c = 0;
       //put the data in
       for (String key : categoryItems.keySet()) {
        int r = 0;
        row = sheet.getRow(r); if (row == null) row = sheet.createRow(r); r++;
        row.createCell(c).setCellValue(key);
        String[] items = categoryItems.get(key);
        for (String item : items) {
         row = sheet.getRow(r); if (row == null) row = sheet.createRow(r); r++;
         row.createCell(c).setCellValue(item);
        }
        //create names for the item list constraints, each named from the current key
        colLetter = CellReference.convertNumToColString(c);
        namedRange = workbook.createName();
        namedRange.setNameName(key);
        reference = "ListSheet!$" + colLetter + "$2:$" + colLetter + "$" + r;
        namedRange.setRefersToFormula(reference);
        c++;
       }
    
       //create name for Categories list constraint
       colLetter = CellReference.convertNumToColString((c-1));
       namedRange = workbook.createName();
       namedRange.setNameName("Categories");
       reference = "ListSheet!$A$1:$" + colLetter + "$1";
       namedRange.setRefersToFormula(reference);
    
       //unselect that sheet because we will hide it later
       sheet.setSelected(false);
    
    
       //visible data sheet
       sheet = workbook.createSheet("Sheet1");
    
       sheet.createRow(0).createCell(0).setCellValue("Select Category");
       sheet.getRow(0).createCell(1).setCellValue("Select item from that category");
    
       sheet.setActiveCell(new CellAddress("A2"));
    
       sheet.autoSizeColumn(0);
       sheet.autoSizeColumn(1);
    
       //data validations
       DataValidationHelper dvHelper = sheet.getDataValidationHelper();
       //data validation for categories in A2:
       DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint("Categories");
       CellRangeAddressList addressList = new CellRangeAddressList(1, 1, 0, 0);            
       DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
       sheet.addValidationData(validation);
    
       //data validation for items of the selected category in B2:
       dvConstraint = dvHelper.createFormulaListConstraint("INDIRECT($A$2)");
       addressList = new CellRangeAddressList(1, 1, 1, 1);            
       validation = dvHelper.createValidation(dvConstraint, addressList);
       sheet.addValidationData(validation);
    
       //hide the ListSheet
       workbook.setSheetHidden(0, true);
       //set Sheet1 active
       workbook.setActiveSheet(1);
    
       FileOutputStream out = new FileOutputStream("CreateExcelDependentDataValidationListsUsingNamedRanges.xlsx");
       workbook.write(out);
       workbook.close();
       out.close();
    
     }
    }
    

    【讨论】:

      【解决方案2】:

      改进一点 - 使用 OFFSET 为任何 B 列工作

      
      import org.apache.poi.ss.usermodel.*;
      import org.apache.poi.xssf.usermodel.XSSFWorkbook;
      
      import org.apache.poi.ss.util.*;
      
      import java.util.Map;
      import java.util.HashMap;
      
      class CreateExcelDependentDataValidationListsUsingNamedRanges {
      
       public static void main(String[] args) throws Exception {
      
         //some data
         Map<String, String[]> categoryItems = new HashMap<String, String[]>();
         categoryItems.put("Countries", new String[]{"France", "Germany", "Italy"});
         categoryItems.put("Capitals", new String[]{"Paris", "Berlin", "Rome"});
         categoryItems.put("Fruits", new String[]{"Apple", "Peach", "Banana", "Orange"});
      
         Workbook workbook = new XSSFWorkbook();
      
         //hidden sheet for list values
         Sheet sheet = workbook.createSheet("ListSheet");
      
         Row row;  
         Name namedRange;
         String colLetter;
         String reference;
      
         int c = 0;
         //put the data in
         for (String key : categoryItems.keySet()) {
          int r = 0;
          row = sheet.getRow(r); if (row == null) row = sheet.createRow(r); r++;
          row.createCell(c).setCellValue(key);
          String[] items = categoryItems.get(key);
          for (String item : items) {
           row = sheet.getRow(r); if (row == null) row = sheet.createRow(r); r++;
           row.createCell(c).setCellValue(item);
          }
          //create names for the item list constraints, each named from the current key
          colLetter = CellReference.convertNumToColString(c);
          namedRange = workbook.createName();
          namedRange.setNameName(key);
          reference = "ListSheet!$" + colLetter + "$2:$" + colLetter + "$" + r;
          namedRange.setRefersToFormula(reference);
          c++;
         }
      
         //create name for Categories list constraint
         colLetter = CellReference.convertNumToColString((c-1));
         namedRange = workbook.createName();
         namedRange.setNameName("Categories");
         reference = "ListSheet!$A$1:$" + colLetter + "$1";
         namedRange.setRefersToFormula(reference);
      
         //unselect that sheet because we will hide it later
         sheet.setSelected(false);
      
      
         //visible data sheet
         sheet = workbook.createSheet("Sheet1");
      
         sheet.createRow(0).createCell(0).setCellValue("Select Category");
         sheet.getRow(0).createCell(1).setCellValue("Select item from that category");
      
         sheet.setActiveCell(new CellAddress("A2"));
      
         sheet.autoSizeColumn(0);
         sheet.autoSizeColumn(1);
      
         //data validations
         DataValidationHelper dvHelper = sheet.getDataValidationHelper();
         //data validation for categories in A2:
         DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint("Categories");
         CellRangeAddressList addressList = new CellRangeAddressList(1, 1, 0, 0);            
         DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
         sheet.addValidationData(validation);
      
         //data validation for items of the selected category in B2:
         dvConstraint = dvHelper.createFormulaListConstraint("INDIRECT(OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0,-1)) for any B column");
         addressList = new CellRangeAddressList(1, 1, 1, 1);            
         validation = dvHelper.createValidation(dvConstraint, addressList);
         sheet.addValidationData(validation);
      
         //hide the ListSheet
         workbook.setSheetHidden(0, true);
         //set Sheet1 active
         workbook.setActiveSheet(1);
      
         FileOutputStream out = new FileOutputStream("CreateExcelDependentDataValidationListsUsingNamedRanges.xlsx");
         workbook.write(out);
         workbook.close();
         out.close();
      
       }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-20
        • 1970-01-01
        • 1970-01-01
        • 2015-02-23
        • 2020-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-19
        相关资源
        最近更新 更多