Calculations
Sometimes, it might be impossible to show the necessary information on the output form using only data binding. You might for example want to show a total at the end of an invoice, containing the sum of all items ordered in their respective quantities, multiplied by the VAT. Or just format the time/date to your region standard.
In order to simplify processing of the data without the need for pre-processing, iText DITO can handle many straightforward and more complex calculations.
Inserting a Calculation
Calculations can be inserted into rich text elements. To insert a calculation, click the f(x) icon in the command bar. Bear in mind that it can be hidden under the ellipsis (three vertical dots) icon.
Straightforward Calculations
iText DITO supports the following functions:
Function | Description | Example |
---|---|---|
sum() | calculates the sum of the arguments | sum({{field1}}+{{field2}}) or sum({{field1}}-{{field2}}) |
product() | calculates the product of the arguments | product({{field1}}*{{field2}}) or product({{field1}}/{{field2}}) |
concat() | concatenates text strings | concat({{first_name}},' ',{{last_name}}) |
size() | calculates the number of items in an array | size({{items}}) |
numberToText() | converts a numerical value into a text string. Optionally you can add a locale. | numberToText({{numerical_field}}, 'en-us') |
moneyToText() | converts a numerical value to a text string, with a currency name. | moneyToText({{numerical_field}}, 'en-us') |
And the following operators:
"+", "-", "*", "/"
Example
Imagine you are designing a report on consumption of service hours. The customer has a certain entitlement of support hours and has consumed some of those. Your report should calculate the total amount due for the hours consumed and the remainder of the entitlement. The data contains only these fields:
{{service_hour_entitlement}}, {{service_hour_consumption}}, {{service_hour_unit_price}}
To calculate the total amount due, you can use the product() function
To calculate the remainder of the service entitlement, you can use the sum() function
Calculations within Loops
All of the straightforward calculations can be used inside a repeatable element, like a table row that repeats for all items on an invoice template. In that case make sure to use relative references to the data elements.
Supported Calculations
It is also possible to calculate a field using other fields which are the results of calculations themselves. In order to perform calculations on the variables in a field, you must name the fields. The field names act as variables that you can use in mathematical expressions.
Arguments are the names of the fields that are referred in the calculation expression. Function arguments refer to the fields in the way similar to binding. The reason they refer to fields is that some fields may not be bound to a value, e.g. calculated fields. If you want to use a specific value from provided data, you can create a hidden field with read-only binding.
If you want to calculate the function based on the variable number of fields all of which have the same name, you can also use the "[*]
" notation.
You can also enter expressions in a free form. The supported mathematical operators are "+
", "*
", "-
", "/
". We also support relative operators: ">
", "<
", ">=
", "<=
", negation operator: "!
", equality operators: "==
", "!=
", and if else operator: "?:
"
See below the current supported calculations:
sum(...)
- sums passed arguments, accepts varargs, requires at least one parameterproduct(...)
- multiplies passed arguments, accepts varargs, requires at least one parameterconcat(...)
- concatenates string representation of passed arguments, accepts varargs, requires at least one parameter. Next to the arguments to be concatenated,concat
function accepts an optional named parameter calledseparator
which specifies delimiter to be used during concatenation. By default the delimiter is empty string, i.e. all the strings are just appended one to another sequentially.moneyToText(value, locale)
- converts number to text in local language with local currency names.locale
is an optional parameter. Element locale will be used by default.numberToText(value, locale)
- converts number to text in local language.locale
is an optional parameter. Element locale will be used by default.min(...)
- finds minimal argument, accepts varargs, requires at least one parametermax(...)
- finds maximal argument, accepts varargs, requires at least one parameter- (deprecated)
contains(string, substring)
- checks whetherstring
containssubstring
, requires at least two parameter stringContains(string, substring, [ignoreCase=true|false])
- checks whetherstring
containssubstring,
accepts optionalignoreCase
argument (default value isfalse
), requires at least two parametersstringEquals(first, second, [ignoreCase=true|false])
- checks whether string first is equal to stringsecond,
accepts optionalignoreCase
argument (default value isfalse
), requires at least two parametersisEmpty(string)
- checks whetherstring
is an empty string""
isBlank(string)
- checks whetherstring
is an empty string""
or consist only of spaces e.g." "
size(...)
- gets the number of passed arguments, accepts varargs (e.g.size({{array[*]}})
will return number of elements inarray
indata
)filterNotNull(...)
- filters passed arguments and leaves only notnull
values, accepts varargs e.g.filterNotNull({{array[*]}})
. Is intended to be used as intermediate function in other functions that accepts varargs e.g.size(filterNotNull({{array[*]}}))
will return number of notnull
elements inarray
.currentTimestamp()
- returns current date/time in ISO-8601 format.formatDate(date, pattern, timeZone, locale)
- formats the date to text using the pattern.parseDate(date, pattern, timeZone, locale)
- parse date text into ISO-8601 format.formatNum(num, pattern, locale, currencySymbol, groupingSeparator, decimalSeparator)
- formats number to text using specified pattern.parseNum(num, pattern, locale, currencySymbol, groupingSeparator, decimalSeparator)
- parses number text using pattern provided.
Example
In the example below the aim is to calculate a grand total based on calculated subtotals.
First, create a table with repeating rows for each item in an array. In the last cell of the row, insert a rich text element with a product() calculation.
To be able to use that product() in another calculation, give the rich text element a name.
You can now use this name in other calculations, for instance to calculate the grand total. Note that you don't use double curly braces to refer to this named field. the double curly braces are only used to refer to elements in the data sample.