Document Generator MS Word Tags

A "tag" refers to an expression that the Document Generator can replace in a document template using JSON data.

Data

The JSON data can be stored in Object Storage or specified inline in a request.

Example - Stored in Object Storage

  "data": {    
    "source": "OBJECT_STORAGE",
    "namespace": "my_namespace",
    "bucketName": "my_bucket",
    "objectName": "my_folder/names.json"
  }

Example - Specified inline in data.content

  "data": {
    "source": "INLINE",
    "content": [{"name":"John"},{"name":"Monica"}]
  }

Tags

Tags contain paths to some value in JSON data. For example, given this data:

{
  "customer": {
    "first_name": "Jack",
    "last_name": "Smith"
  }
}

You could use this template:

Hello {customer.first_name} {customer.last_name}!

To generate this text:

Hello Jack Smith!

Note that JSON keys are case-sensitive. first_name and First_Name are different JSON keys.

Vertical Loop Tag

Syntax: {#loop}...{/loop}

A {#loop} tag is used to produce copies of a section of text vertically.

List Example

Data

{
  "class_list": [
    {
      "name": "Sue",
      "student_id": 1
    },
    {
      "name": "Bob",
      "student_id": 2
    },
    {
      "name": "Jean",
      "student_id": 3
    }
  ]
}

Template

Class List
{#class_list}* {student_id}: {name}
{/class_list}

Result

Class List
* 1: Sue
* 2: Bob
* 3: Jean

Table Example

Data

{
  "class_list": [
    {
      "name": "Sue",
      "student_id": 1
    },
    {
      "name": "Bob",
      "student_id": 2
    },
    {
      "name": "Jean",
      "student_id": 3
    }
  ]
}

Template

IdName
{#class_list}{student_id}{name}{/class_list}

Result

IdName
1Sue
2Bob
3Jean

Vertical Array Operations

Filter

The filter operation takes three arguments:

  1. The property to filter on
  2. The comparison to perform
  3. The value to compare against

Currently, filtering is only supported on numeric types.

To use a filter, you must specify a new list, called {#filtered}...{/filtered}, inside the parent array being filtered.

Example

Data

{
  "products": [
    {
      "price": 1,
      "name": "Belt",
      "category": "Accessory"
    },
    {
      "price": 3,
      "name": "Shirt",
      "category": "Clothing"
    },
    {
      "price": 2,
      "name": "Hat",
      "category": "Accessory"
    }
  ]
}

Template

{#products|filter:price:>=:2}

CategoryNamePrice
{#filtered}{category}{name}{price}{/filtered}

{/products|filter:price:>=:2}

Result

CategoryNamePrice
ClothingShirt3
AccessoryHat2

Sort

The sort operation takes two arguments:

  1. The name of the property to use for sorting
  2. asc or desc to sort the list in ascending or descending order.

To use a sort, you must specify a new list, called {#sorted}...{/sorted}, inside the parent array being sorted.

Example

Data

{
  "products": [
    {
      "price": 1,
      "name": "Belt",
      "category": "Accessory"
    },
    {
      "price": 3,
      "name": "Shirt",
      "category": "Clothing"
    },
    {
      "price": 2,
      "name": "Hat",
      "category": "Accessory"
    }
  ]
}

Template

{#products|sort:price:desc}

CategoryNamePrice
{#sorted}{category}{name}{price}{/sorted}

{/products|sort:price:desc}

Result

CategoryNamePrice
ClothingShirt3
AccessoryHat2
AccessoryBelt1

Distinct

The distinct operation takes a single argument:

  1. The name of the property to select distinct values of.

Example

Data

{
  "products": [
    {
      "price": 1,
      "name": "Belt",
      "category": "Accessory"
    },
    {
      "price": 3,
      "name": "Shirt",
      "category": "Clothing"
    },
    {
      "price": 2,
      "name": "Hat",
      "category": "Accessory"
    }
  ]
}

Template

Categories:
{#products|distinct:category}

* {category}
  {/products|distinct:category}

Result

Categories:

* Accessory
* Clothing

Break

The break operator groups items together based on a shared property. It takes up to two arguments:

  1. The name of the property to group items on.
  2. asc or desc to sort the properties in ascending or descending order. This is optional, and defaults to the natural order.

To use a break, you must specify a new list, called {#break}...{/break}, inside the parent array being broken into groups.

Example

In this example note that the "Belt" and "Hat" items shared a category ("Accessory"), but they are not grouped in the array ("Belt" is the first item in the array and "Hat" is the last item).

Once the break operator has been applied, the items are grouped together in the output.

Data

{
  "products": [
    {
      "price": 1,
      "name": "Belt",
      "category": "Accessory"
    },
    {
      "price": 3,
      "name": "Shirt",
      "category": "Clothing"
    },
    {
      "price": 2,
      "name": "Hat",
      "category": "Accessory"
    }
  ]
}

Template

{#products|break:category}
{#break}* Category:{category}, Product:{name}
{/break}
{/products|break:category}

Result

* Category:Accessory, Product:Belt
* Category:Accessory, Product:Hat
* Category:Clothing, Product:Shirt

Group

Splits an array into subarrays of the given size. A single argument is required:

  1. An integer specifying the group size.

To use a group, you must specify a new list, called {#group}...{/group}, inside the parent array being grouped.

If the array does not split perfectly into groups, the last group will be of smaller size. For example, if you have an array of 5 items, and you use group:2 on it, then two groups of two items and one group of one item will be created.

Example

Data

{
  "products": [
    {
      "price": 1,
      "name": "Belt",
      "category": "Accessory"
    },
    {
      "price": 3,
      "name": "Shirt",
      "category": "Clothing"
    },
    {
      "price": 2,
      "name": "Hat",
      "category": "Accessory"
    }
  ]
}

Template

{#products|group:2}Items
{#group}* {name}
{/group}
{/products|group:2}

Result

Items
* Belt
* Shirt
Items
* Hat

Horizontal Loop Tag

Syntax: {:loop}...{/loop}

A {:loop} tag is used to produce copies of a section of text horizontally.

Table Example

Data

{
  "weekdays": [
    {
      "name": "Monday"
    },
    {
      "name": "Tuesday"
    },
    {
      "name": "Wednesday"
    },
    {
      "name": "Thursday"
    },
    {
      "name": "Friday"
    }
  ]
}

Template

Days{:weekdays}{name}{/weekdays}

Result

DaysMondayTuesdayWednesdayThursdayFriday

Aggregators

Sum

The Sum Aggregator is used to calculate the sum of an array.

Example

Data

{
  "items": [
    {
      "name": "ball",
      "price": 1
    },
    {
      "name": "stick",
      "price": 2
    },
    {
      "name": "cup",
      "price": 3
    }
  ]
}

Template

Total Price: {items|sum:price}

Result

Total Price: 6

Average

The Average Aggregator is used to calculate the average of an array.

Example

Data

{
  "items": [
    {
      "name": "ball",
      "price": 1
    },
    {
      "name": "stick",
      "price": 2
    },
    {
      "name": "cup",
      "price": 3
    }
  ]
}

Template

Average Price: {items|avg:price}

Result

Average Price: 2

Max

The Max Aggregator is used to find the maximum value of an array.

Example

Data

{
  "items": [
    {
      "name": "ball",
      "price": 1
    },
    {
      "name": "stick",
      "price": 2
    },
    {
      "name": "cup",
      "price": 3
    }
  ]
}

Template

Max Price: {items|max:price}

Result

Max Price: 3

Min

The Min Aggregator is used to find the minimum value of an array.

Example

Data

{
  "items": [
    {
      "name": "ball",
      "price": 1
    },
    {
      "name": "stick",
      "price": 2
    },
    {
      "name": "cup",
      "price": 3
    }
  ]
}

Template

Minimum Price: {items|min:price}

Result

Minimum Price: 1

Conditional Tags

# Tag

Syntax: {#expression}...{/expression} An {#expression} tag in a document displays a section only if the expression resolves to true. The expression can be either a reference to a non-array property in your JSON data or a boolean expression like expr(age<18). See the section below on conditional expressions.

Notes

  • A condition evaluates to false when the referenced JSON property is false, an empty string (""), an empty array ([]), null, or missing. If the JSON property has any other value, the section is displayed.
  • If the referenced JSON property has an array value, the tag behaves as a loop tag and duplicates the section for each iteration. See Vertical Loop Tag.

Example

Data

{
  "address": "123 Main street",
  "nullValue": null,
  "falseValue": false,
  "empty_string": ""
}

Template

Displayed
1. {#address}An address: {address}{/address}
2. {#expr(address == "123 Main street")}The address: {address}{/expr(address == "123 Main street")} 

Hidden
1. {#expr(address != "123 Main street")}Expression resolves to false: {address}{/expr(address != "123 Main street")}
2. {#missing_value} Condition is missing in JSON: {address}{/missing_value}
3. {#nullValue}Condition is null: {address}{/nullValue}
4. {#falseValue}Condition is Boolean false: {address}{/falseValue}
5. {#empty_string}Condition is an empty string: {address}{/empty_string}

End of document

Result

Displayed
1. An address: 123 Main street
2. The address: 123 Main street

Hidden
1.
2.
3.
4.
5.

End of document

Image Tag

Syntax: {%dataRef}, where dataRef is a reference to an image object in your JSON data. Example: {%my_image}.

An image tag is used to insert an image into a document. Images can be provided from an OCI Object Storage bucket or from a URL. Images must be provided as an object, for example:

{
  "my_image": {
    "source": "OBJECT_STORAGE",
    "objectName": "image.png",
    "namespace": "object_storage_namespace",
    "bucketName": "my_bucket_name",
    "mediaType": "image/png"
  }
}

Note: an image tag can be used in a watermark. In that case, the image will replace the entire watermark text, and any other tags in the watermark will be ignored.

General

The specific schema for each source type is described below. You can also include the following optional properties in the image object to control image formatting:

  • width: A string of digits, followed by unit of measure. E.G. 200px. Sets the width of the image.
  • height: A string of digits, followed by unit of measure. E.G. 200px. Sets the height of the image.
  • alt_text: A string. This will be set as the alternative text of the image.

Supported units of measure:

Document Generator supports the following units of measure for images:

  • px (pixels)
  • in (inches)
  • cm (centimeters)
  • % (percentage)

Default size of inserted images:

  • Smaller images: If an image is smaller than the page size, the original size is preserved.
  • Larger images: If an image is larger than the page size, it is resized to fit within the page width and height. The aspect ratio of the image is maintained.

Image scaling:

If only one image dimension is provided, the Document Generator will calculate a scaled value for the missing dimension in order to preserve aspect ratio. For instance:

  • If you provide a width, but no height, a scaled height will be calculated based on the image's native dimensions and the provided width.
  • If you provide a height, but no width, a scaled width will be calculated based on the image's native dimensions and the provided height.

Supported Formats

Document Generator supports the following image formats:

  • PNG
  • JPG
  • GIF
  • BMP

Schemas

OCI Object Storage

  • source: must be set to OBJECT_STORAGE
  • objectName: The path and name of the file
  • namespace: The namespace of your object storage bucket
  • bucketName: The name of the bucket that contains the file
  • mediaType: The Media Type (MIME) of the image

Example

Data
{
  "my_image": {
    "source": "OBJECT_STORAGE",
    "objectName": "image.png",
    "namespace": "object_storage_namespace",
    "bucketName": "my_bucket_name",
    "mediaType": "image/png",
    "width": "400px",
    "height": "200px"
  }
}
Template
{%my_image}
Result

Result

URL

  • source: must be set to URL
  • url: the image URL in string format

Note: to use images from the Internet, Document Generator needs outbound access to the Internet. For example, if Document Generator is running in a private subnet in OCI, you could set up a NAT Gateway to allow Document Generator to connect to the Internet.

Example

Data
{
  "my_image": {
    "source": "URL",
    "url": "https://www.oracle.com/.../.jpg"
  }
}
Template
{%my_image}
Result

Result

Data URL

Document Generator also supports images provided as Data URLs. The image must be Base64-encoded.

  • source: must be set to URL
  • url: the image URL in string format

Example

Data
{
  "my_image": {
    "source": "URL",
    "url": "data:image/png;base64,iVBORw0KG...go"
  }
}
Template
{%my_image}
Result

Result

Page Break and Column Break Tag

Syntax: {?pagebreak} and {?columnbreak}

{?my_value} resolves a value from your data and inserts a:

  • Page break when the JSON value is a boolean true or a string equal to one of : pagebreak, page, true
  • Column break when the JSON value is a string equal to one of : columnbreak, column

Note that {?true} also inserts a page break.

Number Formatting

If a value supplied to a {basic} tag is a number, Document Generator can format it.

A formatter is specified as follows: {input_number|format:[format]:[separators]:[currency_symbol]} where:

  • [format] is a supported number format
  • [separators] (optional) is a 2 character string. The first character indicates the decimal separator, the second character indicates the comma separator
  • [currency_symbol] (optional) the currency symbol to apply if L is present in [format]

Number formats must be specified in one of the following Oracle Number Formats:

  • FML999G999G999G999G990D00
  • FML999G999G999G999G990
  • 999G999G999G999G990D00
  • 999G999G999G999G990D0000
  • 999G999G999G999G999G999G990
  • 999G999G999G999G990D00MI
  • S999G999G999G999G990D00
  • 999G999G999G999G990D00S
  • S999G999G999G999G990D00
  • 999G999G999G999G990D00PR
  • FML999G999G999G999G990PR
  • 999G999G999G999G990D00PR

Examples

The following table shows examples of these formats, given a number:

Templateunit_price: 1234.5unit_price: -1234.5
{unit_price|format:"FML999G999G999G999G990D00":"<>":"$"}$1>234<50-$1>234<50
{unit_price|format:"999G999G999G999G990D00":",."}1.234,50-1.234,50
{unit_price|format:"999G999G999G999G990D00":", "}1 234,50-1 234,50
{unit_price|format:"999G999G999G999G999G999G990"}1,234-1,234
{unit_price|format:"999G999G999G999G990D00MI"}1,234.501,234.50-
{unit_price|format:"S999G999G999G999G990D00"}+1,234.50-1,234.50
{unit_price|format:"999G999G999G999G990D00PR"}1,234.50<1,234.50>
{unit_price|format:"FML999G999G999G999G990PR"}$1,234<$1,234>

Date Formatting

If a value supplied to a {basic} tag is an ISO 8601 date-time, Document Generator can format it.

Time Zone considerations:

  • Input: When the time zone is not specified in the input date-time, UTC is used.
  • Output: When the time zone is not specified in the output date, the input time zone is used.

A formatter is specified as follows: {input_date|format_date:[format]:[time_zone]} where:

  • [format] is a supported date-time format
  • [time_zone] (optional) is a character string representing a time zone, such as America/Los_Angeles, UTC or +09:30.

Date-time output formats must be specified as a Java DateTime Formats.

Examples

The following table shows examples of these formats, given a date with a time zone:

Templateinput_date: 2023-12-31T23:01:22-04:00
{input_date|format_date:"dd-MM-yy HH:mm:ss"}31-12-23 23:01:22
{input_date|format_date:dd/MM/yyyy}31/12/2023
{input_date|format_date:"MMM dd, yyyy HH:mm:ss"}Dec 31, 2023 23:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"America/Los_Angeles"}2023-12-31 19:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"UTC"}2024-01-01 03:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"Z"}2024-01-01 03:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"+09:30"}2024-01-01 12:31:22

The following table shows examples of these formats, given a date without a time zone:

Templateinput_date: 2023-12-31T23:01:22
{input_date|format_date:"dd-MM-yy HH:mm:ss"}31-12-23 23:01:22
{input_date|format_date:dd/MM/yyyy}31/12/2023
{input_date|format_date:"MMM dd, yyyy HH:mm:ss"}Dec 31, 2023 23:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"America/Los_Angeles"}2023-12-31 15:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"UTC"}2023-12-31 23:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"Z"}2023-12-31 23:01:22
{input_date|format_date:"yyyy-MM-dd HH:mm:ss":"+09:30"}2024-01-01 08:31:22

Conditional expressions

For some Tags, Document Generator can use expressions that resolve to true or false.

These expressions combine JSON data references, operators (like == and <), built-in functions (like StartsWith) and literals (like "John" or 23).

Rules

  • String comparisons are case-sensitive and use Unicode code-point comparison with NFC normalization.
  • Operators are evaluated from left to right; precedence is: parentheses, comparisons, &&, then ||. Short-circuiting applies to && and ||.
  • Types are strict: numeric comparisons require numbers; equality only compares string-to-string, number-to-number, boolean-to-boolean. No cross-type coercion.
  • JSON data references must be composed of letters (a-z, A-Z), underscores (_) or digits (0-9). The first character must be a letter or an underscore.
  • Missing or null JSON data results in the expression resolving to false when evaluated.
  • Invalid expression syntax in the template causes Document Generator to stop and return an error.

List of supported Operators

NameDescriptionExample
==True if the left operand is equal to the right operandage == 18
!=True if the left operand is not equal to the right operandage != 18
>True if the left operand is greater than the right operandage > 18
>=True if the left operand is greater than or equal to the right operandage >= 18
<True if the left operand is less than the right operandage < 18
<=True if the left operand is less than or equal to the right operandage <= 18
&&True if the left expression and the right expression are truea == 0 && c == 42
||True if the left expression or the right expression is truea == 0 || c == 42

List of supported Functions

NameDescriptionExample
StartsWithData reference starts with given stringStartsWith(movieName, "The")
StartsWithIgnoreCaseData reference starts with given string (case-insensitive)StartsWithIgnoreCase(movieName, "the")
ContainsData reference contains the given stringContains(movieName, "Matrix")
ContainsIgnoreCaseData reference contains the given string (case-insensitive)ContainsIgnoreCase(movieName, "matrix")

Examples

ExpressionComment
age >= 18
a == b || c == d && e > 0c == d && e > 0 is evaluated before a == b
(title=="manager" || title == "director") && employeeCount > 2Parentheses can be used
StartsWith(movieName, "The") && year == 1999Function StartsWith used
Contains(movieName, "Matrix") || movies.0.actor != "Pitt"Function Contains used. Referring to first actor in movies array
(numberOfTomatoes > maxTomatoes) == falseSame as numberOfTomatoes <= maxTomatoes
-1 >= -1.01 || UnknownName == "Smith"Since first part is true, UnknownName == "Smith" is not evaluated
Contains(drink, "Cafe\u0301")Unicode characters are supported