You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LinkedDropDownLists.java 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.examples.ss;
  16. import java.io.FileOutputStream;
  17. import java.io.IOException;
  18. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  19. import org.apache.poi.ss.usermodel.Cell;
  20. import org.apache.poi.ss.usermodel.DataValidation;
  21. import org.apache.poi.ss.usermodel.DataValidationConstraint;
  22. import org.apache.poi.ss.usermodel.DataValidationHelper;
  23. import org.apache.poi.ss.usermodel.Name;
  24. import org.apache.poi.ss.usermodel.Row;
  25. import org.apache.poi.ss.usermodel.Sheet;
  26. import org.apache.poi.ss.usermodel.Workbook;
  27. import org.apache.poi.ss.util.CellRangeAddressList;
  28. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  29. /**
  30. * Demonstrates one technique that may be used to create linked or dependent
  31. * drop down lists. This refers to a situation in which the selection made
  32. * in one drop down list affects the options that are displayed in the second
  33. * or subsequent drop down list(s). In this example, the value the user selects
  34. * from the down list in cell A1 will affect the values displayed in the linked
  35. * drop down list in cell B1. For the sake of simplicity, the data for the drop
  36. * down lists is included on the same worksheet but this does not have to be the
  37. * case; the data could appear on a separate sheet. If this were done, then the
  38. * names for the regions would have to be different, they would have to include
  39. * the name of the sheet.
  40. *
  41. * There are two keys to this technique. The first is the use of named area or
  42. * regions of cells to hold the data for the drop down lists and the second is
  43. * making use of the INDIRECT() function to convert a name into the addresses
  44. * of the cells it refers to.
  45. *
  46. * Note that whilst this class builds just two linked drop down lists, there is
  47. * nothing to prevent more being created. Quite simply, use the value selected
  48. * by the user in one drop down list to determine what is shown in another and the
  49. * value selected in that drop down list to determine what is shown in a third,
  50. * and so on. Also, note that the data for the drop down lists is contained on
  51. * contained on the same sheet as the validations themselves. This is done simply
  52. * for simplicity and there is nothing to prevent a separate sheet being created
  53. * and used to hold the data. If this is done then problems may be encountered
  54. * if the sheet is opened with OpenOffice Calc. To prevent these problems, it is
  55. * better to include the name of the sheet when calling the setRefersToFormula()
  56. * method.
  57. *
  58. * @author Mark Beardsley [msb at apache.org]
  59. * @version 1.00 30th March 2012
  60. */
  61. public class LinkedDropDownLists {
  62. LinkedDropDownLists(String workbookName) throws IOException {
  63. // Using the ss.usermodel allows this class to support both binary
  64. // and xml based workbooks. The choice of which one to create is
  65. // made by checking the file extension.
  66. try (Workbook workbook = workbookName.endsWith(".xlsx") ? new XSSFWorkbook() : new HSSFWorkbook()) {
  67. // Build the sheet that will hold the data for the validations. This
  68. // must be done first as it will create names that are referenced
  69. // later.
  70. Sheet sheet = workbook.createSheet("Linked Validations");
  71. LinkedDropDownLists.buildDataSheet(sheet);
  72. // Build the first data validation to occupy cell A1. Note
  73. // that it retrieves it's data from the named area or region called
  74. // CHOICES. Further information about this can be found in the
  75. // static buildDataSheet() method below.
  76. CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
  77. DataValidationHelper dvHelper = sheet.getDataValidationHelper();
  78. DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint("CHOICES");
  79. DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
  80. sheet.addValidationData(validation);
  81. // Now, build the linked or dependent drop down list that will
  82. // occupy cell B1. The key to the whole process is the use of the
  83. // INDIRECT() function. In the buildDataSheet(0 method, a series of
  84. // named regions are created and the names of three of them mirror
  85. // the options available to the user in the first drop down list
  86. // (in cell A1). Using the INDIRECT() function makes it possible
  87. // to convert the selection the user makes in that first drop down
  88. // into the addresses of a named region of cells and then to use
  89. // those cells to populate the second drop down list.
  90. addressList = new CellRangeAddressList(0, 0, 1, 1);
  91. dvConstraint = dvHelper.createFormulaListConstraint(
  92. "INDIRECT(UPPER($A$1))");
  93. validation = dvHelper.createValidation(dvConstraint, addressList);
  94. sheet.addValidationData(validation);
  95. try (FileOutputStream fos = new FileOutputStream(workbookName)) {
  96. workbook.write(fos);
  97. }
  98. }
  99. }
  100. /**
  101. * Called to populate the named areas/regions. The contents of the cells on
  102. * row one will be used to populate the first drop down list. The contents of
  103. * the cells on rows two, three and four will be used to populate the second
  104. * drop down list, just which row will be determined by the choice the user
  105. * makes in the first drop down list.
  106. *
  107. * In all cases, the approach is to create a row, create and populate cells
  108. * with data and then specify a name that identifies those cells. With the
  109. * exception of the first range, the names that are chosen for each range
  110. * of cells are quite important. In short, each of the options the user
  111. * could select in the first drop down list is used as the name for another
  112. * range of cells. Thus, in this example, the user can select either
  113. * 'Animal', 'Vegetable' or 'Mineral' in the first drop down and so the
  114. * sheet contains ranges named 'ANIMAL', 'VEGETABLE' and 'MINERAL'.
  115. *
  116. * @param dataSheet An instance of a class that implements the Sheet Sheet
  117. * interface (HSSFSheet or XSSFSheet).
  118. */
  119. private static void buildDataSheet(Sheet dataSheet) {
  120. Row row = null;
  121. Cell cell = null;
  122. Name name = null;
  123. // The first row will hold the data for the first validation.
  124. row = dataSheet.createRow(10);
  125. cell = row.createCell(0);
  126. cell.setCellValue("Animal");
  127. cell = row.createCell(1);
  128. cell.setCellValue("Vegetable");
  129. cell = row.createCell(2);
  130. cell.setCellValue("Mineral");
  131. name = dataSheet.getWorkbook().createName();
  132. name.setRefersToFormula("$A$11:$C$11");
  133. name.setNameName("CHOICES");
  134. // The next three rows will hold the data that will be used to
  135. // populate the second, or linked, drop down list.
  136. row = dataSheet.createRow(11);
  137. cell = row.createCell(0);
  138. cell.setCellValue("Lion");
  139. cell = row.createCell(1);
  140. cell.setCellValue("Tiger");
  141. cell = row.createCell(2);
  142. cell.setCellValue("Leopard");
  143. cell = row.createCell(3);
  144. cell.setCellValue("Elephant");
  145. cell = row.createCell(4);
  146. cell.setCellValue("Eagle");
  147. cell = row.createCell(5);
  148. cell.setCellValue("Horse");
  149. cell = row.createCell(6);
  150. cell.setCellValue("Zebra");
  151. name = dataSheet.getWorkbook().createName();
  152. name.setRefersToFormula("$A$12:$G$12");
  153. name.setNameName("ANIMAL");
  154. row = dataSheet.createRow(12);
  155. cell = row.createCell(0);
  156. cell.setCellValue("Cabbage");
  157. cell = row.createCell(1);
  158. cell.setCellValue("Cauliflower");
  159. cell = row.createCell(2);
  160. cell.setCellValue("Potato");
  161. cell = row.createCell(3);
  162. cell.setCellValue("Onion");
  163. cell = row.createCell(4);
  164. cell.setCellValue("Beetroot");
  165. cell = row.createCell(5);
  166. cell.setCellValue("Asparagus");
  167. cell = row.createCell(6);
  168. cell.setCellValue("Spinach");
  169. cell = row.createCell(7);
  170. cell.setCellValue("Chard");
  171. name = dataSheet.getWorkbook().createName();
  172. name.setRefersToFormula("$A$13:$H$13");
  173. name.setNameName("VEGETABLE");
  174. row = dataSheet.createRow(13);
  175. cell = row.createCell(0);
  176. cell.setCellValue("Bauxite");
  177. cell = row.createCell(1);
  178. cell.setCellValue("Quartz");
  179. cell = row.createCell(2);
  180. cell.setCellValue("Feldspar");
  181. cell = row.createCell(3);
  182. cell.setCellValue("Shist");
  183. cell = row.createCell(4);
  184. cell.setCellValue("Shale");
  185. cell = row.createCell(5);
  186. cell.setCellValue("Mica");
  187. name = dataSheet.getWorkbook().createName();
  188. name.setRefersToFormula("$A$14:$F$14");
  189. name.setNameName("MINERAL");
  190. }
  191. }