6.5. Using Decision Tables in Spreadsheets
6.5.1. Decision Tables in Spreadsheets
Note
6.5.2. OpenOffice Example

Figure 6.3. OpenOffice Screenshot
Note
6.5.3. Rules and Spreadsheets
- Rules inserted into rows
- As each row is a rule, the same principles apply as with written code. As the rule engine processes the facts, any rules that match may fire.
- Agendas
- It is possible to clear the agenda when a rule fires and simulate a very simple decision table where only the first match effects an action.
- Multiple tables
- You can have multiple tables on one spreadsheet. This way, rules can be grouped where they share common templates, but are still all combined into one rule package.
6.5.4. The RuleTable Keyword
Important
6.5.5. The RuleSet Keyword
6.5.6. Rule Template Example
- Store your data in a database (or any other format)
- Conditionally generate rules based on the values in the data
- Use data for any part of your rules (such as condition operator, class name, and property name)
- Run different templates over the same data

Figure 6.4. Template Data

Figure 6.5. Rule Template
- Line 1: All rule templates start with template header.
- Lines 2-4: Following the header is the list of columns in the order they appear in the data. In this case we are calling the first column age, the second type and the third log.
- Line 5: An empty line signifies the end of the column definitions.
- Lines 6-9: Standard rule header text. This is standard rule DRL and will appear at the top of the generated DRL. Put the package statement and any imports and global and function definitions into this section.
- Line 10: The keyword template signals the start of a rule template. There can be more than one template in a template file, but each template must have a unique name.
- Lines 11-18: The rule template.
- Line 20: The keywords end template signify the end of the template.
@{token_name}. The built-in expression @{row.rowNumber} gives a unique number for each row of data and enables you to generate unique rule names. For each row of data, a rule is generated with the values in the data substituted for the tokens in the template. With the example data above, the following rule file is generated:
package org.drools.examples.templates;
global java.util.List list;
rule "Cheese fans_1"
when
Person(age == 42)
Cheese(type == "stilton")
then
list.add("Old man stilton");
end
rule "Cheese fans_2"
when
Person(age == 21)
Cheese(type == "cheddar")
then
list.add("Young man cheddar");
endDecisionTableConfiguration dtableconfiguration =
KnowledgeBuilderFactory.newDecisionTableConfiguration();
dtableconfiguration.setInputType( DecisionTableInputType.XLS );
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newClassPathResource( getSpreadsheetName(),
getClass() ),
ResourceType.DTABLE,
dtableconfiguration );6.5.7. Data-Defining Cells
RuleSet, defines all DRL items except rules. The other one may occur repeatedly and is to the right and below a cell whose contents begin with RuleTable. These areas represent the actual decision tables, each area resulting in a set of rules of similar structure.
RuleSet cell and containing a keyword designating the kind of value contained in the other one that follows in the same row.
6.5.8. Rule Table Columns
RuleTable are earmarked as header area, mostly used for the definition of code to construct the rules. It is any additional row below these four header rows that spawns another rule, with its data providing for variations in the code defined in the Rule Table header.
Note
6.5.9. Rule Set Entries
RuleSet is upheld as the one containing the keyword.
6.5.10. Entries in the Rule Set Area
Table 6.1. Entries in the Rule Set area
| Keyword | Value | Usage |
|---|---|---|
| RuleSet | The package name for the generated DRL file. Optional, the default is rule_table. | Must be First entry. |
| Sequential | "true" or "false". If "true", then salience is used to ensure that rules fire from the top down. | Optional, at most once. If omitted, no firing order is imposed. |
| EscapeQuotes | "true" or "false". If "true", then quotation marks are escaped so that they appear literally in the DRL. | Optional, at most once. If omitted, quotation marks are escaped. |
| Import | A comma-separated list of Java classes to import. | Optional, may be used repeatedly. |
| Variables | Declarations of DRL globals, i.e., a type followed by a variable name. Multiple global definitions must be separated with a comma. | Optional, may be used repeatedly. |
| Functions | One or more function definitions, according to DRL syntax. | Optional, may be used repeatedly. |
| Queries | One or more query definitions, according to DRL syntax. | Optional, may be used repeatedly. |
| Declare | One or more declarative types, according to DRL syntax. | Optional, may be used repeatedly. |
6.5.11. Rule Attribute Entries in the Rule Set Area
Important
Table 6.2. Rule Attribute Entries in the Rule Set Area
| Keyword | Initial | Value |
|---|---|---|
| PRIORITY | P | An integer defining the "salience" value for the rule. Overridden by the "Sequential" flag. |
| DURATION | D | A long integer value defining the "duration" value for the rule. |
| TIMER | T | A timer definition. See "Timers" section. |
| CALENDARS | E | A calendars definition. See "Calendars" section. |
| NO-LOOP | U | A Boolean value. "true" inhibits looping of rules due to changes made by its consequence. |
| LOCK-ON-ACTIVE | L | A Boolean value. "true" inhibits additional activations of all rules with this flag set within the same ruleflow or agenda group. |
| AUTO-FOCUS | F | A Boolean value. "true" for a rule within an agenda group causes activations of the rule to automatically give the focus to the group. |
| ACTIVATION-GROUP | X | A string identifying an activation (or XOR) group. Only one rule within an activation group will fire, i.e., the first one to fire cancels any existing activations of other rules within the same group. |
| AGENDA-GROUP | G | A string identifying an agenda group, which has to be activated by giving it the "focus", which is one way of controlling the flow between groups of rules. |
| RULEFLOW-GROUP | R | A string identifying a rule-flow group. |
| DATE-EFFECTIVE | V | A string containing a date and time definition. A rule can only activate if the current date and time is after DATE-EFFECTIVE attribute. |
| DATE-EXPIRES | Z | A string containing a date and time definition. A rule cannot activate if the current date and time is after the DATE-EXPIRES attribute. |
6.5.12. The RuleTable Cell
6.5.13. Column Types
6.5.14. Column Headers in the Rule Table
Table 6.3. Column Headers in the Rule Table
| Keyword | Initial | Value | Usage |
|---|---|---|---|
| NAME | N | Provides the name for the rule generated from that row. The default is constructed from the text following the RuleTable tag and the row number. | At most one column |
| DESCRIPTION | I | A text, resulting in a comment within the generated rule. | At most one column |
| CONDITION | C | Code snippet and interpolated values for constructing a constraint within a pattern in a condition. | At least one per rule table |
| ACTION | A | Code snippet and interpolated values for constructing an action for the consequence of the rule. | At least one per rule table |
| METADATA | @ | Code snippet and interpolated values for constructing a metadata entry for the rule. | Optional, any number of columns |
6.5.15. Conditional Elements
- Text in the first cell below CONDITION develops into a pattern for the rule condition, with the snippet in the next line becoming a constraint. If the cell is merged with one or more neighbours, a single pattern with multiple constraints is formed: all constraints are combined into a parenthesized list and appended to the text in this cell. The cell may be left blank, which means that the code snippet in the next row must result in a valid conditional element on its own.To include a pattern without constraints, you can write the pattern in front of the text for another pattern.The pattern may be written with or without an empty pair of parentheses. A "from" clause may be appended to the pattern.If the pattern ends with "eval", code snippets are supposed to produce boolean expressions for inclusion into a pair of parentheses after "eval".
- Text in the second cell below CONDITION is processed in two steps.
- The code snippet in this cell is modified by interpolating values from cells farther down in the column. If you want to create a constraint consisting of a comparison using "==" with the value from the cells below, the field selector alone is sufficient. Any other comparison operator must be specified as the last item within the snippet, and the value from the cells below is appended. For all other constraint forms, you must mark the position for including the contents of a cell with the symbol
$param. Multiple insertions are possible by using the symbols$1,$2, etc., and a comma-separated list of values in the cells below.A text according to the patternforall(delimiter){snippet}is expanded by repeating the snippet once for each of the values of the comma-separated list of values in each of the cells below, inserting the value in place of the symbol$and by joining these expansions by the given delimiter. Note that the forall construct may be surrounded by other text. - If the cell in the preceding row is not empty, the completed code snippet is added to the conditional element from that cell. A pair of parentheses is provided automatically, as well as a separating comma if multiple constraints are added to a pattern in a merged cell.If the cell above is empty, the interpolated result is used as is.
- Text in the third cell below CONDITION is for documentation only. It should be used to indicate the column's purpose to a human reader.
- From the fourth row on, non-blank entries provide data for interpolation as described above. A blank cell results in the omission of the conditional element or constraint for this rule.
6.5.16. Action Statements
- Text in the first cell below ACTION is optional. If present, it is interpreted as an object reference.
- Text in the second cell below ACTION is processed in two steps.
- The code snippet in this cell is modified by interpolating values from cells farther down in the column. For a singular insertion, mark the position for including the contents of a cell with the symbol
$param. Multiple insertions are possible by using the symbols$1,$2, etc., and a comma-separated list of values in the cells below.A method call without interpolation can be achieved by a text without any marker symbols. In this case, use any non-blank entry in a row below to include the statement.The forall construct is available here, too. - If the first cell is not empty, its text, followed by a period, the text in the second cell and a terminating semicolon are stringed together, resulting in a method call which is added as an action statement for the consequence.If the cell above is empty, the interpolated result is used as is.
- Text in the third cell below ACTION is for documentation only. It should be used to indicate the column's purpose to a human reader.
- From the fourth row on, non-blank entries provide data for interpolation as described above. A blank cell results in the omission of the action statement for this rule.
Note
$1 instead of $param will fail if the replacement text contains a comma.
6.5.17. Metadata Statements
- Text in the first cell below METADATA is ignored.
- Text in the second cell below METADATA is subject to interpolation, as described above, using values from the cells in the rule rows. The metadata marker character
@is prefixed automatically, and should not be included in the text for this cell. - Text in the third cell below METADATA is for documentation only. It should be used to indicate the column's purpose to a human reader.
- From the fourth row on, non-blank entries provide data for interpolation as described above. A blank cell results in the omission of the metadata annotation for this rule.
6.5.18. Interpolating Cell Data Example
- If the template is
Foo(bar == $param)and the cell is42, then the result isFoo(bar == 42). - If the template is
Foo(bar < $1, baz == $2)and the cell contains42,43, the result will beFoo(bar < 42, baz ==43). - The template
forall(&&){bar != $}with a cell containing42,43results inbar != 42 && bar != 43.
6.5.19. Tips for Working Within Cells
- Multiple package names within the same cell must be comma-separated.
- Pairs of type and variable names must be comma-separated.
- Functions must be written as they appear in a DRL file. This should appear in the same column as the "RuleSet" keyword. It can be above, between or below all the rule rows.
- You can use Import, Variables, Functions and Queries repeatedly instead of packing several definitions into a single cell.
- Trailing insertion markers can be omitted.
- You can provide the definition of a binding variable.
- Anything can be placed in the object type row. Apart from the definition of a binding variable, it could also be an additional pattern that is to be inserted literally.
- The cell below the ACTION header can be left blank. Using this style, anything can be placed in the consequence, not just a single method call. (The same technique is applicable within a CONDITION column.)
6.5.20. The SpreadsheetCompiler Class
SpreadsheetCompiler class is the main class used with API spreadsheet-based decision tables in the drools-decisiontables module. This class takes spreadsheets in various formats and generates rules in DRL.
SpreadsheetCompiler can be used to generate partial rule files and assemble them into a complete rule package after the fact. This allows the separation of technical and non-technical aspects of the rules if needed.
6.5.21. Using Spreadsheet-Based Decision Tables
Procedure 6.5. Task
- Generate a sample spreadsheet that you can use as the base.
- If the JBoss BRMS plug-in is being used, use the wizard to generate a spreadsheet from a template.
- Use an XSL-compatible spreadsheet editor to modify the XSL.
6.5.22. Lists
lists of values. These can be stored in other worksheets to provide valid lists of values for cells.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.