<li><link href="#CellComments">How to set cell comments</link></li>
<li><link href="#Autofit">How to adjust column width to fit the contents</link></li>
<li><link href="#Hyperlinks">Hyperlinks</link></li>
- <li><link href="#Validation">Data Validation</link></li>
+ <li><link href="#Validation">Data Validations</link></li>
<li><link href="#Embedded">Embedded Objects</link></li>
<li><link href="#Autofilter">Autofilters</link></li>
<li><link href="#ConditionalFormatting">Conditional Formatting</link></li>
+ <li><link href="#Hiding">Hiding and Un-Hiding Rows</link></li>
</ul>
</section>
<section><title>Features</title>
</section>
<anchor id="Validation"/>
<section><title>Data Validations</title>
- <p><strong>Check the value a user enters into a cell against one or more predefined value(s).</strong></p>
- <p>The following code will limit the value the user can enter into cell A1 to one of three integer values, 10, 20 or 30.</p>
+ <p>
+ As of version 3.8, POI has slightly different syntax to work with data validations with .xls and .xlsx formats.
+ </p>
+ <section>
+ <title>hssf.usermodel (binary .xls format)</title>
+ <p><strong>Check the value a user enters into a cell against one or more predefined value(s).</strong></p>
+ <p>The following code will limit the value the user can enter into cell A1 to one of three integer values, 10, 20 or 30.</p>
<source>
- Workbook workbook = new HSSFWorkbook();
- Sheet sheet = workbook.createSheet("Data Validation");
- CellRangeAddressList addressList = new CellRangeAddressList(
- 0, 0, 0, 0);
- DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(
- new String[]{"10", "20", "30"});
- DataValidation dataValidation = new HSSFDataValidation
- (addressList, dvConstraint);
- dataValidation.setSuppressDropDownArrow(true);
- sheet.addValidationData(dataValidation);
+ HSSFWorkbook workbook = new HSSFWorkbook();
+ HSSFSheet sheet = workbook.createSheet("Data Validation");
+ CellRangeAddressList addressList = new CellRangeAddressList(
+ 0, 0, 0, 0);
+ DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(
+ new String[]{"10", "20", "30"});
+ DataValidation dataValidation = new HSSFDataValidation
+ (addressList, dvConstraint);
+ dataValidation.setSuppressDropDownArrow(true);
+ sheet.addValidationData(dataValidation);
</source>
<p><strong> Drop Down Lists:</strong></p>
<p>This code will do the same but offer the user a drop down list to select a value from.</p>
<source>
- Workbook workbook = new HSSFWorkbook();
- Sheet sheet = workbook.createSheet("Data Validation");
- CellRangeAddressList addressList = new CellRangeAddressList(
- 0, 0, 0, 0);
- DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(
- new String[]{"10", "20", "30"});
- DataValidation dataValidation = new HSSFDataValidation
- (addressList, dvConstraint);
- dataValidation.setSuppressDropDownArrow(false);
- sheet.addValidationData(dataValidation);
+ HSSFWorkbook workbook = new HSSFWorkbook();
+ HSSFSheet sheet = workbook.createSheet("Data Validation");
+ CellRangeAddressList addressList = new CellRangeAddressList(
+ 0, 0, 0, 0);
+ DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(
+ new String[]{"10", "20", "30"});
+ DataValidation dataValidation = new HSSFDataValidation
+ (addressList, dvConstraint);
+ dataValidation.setSuppressDropDownArrow(false);
+ sheet.addValidationData(dataValidation);
</source>
<p><strong>Messages On Error:</strong></p>
<p>To create a message box that will be shown to the user if the value they enter is invalid.</p>
<source>
dataValidation.setErrorStyle(DataValidation.ErrorStyle.STOP);
dataValidation.createErrorBox("Box Title", "Message Text");
- </source>
+ </source>
<p>Replace 'Box Title' with the text you wish to display in the message box's title bar
and 'Message Text' with the text of your error message.</p>
<p><strong>Prompts:</strong></p>
<p>The text encapsulated in the first parameter passed to the createPromptBox() method will appear emboldened
and as a title to the prompt whilst the second will be displayed as the text of the message.
The createExplicitListConstraint() method can be passed and array of String(s) containing interger, floating point, dates or text values.</p>
+
<p><strong>Further Data Validations:</strong></p>
<p>To obtain a validation that would check the value entered was, for example, an integer between 10 and 100,
use the DVConstraint.createNumericConstraint(int, int, String, String) factory method.</p>
the setSuppressDropDownArrow(false) method call will simply be ignored.</p>
<p>Date and time constraints can be created by calling the createDateConstraint(int, String, String, String)
or the createTimeConstraint(int, String, String). Both are very similar to the above and are explained in the javadoc. </p>
-
<p><strong>Creating Data Validations From Spreadsheet Cells.</strong></p>
<p>The contents of specific cells can be used to provide the values for the data validation
and the DVConstraint.createFormulaListConstraint(String) method supports this.
</source><p>and nor will this:</p><source>
dvConstraint = DVConstraint.createFormulaListConstraint("'Sheet1'!$A$1:$A$3");
</source>
+ </section>
+ <section>
+ <title>xssf.usermodel (.xlsx format)</title>
+<p>
+Data validations work similarly when you are creating an xml based, SpreadsheetML,
+workbook file; but there are differences. Explicit casts are required, for example,
+in a few places as much of the support for data validations in the xssf stream was
+built into the unifying ss stream, of which more later. Other differences are
+noted with comments in the code.
+</p>
+
+<p><strong>Check the value the user enters into a cell against one or more predefined value(s).</strong></p>
+<source>
+ XSSFWorkbook workbook = new XSSFWorkbook();
+ XSSFSheet sheet = workbook.createSheet("Data Validation");
+ XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createExplicitListConstraint(new String[]{"11", "21", "31"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ XSSFDataValidation validation =(XSSFDataValidation)dvHelper.createValidation(
+ dvConstraint, addressList);
+
+ // Here the boolean value false is passed to the setSuppressDropDownArrow()
+ // method. In the hssf.usermodel examples above, the value passed to this
+ // method is true.
+ validation.setSuppressDropDownArrow(false);
+
+ // Note this extra method call. If this method call is omitted, or if the
+ // boolean value false is passed, then Excel will not validate the value the
+ // user enters into the cell.
+ validation.setShowErrorBox(true);
+ sheet.addValidationData(validation);
+</source>
+
+<p><strong>Drop Down Lists:</strong></p>
+<p>This code will do the same but offer the user a drop down list to select a value from.</p>
+<source>
+ XSSFWorkbook workbook = new XSSFWorkbook();
+ XSSFSheet sheet = workbook.createSheet("Data Validation");
+ XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createExplicitListConstraint(new String[]{"11", "21", "31"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ XSSFDataValidation validation = (XSSFDataValidation)dvHelper.createValidation(
+ dvConstraint, addressList);
+ validation.setShowErrorBox(true);
+ sheet.addValidationData(validation);
+</source>
+<p>Note that the call to the setSuppressDropDowmArrow() method can either be simply excluded or replaced with:</p>
+<source>
+ validation.setSuppressDropDownArrow(true);
+</source>
+
+<p><strong>Prompts and Error Messages:</strong></p>
+<p>
+These both exactly mirror the hssf.usermodel so please refer to the 'Messages On Error:' and 'Prompts:' sections above.
+</p>
+
+<p><strong>Further Data Validations:</strong></p>
+<p>
+To obtain a validation that would check the value entered was, for example,
+an integer between 10 and 100, use the XSSFDataValidationHelper(s) createNumericConstraint(int, int, String, String) factory method.
+</p>
+<source>
+
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createNumericConstraint(
+ XSSFDataValidationConstraint.ValidationType.INTEGER,
+ XSSFDataValidationConstraint.OperatorType.BETWEEN,
+ "10", "100");
+</source>
+<p>
+The values passed to the final two String parameters can be formulas; the '=' symbol is used to denote a formula.
+Thus, the following would create a validation the allows values only if they fall between the results of summing two cell ranges
+</p>
+<source>
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createNumericConstraint(
+ XSSFDataValidationConstraint.ValidationType.INTEGER,
+ XSSFDataValidationConstraint.OperatorType.BETWEEN,
+ "=SUM(A1:A10)", "=SUM(B24:B27)");
+</source>
+<p>
+It is not possible to create a drop down list if the createNumericConstraint() method is called,
+the setSuppressDropDownArrow(true) method call will simply be ignored.
+</p>
+<p>
+Please check the javadoc for other constraint types as examples for those will not be included here.
+There are, for example, methods defined on the XSSFDataValidationHelper class allowing you to create
+the following types of constraint; date, time, decimal, integer, numeric, formula, text length and custom constraints.
+</p>
+<p><strong>Creating Data Validations From Spread Sheet Cells:</strong></p>
+<p>
+One other type of constraint not mentioned above is the formula list constraint.
+It allows you to create a validation that takes it value(s) from a range of cells. This code
+</p>
+<source>
+XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createFormulaListConstraint("$A$1:$F$1");
+</source>
+
+<p>
+would create a validation that took it's values from cells in the range A1 to F1.
+</p>
+<p>
+The usefulness of this technique can be extended if you use named ranges like this;
+</p>
+
+<source>
+ XSSFName name = workbook.createName();
+ name.setNameName("data");
+ name.setRefersToFormula("$B$1:$F$1");
+ XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createFormulaListConstraint("data");
+ CellRangeAddressList addressList = new CellRangeAddressList(
+ 0, 0, 0, 0);
+ XSSFDataValidation validation = (XSSFDataValidation)
+ dvHelper.createValidation(dvConstraint, addressList);
+ validation.setSuppressDropDownArrow(true);
+ validation.setShowErrorBox(true);
+ sheet.addValidationData(validation);
+</source>
+<p>
+OpenOffice Calc has slightly different rules with regard to the scope of names.
+Excel supports both Workbook and Sheet scope for a name but Calc does not, it seems only to support Sheet scope for a name.
+Thus it is often best to fully qualify the name for the region or area something like this;
+</p>
+<source>
+ XSSFName name = workbook.createName();
+ name.setNameName("data");
+ name.setRefersToFormula("'Data Validation'!$B$1:$F$1");
+ ....
+</source>
+<p>
+This does open a further, interesting opportunity however and that is to place all of the data for the validation(s) into named ranges of cells on a hidden sheet within the workbook. These ranges can then be explicitly identified in the setRefersToFormula() method argument.
+</p>
+ </section>
+ <section><title>ss.usermodel</title>
+<p>
+The classes within the ss.usermodel package allow developers to create code that can be used
+to generate both binary (.xls) and SpreadsheetML (.xlsx) workbooks.
+</p>
+<p>
+The techniques used to create data validations share much in common with the xssf.usermodel examples above.
+As a result just one or two examples will be presented here.
+</p>
+<p><strong>Check the value the user enters into a cell against one or more predefined value(s).</strong></p>
+<source>
+ Workbook workbook = new XSSFWorkbook(); // or new HSSFWorkbook
+ Sheet sheet = workbook.createSheet("Data Validation");
+ DataValidationHelper dvHelper = sheet.getDataValidationHelper();
+ DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(
+ new String[]{"13", "23", "33"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ // Note the check on the actual type of the DataValidation object.
+ // If it is an instance of the XSSFDataValidation class then the
+ // boolean value 'false' must be passed to the setSuppressDropDownArrow()
+ // method and an explicit call made to the setShowErrorBox() method.
+ if(validation instanceof XSSFDataValidation) {
+ validation.setSuppressDropDownArrow(false);
+ validation.setShowErrorBox(true);
+ }
+ else {
+ // If the Datavalidation contains an instance of the HSSFDataValidation
+ // class then 'true' should be passed to the setSuppressDropDownArrow()
+ // method and the call to setShowErrorBox() is not necessary.
+ validation.setSuppressDropDownArrow(true);
+ }
+ sheet.addValidationData(validation);
+</source>
+
+<p><strong>Drop Down Lists:</strong></p>
+
+<p>This code will do the same but offer the user a drop down list to select a value from.</p>
+
+<source>
+ Workbook workbook = new XSSFWorkbook(); // or new HSSFWorkbook
+ Sheet sheet = workbook.createSheet("Data Validation");
+ DataValidationHelper dvHelper = sheet.getDataValidationHelper();
+ DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(
+ new String[]{"13", "23", "33"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ // Note the check on the actual type of the DataValidation object.
+ // If it is an instance of the XSSFDataValidation class then the
+ // boolean value 'false' must be passed to the setSuppressDropDownArrow()
+ // method and an explicit call made to the setShowErrorBox() method.
+ if(validation instanceof XSSFDataValidation) {
+ validation.setSuppressDropDownArrow(true);
+ validation.setShowErrorBox(true);
+ }
+ else {
+ // If the Datavalidation contains an instance of the HSSFDataValidation
+ // class then 'true' should be passed to the setSuppressDropDownArrow()
+ // method and the call to setShowErrorBox() is not necessary.
+ validation.setSuppressDropDownArrow(false);
+ }
+ sheet.addValidationData(validation);
+</source>
+
+<p><strong>Prompts and Error Messages:</strong></p>
+<p>
+These both exactly mirror the hssf.usermodel so please refer to the 'Messages On Error:' and 'Prompts:' sections above.
+</p>
+<p>
+As the differences between the ss.usermodel and xssf.usermodel examples are small -
+restricted largely to the way the DataValidationHelper is obtained, the lack of any
+need to explicitly cast data types and the small difference in behaviour between
+the hssf and xssf interpretation of the setSuppressDropDowmArrow() method,
+no further examples will be included in this section.
+</p>
+<p><strong>Advanced Data Validations.</strong></p>
+<p><strong>Dependent Drop Down Lists.</strong></p>
+<p>
+In some cases, it may be necessary to present to the user a sheet which contains more than one drop down list.
+Further, the choice the user makes in one drop down list may affect the options that are presented to them in
+the second or subsequent drop down lists. One technique that may be used to implement this behaviour will now be explained.
+</p>
+<p>
+There are two keys to the technique; one is to use named areas or regions of cells to hold the data for the drop down lists,
+the second is to use the INDIRECT() function to convert between the name and the actual addresses of the cells.
+In the example section there is a complete working example- called LinkedDropDownLists.java -
+that demonstrates how to create linked or dependent drop down lists. Only the more relevant points are explained here.
+</p>
+<p>
+To create two drop down lists where the options shown in the second depend upon the selection made in the first,
+begin by creating a named region of cells to hold all of the data for populating the first drop down list.
+Next, create a data validation that will look to this named area for its data, something like this;
+</p>
+<source>
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ DataValidationHelper dvHelper = sheet.getDataValidationHelper();
+ DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(
+ "CHOICES");
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ sheet.addValidationData(validation);
+</source>
+<p>
+Note that the name of the area - in the example above it is 'CHOICES' -
+is simply passed to the createFormulaListConstraint() method. This is sufficient
+to cause Excel to populate the drop down list with data from that named region.
+</p>
+<p>
+Next, for each of the options the user could select in the first drop down list,
+create a matching named region of cells. The name of that region should match the
+text the user could select in the first drop down list. Note, in the example,
+all upper case letters are used in the names of the regions of cells.
+</p>
+
+<p>
+Now, very similar code can be used to create a second, linked, drop down list;
+</p>
+
+<source>
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 1, 1);
+ DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(
+ "INDIRECT(UPPER($A$1))");
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ sheet.addValidationData(validation);
+</source>
+
+<p>
+The key here is in the following Excel function - INDIRECT(UPPER($A$1)) - which is used to populate the second,
+linked, drop down list. Working from the inner-most pair of brackets, it instructs Excel to look
+at the contents of cell A1, to convert what it reads there into upper case – as upper case letters are used
+in the names of each region - and then convert this name into the addresses of those cells that contain
+the data to populate another drop down list.
+</p>
+ </section>
</section>
<anchor id="Embedded"/>
<section><title>Embedded Objects</title>
</p>
</section>
+ <anchor id="Hiding"/>
+ <section><title>Hiding and Un-Hiding Rows</title>
+ <p>
+ Using Excel, it is possible to hide a row on a worksheet by selecting that row (or rows),
+ right clicking once on the right hand mouse button and selecting 'Hide' from the pop=up menu that appears.
+ </p>
+ <p>
+ To emulate this using POI, simply call the setZeroHeight() method on an instance of either
+ XSSFRow or HSSFRow (the method is defined on the ss.usermodel.Row interface that both classes implement), like this:
+ </p>
+ <source>
+ Workbook workbook = new XSSFWorkbook(); // OR new HSSFWorkbook()
+ Sheet sheet = workbook.createSheet(0);
+ Row row = workbook.createRow(0);
+ row.setZeroHeight();
+ </source>
+ <p>
+ If the file were saved away to disc now, then the first row on the first sheet would not be visible.
+ </p>
+ <p>
+ Using Excel, it is possible to unhide previously hidden rows by selecting the row above and the row below
+ the one that is hidden and then pressing and holding down the Ctrl key, the Shift and the pressing
+ the number 9 before releasing them all.
+ </p>
+ <p>
+ To emulate this behaviour using POI do something like this:
+ </p>
+ <source>
+ Workbook workbook = WorkbookFactory.create(new File(.......));
+ Sheet = workbook.getSheetAt(0);
+ Iterator<Row> row Iter = sheet.iterator();
+ while(rowIter.hasNext()) {
+ Row row = rowIter.next();
+ if(row.getZeroHeight()) {
+ row.setZeroHeight(false);
+ }
+ }
+ </source>
+ <p>
+ If the file were saved away to disc now, any previously hidden rows on the first sheet of the workbook would now be visible.
+ </p>
+ <p>
+ The example illustrates two features. Firstly, that it is possible to unhide a row simply by calling the setZeroHeight()
+ method and passing the boolean value 'false'. Secondly, it ilustrates how to test whther a row is hidden or not.
+ Simply call the getZeroHeight() method and it will return 'true' if the row is hidden, 'false' otherwise.
+ </p>
+ </section>
</body>
</document>
--- /dev/null
+ /* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+ ==================================================================== */\r
+\r
+package org.apache.poi.ss.examples;\r
+import java.io.*;\r
+import org.apache.poi.xssf.usermodel.*;\r
+import org.apache.poi.hssf.usermodel.*;\r
+import org.apache.poi.ss.usermodel.*;\r
+import org.apache.poi.ss.util.CellRangeAddressList;\r
+\r
+/**\r
+ * Demonstrates one technique that may be used to create linked or dependent\r
+ * drop down lists. This refers to a situation in which the selection made\r
+ * in one drop down list affects the options that are displayed in the second\r
+ * or subsequent drop down list(s). In this example, the value the user selects\r
+ * from the down list in cell A1 will affect the values displayed in the linked\r
+ * drop down list in cell B1. For the sake of simplicity, the data for the drop\r
+ * down lists is included on the same worksheet but this does not have to be the\r
+ * case; the data could appear on a separate sheet. If this were done, then the\r
+ * names for the regions would have to be different, they would have to include\r
+ * the name of the sheet.\r
+ * \r
+ * There are two keys to this technique. The first is the use of named area or \r
+ * regions of cells to hold the data for the drop down lists and the second is\r
+ * making use of the INDIRECT() function to convert a name into the addresses\r
+ * of the cells it refers to.\r
+ * \r
+ * Note that whilst this class builds just two linked drop down lists, there is\r
+ * nothing to prevent more being created. Quite simply, use the value selected\r
+ * by the user in one drop down list to determine what is shown in another and the\r
+ * value selected in that drop down list to determine what is shown in a third,\r
+ * and so on. Also, note that the data for the drop down lists is contained on\r
+ * contained on the same sheet as the validations themselves. This is done simply\r
+ * for simplicity and there is nothing to prevent a separate sheet being created\r
+ * and used to hold the data. If this is done then problems may be encountered\r
+ * if the sheet is opened with OpenOffice Calc. To prevent these problems, it is\r
+ * better to include the name of the sheet when calling the setRefersToFormula()\r
+ * method.\r
+ *\r
+ * @author Mark Beardsley [msb at apache.org]\r
+ * @version 1.00 30th March 2012\r
+ */\r
+public class LinkedDropDownLists {\r
+\r
+ LinkedDropDownLists(String workbookName) {\r
+ File file = null;\r
+ FileOutputStream fos = null;\r
+ Workbook workbook = null;\r
+ Sheet sheet = null;\r
+ DataValidationHelper dvHelper = null;\r
+ DataValidationConstraint dvConstraint = null;\r
+ DataValidation validation = null;\r
+ CellRangeAddressList addressList = null;\r
+ try {\r
+\r
+ // Using the ss.usermodel allows this class to support both binary\r
+ // and xml based workbooks. The choice of which one to create is\r
+ // made by checking the file extension.\r
+ if (workbookName.endsWith(".xlsx")) {\r
+ workbook = new XSSFWorkbook();\r
+ } else {\r
+ workbook = new HSSFWorkbook();\r
+ }\r
+ \r
+ // Build the sheet that will hold the data for the validations. This\r
+ // must be done first as it will create names that are referenced \r
+ // later.\r
+ sheet = workbook.createSheet("Linked Validations");\r
+ LinkedDropDownLists.buildDataSheet(sheet);\r
+\r
+ // Build the first data validation to occupy cell A1. Note\r
+ // that it retrieves it's data from the named area or region called\r
+ // CHOICES. Further information about this can be found in the\r
+ // static buildDataSheet() method below.\r
+ addressList = new CellRangeAddressList(0, 0, 0, 0);\r
+ dvHelper = sheet.getDataValidationHelper();\r
+ dvConstraint = dvHelper.createFormulaListConstraint("CHOICES");\r
+ validation = dvHelper.createValidation(dvConstraint, addressList);\r
+ sheet.addValidationData(validation);\r
+ \r
+ // Now, build the linked or dependent drop down list that will\r
+ // occupy cell B1. The key to the whole process is the use of the\r
+ // INDIRECT() function. In the buildDataSheet(0 method, a series of\r
+ // named regions are created and the names of three of them mirror\r
+ // the options available to the user in the first drop down list\r
+ // (in cell A1). Using the INDIRECT() function makes it possible\r
+ // to convert the selection the user makes in that first drop down\r
+ // into the addresses of a named region of cells and then to use\r
+ // those cells to populate the second drop down list.\r
+ addressList = new CellRangeAddressList(0, 0, 1, 1);\r
+ dvConstraint = dvHelper.createFormulaListConstraint(\r
+ "INDIRECT(UPPER($A$1))");\r
+ validation = dvHelper.createValidation(dvConstraint, addressList);\r
+ sheet.addValidationData(validation);\r
+ \r
+ file = new File(workbookName);\r
+ fos = new FileOutputStream(file);\r
+ workbook.write(fos);\r
+ } catch (IOException ioEx) {\r
+ System.out.println("Caught a: " + ioEx.getClass().getName());\r
+ System.out.println("Message: " + ioEx.getMessage());\r
+ System.out.println("Stacktrace follws:.....");\r
+ ioEx.printStackTrace(System.out);\r
+ } finally {\r
+ try {\r
+ if (fos != null) {\r
+ fos.close();\r
+ fos = null;\r
+ }\r
+ } catch (IOException ioEx) {\r
+ System.out.println("Caught a: " + ioEx.getClass().getName());\r
+ System.out.println("Message: " + ioEx.getMessage());\r
+ System.out.println("Stacktrace follws:.....");\r
+ ioEx.printStackTrace(System.out);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Called to populate the named areas/regions. The contents of the cells on\r
+ * row one will be used to populate the first drop down list. The contents of\r
+ * the cells on rows two, three and four will be used to populate the second\r
+ * drop down list, just which row will be determined by the choice the user\r
+ * makes in the first drop down list.\r
+ * \r
+ * In all cases, the approach is to create a row, create and populate cells\r
+ * with data and then specify a name that identifies those cells. With the\r
+ * exception of the first range, the names that are chosen for each range\r
+ * of cells are quite important. In short, each of the options the user \r
+ * could select in the first drop down list is used as the name for another\r
+ * range of cells. Thus, in this example, the user can select either \r
+ * 'Animal', 'Vegetable' or 'Mineral' in the first drop down and so the\r
+ * sheet contains ranges named 'ANIMAL', 'VEGETABLE' and 'MINERAL'.\r
+ * \r
+ * @param dataSheet An instance of a class that implements the Sheet Sheet\r
+ * interface (HSSFSheet or XSSFSheet).\r
+ */\r
+ private static final void buildDataSheet(Sheet dataSheet) {\r
+ Row row = null;\r
+ Cell cell = null;\r
+ Name name = null;\r
+\r
+ // The first row will hold the data for the first validation.\r
+ row = dataSheet.createRow(10);\r
+ cell = row.createCell(0);\r
+ cell.setCellValue("Animal");\r
+ cell = row.createCell(1);\r
+ cell.setCellValue("Vegetable");\r
+ cell = row.createCell(2);\r
+ cell.setCellValue("Mineral");\r
+ name = dataSheet.getWorkbook().createName();\r
+ name.setRefersToFormula("$A$11:$C$11");\r
+ name.setNameName("CHOICES");\r
+\r
+ // The next three rows will hold the data that will be used to\r
+ // populate the second, or linked, drop down list.\r
+ row = dataSheet.createRow(11);\r
+ cell = row.createCell(0);\r
+ cell.setCellValue("Lion");\r
+ cell = row.createCell(1);\r
+ cell.setCellValue("Tiger");\r
+ cell = row.createCell(2);\r
+ cell.setCellValue("Leopard");\r
+ cell = row.createCell(3);\r
+ cell.setCellValue("Elephant");\r
+ cell = row.createCell(4);\r
+ cell.setCellValue("Eagle");\r
+ cell = row.createCell(5);\r
+ cell.setCellValue("Horse");\r
+ cell = row.createCell(6);\r
+ cell.setCellValue("Zebra");\r
+ name = dataSheet.getWorkbook().createName();\r
+ name.setRefersToFormula("$A$12:$G$12");\r
+ name.setNameName("ANIMAL");\r
+\r
+ row = dataSheet.createRow(12);\r
+ cell = row.createCell(0);\r
+ cell.setCellValue("Cabbage");\r
+ cell = row.createCell(1);\r
+ cell.setCellValue("Cauliflower");\r
+ cell = row.createCell(2);\r
+ cell.setCellValue("Potato");\r
+ cell = row.createCell(3);\r
+ cell.setCellValue("Onion");\r
+ cell = row.createCell(4);\r
+ cell.setCellValue("Beetroot");\r
+ cell = row.createCell(5);\r
+ cell.setCellValue("Asparagus");\r
+ cell = row.createCell(6);\r
+ cell.setCellValue("Spinach");\r
+ cell = row.createCell(7);\r
+ cell.setCellValue("Chard");\r
+ name = dataSheet.getWorkbook().createName();\r
+ name.setRefersToFormula("$A$13:$H$13");\r
+ name.setNameName("VEGETABLE");\r
+\r
+ row = dataSheet.createRow(13);\r
+ cell = row.createCell(0);\r
+ cell.setCellValue("Bauxite");\r
+ cell = row.createCell(1);\r
+ cell.setCellValue("Quartz");\r
+ cell = row.createCell(2);\r
+ cell.setCellValue("Feldspar");\r
+ cell = row.createCell(3);\r
+ cell.setCellValue("Shist");\r
+ cell = row.createCell(4);\r
+ cell.setCellValue("Shale");\r
+ cell = row.createCell(5);\r
+ cell.setCellValue("Mica");\r
+ name = dataSheet.getWorkbook().createName();\r
+ name.setRefersToFormula("$A$14:$F$14");\r
+ name.setNameName("MINERAL");\r
+ }\r
+}\r