APEX 26.2 simplifies using custom JSON in report queries. Two situations requiring it are scannable bar codes and images in a DocGen report layout. Both required custom code to achieve: now both are declarative. To celebrate Joel Kallman Day 2026, we explore including QR codes and images into a pixel-perfect PDF report using this new JSON report query capability.
Why is Custom JSON Required?
The Oracle Document Generator documentation explains the tags you can embed in a Microsoft Word document. These tags reference data values by name from the JSON document APEX sends the report server containing your report query data. Each source query in an APEX Report Query definition provides data to include in that JSON “datagram”. Each one defines a data loop name – like departments below – to identify that source query’s “section” in the document.
Referencing the scalar value of a deptno or dname column uses simple tags like {dname} and {deptno} to include simple values from the JSON like:
{ "departments" : [ { ⋮ "deptno": 10, "dname": "ACCOUNTING", ⋮ } ]}
In contrast, some report output like a scannable bar code requires more info in the JSON than a single scalar value. Imagine wanting to render the value of the loc column as a QR code. The DocGen tag documentation says a tag like {barcode:loc} expects the loc property to have a particular nested structure like this:
{ ⋮ "loc": { "barcodeType": "QR", "data": "NEW YORK", "version": 10 }, ⋮}
Depending on the barcode type, some other properties are required while others are optional. Producing this nested structure for the loc property in the report query JSON used to require programmatically constructing the JSON document to pass to the GENERATE_DOCUMENT function of the APEX_PRINT package.
Including Nested JSON in a Query
Use the JSON_OBJECT function to create a JSON object as the value of a column in your query. For example, in a query against the familiar DEPT table, you can include LOC as a JSON object having barcodeType, data, and version properties like this:
SELECT deptno, dname, json_object( 'barcodeType' value 'QR', 'data' value loc, 'version' value 10 ) as locFROM dept
If you create a DepartmentsQR report query with the above SQL statement, use the handy technique explained in Inspecting the Report Query JSON to review the JSON document it will produce at runtime. By clicking the (Download) button in the report query editor, you can open the JSON file from your downloads folder. It will look like the following:
{ "departments": [ { "deptno": 10, "dname": "ACCOUNTING", "loc": "{\"barcodeType\":\"QR\",\"data\":\"NEW YORK\",\"version\":10}" }, { "deptno": 20, "dname": "RESEARCH", "loc": "{\"barcodeType\":\"QR\",\"data\":\"DALLAS\",\"version\":10}" }, ⋮ ]}
You can see that by default, the JSON has been automatically “escaped” into a string format, which is not what we need. Rather than a string containing JSON, we need the value of the loc property to be structured JSON properties.
The solution is simple. In APEX 26.2, any source query column in a Report Query whose alias begins with {} gets included as “raw” JSON that should not be escaped. So, to get the result we need, we simply change the loc column alias to be "{}loc" instead like this:
SELECT deptno, dname, json_object( 'barcodeType' value 'QR', 'data' value loc, 'version' value 10 ) as "{}loc"FROM dept
Clicking (Download) again, we now see the effect in the JSON file. Instead of being escaped as a string value, the nested JSON is included inline:
{ "departments": [ { "deptno": 10, "dname": "ACCOUNTING", "loc": { "barcodeType": "QR", "data": "NEW YORK", "version": 10 } }, { "deptno": 20, "dname": "RESEARCH", "loc": { "barcodeType": "QR", "data": "DALLAS", "version": 10 } }, ⋮ ]}
Including QR Code in a Word Template
Including the loc property as a scannable bar code in your Word template requires the tag {barcode:loc}, whose shortened version is {bc:loc}. Notice below this {bc:loc} tag appears in the Location column of a Word table cell, between the opening {#departments} and closing {/departments} tags.

Testing the Report in App Builder
After creating a Report Layout with your Word template and associating it with your Report Query, you can test out the report right in App Builder. In the Report Query edit page, click (Test Report). This runs the report queries to produce the JSON, sendsthe JSON to the DocGen report server along with the report template, and downloads the PDF result shown below.

Adding Margin Around QR Code
The QR code appears. A small amount of margin would improve scannability. This is simple to add using Word paragraph spacing in the template document. Just select the contents of the Location cell and use Word’s Paragraph Line Spacing Options as shown below. In the Paragraph dialog that appears, you can set the precise spacing before and after the paragraph containing the barcode tag. The same goes for most Word formatting like horizontal and vertical cell alignment. Your report inherits the formatting features of the Word template.

For example, suppose you configure four (4) points of space above and below the barcode tag paragraph. After saving the modified report layout Word document, uploading it to replace the one in the APEX report layout, and clicking (Test Report) again, you now get the report shown below:

Including an Image in Each Row
The DocGen {image:dataRef} tags lets you include an image from object storage or using a URL. I’ve staged four sample images named accounting.png, research.png, sales.png, and operations.png on my public GitHub site, so we’ll use the URL-based images in this example.
DocGen documentation says the nested JSON structure of an URL image namecan look like this to fix its width at 15o pixels:
{ ⋮ "somePropertyName": { "source": "URL", "url": "https://example.org/somefile.png", "width": "150px" }, ⋮}
You can update the report query to include a new "{}locGraphic" column with the following additional JSON_OBJECT expression:
SELECT deptno, dname, JSON_OBJECT( 'barcodeType' VALUE 'QR', 'data' VALUE loc, 'version' VALUE 10 ) as "{}loc", JSON_OBJECT( 'source' VALUE 'URL', 'url' VALUE 'https://stevemuench.github.io/' || lower(dname) || '.png', 'width' VALUE '150px' ) AS "{}locGraphic"FROM dept
Then, you can add an {image:locgraphic} tag to the template in a new column. To conserve space, you can use either of the shortened tag variants of {im:locgraphic} or {%locgraphic} as well. I’ve used the shortest version below.

locgraphic JSON PropertyNotice that despite using an alias of "{}locGraphic", the JSON the APEX engine produces from the query has all lowercase property names. So make sure you use {image:locgraphic}, {im:locgraphic}, or {%locgraphic}.
If you inadvertently use a tag like {%locGraphic} with a capital G, you’ll end up with a blank table cell since the JSON property name in the DocGen tag is case-sensitive. You can always inspect the JSON for your report query using the (Download) button in the App Builder if you’re not getting the result you expect.
Printing a Report with a Dynamic Action
When your application needs to print a report, you can use a page process, a call to GENERATE_DOCUMENT in the APEX_PRINT package, or with a Print Report dynamic action step. In the sample app you can download at the end of this article, as shown below, each of the three buttons uses the dynamic action approach in a Triggered Action on the respective button.

Clicking on the (Print Departments Report) button as shown below, the report with both a QR code and an image in each row is produced and downloaded.

Opening it, you see the results below.

Using HTML in a Pixel-Perfect Report
While not strictly related to the new APEX 26.2 feature to declaratively include JSON content in a report query, I wasn’t previously aware that DocGen supports a subset of HTML tags in a template. So, I wanted to show one last example to pass along that information I learned while writing this article.
The DocGen documentation explains the allowed HTML tags. The <img> tag is one of them. So, another way to include an image is with an <img> tag. It also supports the <p> tag and some common CSS styling properties, so we can mimic the result we got above by changing the query to produce a snippet of HTML instead.
Consider the following updated report query source SQL statement. It continues using JSON_OBJECT for the QR code, but includes HTML tags instead for the value of the IMAGE column.
SELECT deptno, dname, JSON_OBJECT( 'barcodeType' VALUE 'QR', 'data' VALUE loc, 'version' VALUE 10 ) as "{}loc", apex_string.format( q'~<p style="margin:5px;text-align:center"> <img style="width:150px; height:150px; padding:5px;" src="%s"> </p>~', 'https://stevemuench.github.io/' || lower(dname) || '.png') as imageFROM dept
The query expression uses apex_string.format() to substitute the computed image URL into the HTML snippet as the value of the src attribute if the <img> tag:
<p style="margin:5px;text-align:center"> <img style="width:150px; height:150px; padding:5px;" src="%s"></p>
With this query in place, the report template can reference the HTML using the {html:image} tag. The name of the column here is IMAGE, producing an property named image in the JSON. This result, produces an effect similar to the previous report output. However, it’s good to know you can use a subset of HTML when that would come in handy.
Downloading the Sample App
After ensuring you have installed the EMP/DEPT sample dataset using SQL Workshop > Utilities > Sample Datasets, download the sample app from here. Hope you find many uses for custom JSON in your report queries!
In Memoriam
Earlier this year, I dedicated the APEX Developer’s Companion to the memory of Joel Kallman, Allan Sitterson, and my dad Robert Muench. All left us too soon and are greatly missed.
