Skip to main content

JSON


DynamicPDF Designer uses JSON data to create a report.

Designer uses JSON as the data structure for providing data to DLEX documents created using Designer. The JSON document consist of top-level data followed by one or more arrays. Layout data can consist of named and unnamed objects.

DLEX report JSON data is driven by an array where each element in the array is a line of data in the report.

Figure 1. JSON element in an array.

Think of your JSON document like this: top-level JSON elements are for static placement, the first JSON array after top-level elements is for the report, then any nested arrays are for subreports.

tip

If you use Microsoft SQL Server as your database, then an easy way to work with a JSON document is by using the for json auto clause in your SQL statement. For example, the following SQL statement produces a JSON document.

select CategoryName Name, ProductID, ProductName, QuantityPerUnit, Discontinued, UnitPrice  from Products, Categories as ProductsByCategory
where Products.CategoryID = ProductsByCategory.CategoryID
order by CategoryName
for json auto, root('ProductsByCategory')
{
"ProductsByCategory": [
{
"Name": "Beverages",
"Products": [
{
"ProductID": 1,
"ProductName": "Chai",
"QuantityPerUnit": "10 boxes x 20 bags",
"Discontinued": false,
"UnitPrice": 18
},
{
"ProductID": 2,
"ProductName": "Chang",
"QuantityPerUnit": "24 - 12 oz bottles",
"Discontinued": false,
"UnitPrice": 19
}
]
}
]
}

Top Level Elements

Top level elements are ideal for using on a cover page. JSON data from top-level elements can be placed on a page or any report section.

{
"ReportName": "Widget Stock By Region State and City",
"Date": "09/21/2021",
"Author": "John Doe"
}

Figure 2. Using top-level JSON elements in a Page.

tip

If creating a header with static top-level JSON fields, consider using a Subreport rather than a header or conditional header.

Repeating Data Elements

Use an array to represent JSON data as data rows. For example, in the following JSON data each element in the regions array constitutes a data-row. When placed in a report's Detail section, it adds each array element as a record, and the elements within the array as fields.

{
"ReportName": "Widget Stock By Region State and City",
"Date": "09/21/2021",
"Author": "John Doe",
"regions": [
{
"name": "North East",
"description": "The north east region's stock by state.",
"units": 369444
},
{
"name": "South West",
"description": "The South West region's stock by state.",
"units": 3514011
}
]
}

For example, in the preceding JSON document, the regions array is the repeating data row.

Figure 3. The regions array in a JSON document.

Add the name, description, and units elements as RecordBox elements in the Detail section and when the PDF is generated each array element is printed as a data row.

Figure 4. Repeating data elements represented as rows in the generated PDF.

If you wish to have a header for the data, use a label for the data name.

Figure 5. Repeating data elements and labels represented as rows in a generated PDF.

Nested Arrays

JSON arrays can have nested arrays, where each nested array corresponds to a Subreport layout element. For example, in the following JSON document, the regions array is the top-level report's Detail section, while states array is a Subreport. The cities array is a nested Subreport.

info

You can nest as many Subreport layout elements as is reasonable in your DLEX report.

{
"ReportName": "Widget Stock By Region State and City",
"Date": "09/21/2021",
"Author": "John Doe",
"regions": [
{
"name": "North East",
"description": "The north east region's stock by state.",
"units": 369444,
"states": [
{
"name": "New Jersey",
"units": 22609,
"cities": [
{
"name": "Toms River",
"units": 333
},
{
"name": "Newark",
"units": 22276
}
]
},
{
"name": "New York",
"units": 346835,
"cities": [
{
"name": "Albany",
"units": 323423
},
{
"name": "Catskill",
"units": 23412
}
]
}
]
},
{
"name": "South West",
"description": "The South West region's stock by state.",
"units": 3514011,
"states": [
{
"name": "Arizona",
"units": 2156764,
"cities": [
{
"name": "Tempe",
"units": 2124312
},
{
"name": "Phoenix",
"units": 32452
}
]
},
{
"name": "New Mexico",
"units": 1357247,
"cities": [
{
"name": "Las Cruces",
"units": 1234124
},
{
"name": "Albuquerque",
"units": 123123
}
]
}
]
}
]
}

Figure 6. A nested JSON array and corresponding subreport rows.

Multiple Same-Level Arrays

Designer also supports JSON with multiple arrays on the same level. For example, the following JSON has animals and plants on the same level.

{
"store" : "petstore",
"animals": [
{
"name": "dog"
},
{
"name": "cat"
}
],
"plants": [
{
"name": "Ivy"
},
{
"name": "grass"
}
]
}

When displayed in Designer, the Data Explorer lists the top-level element, store, and then the two arrays, animals and plants.

Figure 7. Designer with two arrays on the same level.

However, notice that when adding the array to a report's details, you must select the animals array OR the plants array as the Report layout element's dataName property. If you tried to add the name under plants to the details, then Designer notifies you of the error, informing you that you must change the report's dataName to plants.

Figure 8. Designer setting data name for the report.

Multiple Arrays as Subreports

You also cannot create a subreport, as that implies that plants is nested within animals. Instead, you must treat separate arrays on the same level as different reports. Designer allows creating documents consisting of multiple reports.

Figure 9. Arrays on the same level must be in different reports.

However, you can include multiple sub arrays within a single top-level array. For example, suppose we added a top-level array named stores that contained a sub array of plants and a sub array of animals; the following JSON illustrates.

{
"stores": [
{
"name": "PetStore One",
"animals": [
{
"name": "dog"
},
{
"name": "cat"
}
],
"plants": [
{
"name": "Ivy"
},
{
"name": "grass"
}
]
},
{
"name": "PetStore Two",
"animals": [
{
"name": "dog2"
},
{
"name": "cat2"
}
],
"plants": [
{
"name": "Ivy2"
},
{
"name": "grass2"
}
]
}
]
}

What this JSON allows is a top-level report of stores, nested by two subreports, animals and plants.

Figure 10. Two subreports on the same level below stores.

Objects

The DynamicPDF Designer supports JSON data consisting of a object hierarchy. You refer to individual fields using dot (.) notation. For example, in Figure 10 the report's dataName is barrels. The repeating records are unnamed, however, consist of a nested object named content. So to refer to the nested object, when creating a data row, you would refer to the object as object-name.fieldname.

Figure 11. Report with content objects in the data array.

You are not limited to simple JSON object hierarchies. Designer supports complex JSON object hierarchys. The following JSON illustrates a more complex JSON object hierarchy.

{
"OrderID": 11077,
"OrderDate": "2019-01-06T00:00:00",
"CustomerID": "RATTC",
"ShippedDate": "2019-01-30T00:00:00",
"CustomerDetail":{
"ShipperName": "United Package",
"ShipTo": "Rattlesnake Canyon Grocery\n2817 Milton Dr.\nAlbuquerque, NM 87110\nUSA",
"BillTo": "Rattlesnake Canyon Grocery\n2817 Milton Dr.\nAlbuquerque, NM 87110\nUSA"
},
"Freight": 8.53,
"OrderDetails": [
{
"Product":{
"ID": 2,
"Name": "Chang"
},
"Quantity": 24,
"UnitPrice": 19
},
{
"Product":{
"ID": 3,
"Name": "Aniseed Syrup"
},
"Quantity": 4,
"UnitPrice": 10
},
{
"Product":{
"ID": 4,
"Name": "Chef Anton\u0027s Cajun Seasoning"
},
"Quantity": 1,
"UnitPrice": 22
},
...

The JSON consists of unnamed top-level data that contains a CustomerDetail object in addition to several other top-level fields. It then consists of an array of elements named OrderDetails. Each unnamed element in OrderDetails consists of a nested Product object and also the Quantity and Price fields.

Figure 12. Object model for JSON data.

When loading this JSON into Designer the Data Explorer shows the following data field names in a hierarchy.

Figure 13. Object model for JSON data.

The report in Figure 13 places the top-level data in the Header and the data in a subreport's Detail section. The report's header consists of the top-level data and the nested CustomerDetails. Because CustomerDetail is an object in the top-level data it refers to its fields as CustomerDetail.ShipperName, CustomerDetail.BillTo, and CustomerDetail.ShipTo.

The report's Detail section consists of a nested Subreport. The subreport's dataName is OrderDetails which is the array driving the data row generation. The subreport's Detail section contains the fields Product, Quantity, and Price. These are the fields repeated for each data row. Because Product is an object in each element of the OrderDetails array, it refers to its fields as Product.ID and Product.Name.

Figure 14. Object model for JSON data.

Generating the report results in the following PDF document.

Figure 15. Object model for JSON data.

Nested Objects

Refer to nested objects using dot notation only refer to the property using the parent object's name and the nested object's name. For example, consider the following Content object.

"Content": {
"Description": "Coffee beans from Brazil.",
"Origin": {
"Country": "Brazil",
"State" :"Sao Paulo"
},
"Type": "coffee"
}

The Content object contains a nested Origin object, therefore to refer to the Country or State property you would use Content.Origin.Country or Content.Origin.State when using it in an array as the details of a report.

  "Id":"13456X",
"Date":"11/10/2023",
"Client":"Acme Drink Company",
"Barrels": [
{
"Content": {
"Description": "Coffee beans from Brazil.",
"Origin": {
"Country": "Brazil",
"State" :"Sao Paulo"
},
"Type": "coffee"
},
"Volume": 24,
"Material": "Oak",
"Quantity": 300
},
{
"Content": {
"Description": "Burgundy wine.",
"Origin": {
"Country": "USA",
"State" :"California"
},
"Type": "burgundy"
},
"Volume": 32,
"Material": "Cedar",
"Quantity": 45
}
]
}

For example, the following report refers to the Barrels array as the report's dataName. Each array element drives one row in the report's details. Therefore, to refer to properties in the Content object such as Description, you use Content.Description as the data element name. Because Origin is a nested object in Content, you use Content.Origin.Country and Content.Origin.State to refer to the County and State properties.

Figure 16. Nested objects in JSON data.