如何使用[Apache POI]创建从属下拉列表

时间:2018-12-03 05:32:25

标签: java excel apache-poi

在这里,我正在使用[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);
        }
    }

2 个答案:

答案 0 :(得分:3)

创建从属下拉列表不是apache poi所能做的。 apache poi库用于创建Excel文件。下拉列表的依赖性必须在运行生成的文件的Excel 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();

 }
}

答案 1 :(得分:0)

改进一点-可以使用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();

 }
}