In our actual program development, we often need to import data system from excel. In order to prevent users from entering text randomly in excel, some places need to use drop-down selection, we need to generate templates dynamically from the program. This example briefly explains how to generate cascade drop-down selections.
Effect drawing: (Choose the car as the drop-down selection, and the value of the fruit drop-down selection changes dynamically)
The implementation steps of cascade drop-down selection are as follows:
1. In another sheet page in excel, the drop-down value is saved.
2. Create a name for the data in the drop-down (similar to operating the naming manager in excel)
3. Use the INDIRECT() function to get the cascade drop-down value.
4. Description of creating cascade drop-down selection on POI official website
In this example, a simple way to generate dynamic excel templates is presented.
Note: Each template field is an ExportDefinition object. If it is a drop-down type, the mainDict field has a value. According to its value, the drop-down value is loaded from the DictData. If a cascade operation exists to select it, the subDict and subField fields have values. SubDict also loads data from DictData, and subField represents cascaded fields
Ideas:
1. According to a set of Export Definition defining objects, the export template of excel is generated. At this time, only one line to the output data is exported from the template.
2. Create a data dictionary page, which stores the data needed for dropdown selection.
3. If the main drop-down is selected, a name management is created for the main drop-down.
4. If the main drop-down selection is associated with the cascade drop-down selection, then the data of the sub-drop-down selection needs to be loaded at this time, and a name management is created according to each item selected by the main drop-down selection, and the value is the value of the associated sub-drop-down selection.
5. Use INDIRECT function, set the validity of data, etc.
Steps:
1. Create drop-down values
- public class DictData {
- public static Map<String, Object> dict = null;
- static {
- dict = new HashMap<>();
- List<String> list = new ArrayList<>();
- list.add("automobile");
- list.add("Fruits");
- dict.put("car-dict", list);
- Map<String, List<String>> subMap = new HashMap<>();
- list = new ArrayList<>();
- list.add("BMW");
- list.add("Public");
- subMap.put("automobile", list);
- list = new ArrayList<>();
- list.add("Apple");
- list.add("Pear");
- subMap.put("Fruits", list);
- dict.put("fruit-dict", subMap);
- list = new ArrayList<>();
- list.add("automobile-1");
- list.add("Fruits-1");
- dict.put("t-dict", list);
- }
- /** Get the values in the data dictionary*/
- public static Object getDict(String dict) {
- return DictData.dict.get(dict);
- }
- }
2. Create a RowCellIndex object for maintenance, currently creating the row and column of the drop-down selection
- public class RowCellIndex {
- /** Row index of cells*/
- private int rowIndex;
- /** Column index of cells*/
- private int cellIndex;
- public RowCellIndex(int rowIndex, int cellIndex) {
- this.rowIndex = rowIndex;
- this.cellIndex = cellIndex;
- }
- public int getRowIndex() {
- return rowIndex;
- }
- public void setRowIndex(int rowIndex) {
- this.rowIndex = rowIndex;
- }
- public int getCellIndex() {
- return cellIndex;
- }
- public void setCellIndex(int cellIndex) {
- this.cellIndex = cellIndex;
- }
- public int incrementRowIndexAndGet() {
- this.rowIndex++;
- return this.getRowIndex();
- }
- public int incrementCellIndexAndGet() {
- this.cellIndex++;
- return this.getCellIndex();
- }
- }
3. Create an export definition object for an excel column, omitting some getter and setter methods
- public class ExportDefinition {
- private String title; //Title
- private String field; //Field
- private int rowIndex; //The row in which it is located
- private int cellIndex; //The column in which it is located
- private String mainDict; //Master Dictionary - Data for Loading Master Dictionary
- private String subDict; //Subdictionary - Data used to load subField
- private String subField; //That is, a cascaded dictionary is required
- private String refName; //Location of the main field
- private String point; //Coordinates of headings
- private boolean validate;//Whether to set the limitation of data
- public ExportDefinition(String title, String field, String mainDict, String subDict, String subField) {
- this.title = title;
- this.field = field;
- this.mainDict = mainDict;
- this.subDict = subDict;
- this.subField = subField;
- }
4. Implementing export
- package com.huan.excel.ex2;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Objects;
- import org.apache.poi.hssf.usermodel.DVConstraint;
- import org.apache.poi.hssf.usermodel.HSSFDataValidation;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.hssf.util.CellReference;
- import org.apache.poi.ss.usermodel.DataValidation;
- import org.apache.poi.ss.usermodel.Name;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import org.apache.poi.ss.util.CellRangeAddressList;
- /**
- * Generate cascade drop-down selection
- *
- * @describe
- * @Author Huang
- * @Time: 31 March 2017 - 9:14:43 p.m.
- */
- public class DropDownListTest {
- private static final String DICT_SHEET = "DICT_SHEET";
- public static void main(String[] args) throws IOException {
- //1. Preparing the data needed to generate excel templates
- List<ExportDefinition> edList = new ArrayList<>(2);
- edList.add(new ExportDefinition("Articles for daily use", "xx", null, null, null));
- edList.add(new ExportDefinition("automobile", "cat", "car-dict", "fruit-dict", "fruit"));
- edList.add(new ExportDefinition("Fruits", "fruit", "fruit-dict", "", ""));
- edList.add(new ExportDefinition("test", "yy", "t-dict", null, null));
- //2. Generating export templates
- Workbook wb = new HSSFWorkbook();
- Sheet sheet = createExportSheet(edList, wb);
- //3. Create sheet pages of data dictionary
- createDictSheet(edList, wb);
- //4. Setting up data validity
- setDataValidation(edList, sheet);
- //5. Save excel locally
- OutputStream os = new FileOutputStream("d:/4.xls");
- wb.write(os);
- System.out.println("Successful template generation.");
- }
- /**
- * @param edList
- * @param sheet
- */
- private static void setDataValidation(List<ExportDefinition> edList, Sheet sheet) {
- for (ExportDefinition ed : edList) {
- if (ed.isValidate()) {//Explanation is drop-down
- DVConstraint constraint = DVConstraint.createFormulaListConstraint(ed.getField());
- if (null == ed.getRefName()) {//Explanation is a first-level drop-down
- createDataValidate(sheet, ed, constraint);
- } else {//Explanation is second-level drop-down
- constraint = DVConstraint.createFormulaListConstraint("INDIRECT(" + ed.getRefName() + ")");
- createDataValidate(sheet, ed, constraint);
- }
- }
- }
- }
- /**
- * @param sheet
- * @param ed
- * @param constraint
- */
- private static void createDataValidate(Sheet sheet, ExportDefinition ed, DVConstraint constraint) {
- CellRangeAddressList regions = new CellRangeAddressList(ed.getRowIndex() + 1, ed.getRowIndex() + 100, ed.getCellIndex(), ed.getCellIndex());
- DataValidation dataValidation = new HSSFDataValidation(regions, constraint);
- dataValidation.setSuppressDropDownArrow(false);
- //Setting prompt information
- dataValidation.createPromptBox("Operational tips", "Please select the value selected by dropdown");
- //Setting input error information
- dataValidation.createErrorBox("Error prompt", "Choose from the drop-down and don't type in casually.");
- sheet.addValidationData(dataValidation);
- }
- /**
- * @param edList
- * @param wb
- */
- private static void createDictSheet(List<ExportDefinition> edList, Workbook wb) {
- Sheet sheet = wb.createSheet(DICT_SHEET);
- RowCellIndex rci = new RowCellIndex(0, 0);
- for (ExportDefinition ed : edList) {
- String mainDict = ed.getMainDict();
- if (null != mainDict && null == ed.getRefName()) {//The first drop-down
- List<String> mainDictList = (List<String>) DictData.getDict(mainDict);
- String refersToFormula = createDictAndReturnRefFormula(sheet, rci, mainDictList);
- //Create naming management
- createName(wb, ed.getField(), refersToFormula);
- ed.setValidate(true);
- }
- if (null != mainDict && null != ed.getSubDict() && null != ed.getSubField()) {//Load the data of ed.getSubField() when interacting
- ExportDefinition subEd = fiterByField(edList, ed.getSubField());//Get the field that needs to be cascaded
- if (null == subEd) {
- continue;
- }
- subEd.setRefName(ed.getPoint());//Save the main drop-down location
- subEd.setValidate(true);
- Map<String, List<String>> subDictListMap = (Map<String, List<String>>) DictData.getDict(ed.getSubDict());
- for (Entry<String, List<String>> entry : subDictListMap.entrySet()) {
- String refersToFormula = createDictAndReturnRefFormula(sheet, rci, entry.getValue());
- //Create naming management
- createName(wb, entry.getKey(), refersToFormula);
- }
- }
- }
- }
- /**
- * @param sheet
- * @param rci
- * @param mainDict
- * @return
- */
- private static String createDictAndReturnRefFormula(Sheet sheet, RowCellIndex rci, List<String> datas) {
- Row row = sheet.createRow(rci.incrementRowIndexAndGet());
- rci.setCellIndex(0);
- int startRow = rci.getRowIndex();
- int startCell = rci.getCellIndex();
- for (String dict : datas) {
- row.createCell(rci.incrementCellIndexAndGet()).setCellValue(dict);
- }
- int endRow = rci.getRowIndex();
- int endCell = rci.getCellIndex();
- String startName = new CellReference(DICT_SHEET, startRow, startCell, true, true).formatAsString();
- String endName = new CellReference(endRow, endCell, true, true).formatAsString();
- String refersToFormula = startName + ":" + endName;
- System.out.println(refersToFormula);
- return refersToFormula;
- }
- /**
- * @param wb
- * @param nameName
- * Name that represents naming management
- * @param refersToFormula
- */
- private static void createName(Workbook wb, String nameName, String refersToFormula) {
- Name name = wb.createName();
- name.setNameName(nameName);
- name.setRefersToFormula(refersToFormula);
- }
- private static ExportDefinition fiterByField(List<ExportDefinition> edList, String field) {
- for (ExportDefinition ed : edList) {
- if (Objects.equals(ed.getField(), field)) {
- return ed;
- }
- }
- return null;
- }
- /**
- * @param edList
- * @param wb
- */
- private static Sheet createExportSheet(List<ExportDefinition> edList, Workbook wb) {
- Sheet sheet = wb.createSheet("Export Template");
- RowCellIndex rci = new RowCellIndex(0, 0);
- Row row = sheet.createRow(rci.getRowIndex());
- CellReference cr = null;
- for (ExportDefinition ed : edList) {
- row.createCell(rci.incrementCellIndexAndGet()).setCellValue(ed.getTitle());
- ed.setRowIndex(rci.getRowIndex());
- ed.setCellIndex(rci.getCellIndex());
- cr = new CellReference(ed.getRowIndex() + 1, ed.getCellIndex(), true, true);
- ed.setPoint(cr.formatAsString());
- }
- return sheet;
- }
- }