Oracle Visual Builder created web interfaces to show you data, but sometimes customers are looking to also create documents that they can save or print for later use. Common scenarios are creating invoices, filled out forms, or reports. In this blog we'll show how you can leverage the new document generation function provided by Oracle Cloud Infrastructure (OCI) to create such documents passing information directly from the UI in Visual Builder. Below is a quick demo showing an example followed by more detailed information about the implementation:
OCI Document Generation Function
The OCI document generation function is a serverless function that is one of the pre-built functions that OCI provides out of the box. Functions are fully managed, multi-tenant, and highly scalable on-demand and don't require you to administer infrastructure or software.
The document generation relies on template Microsoft word files and a JSON files that will contain the data we want to inject into the templates. These files will reside on the OCI Object Storage. The function then reads the JSON file and inject data from it into reserved spaces in the word file – generating a resulting PDF file.
To start, we'll create a storage object bucket and place sample docx and json files there. Note the namespace, bucketname, and file names – as you'll need to pass this information to the doc generation function.
We'll enable the function from the cloud console. There are various ways to invoke functions, for our Visual Builder UI we'll use the REST invoke endpoint. The URL for it is one of the properties of the function in your cloud console.
To invoke this endpoint from Visual Builder you'll add it as a REST endpoint of type POST (with the CREATE hint), and provide a body payload. For the authentication we'll use the "Oracle Cloud Infrastructure API Signature 1.0" providing the key id and private key – if you need help setting this authentication see this blog about connecting to secured OCI services from VB. The payload for the function to generate a single pdf file specifies the template, data file, and target file and looks something like this:
{
"requestType": "SINGLE",
"tagSyntax": "DOCGEN_1_0",
"data": {
"source": "OBJECT_STORAGE",
"namespace": "vbauto",
"bucketName": "shaybucket",
"objectName": "movies.json"
},
"template": {
"source": "OBJECT_STORAGE",
"namespace": "vbauto",
"bucketName": "shaybucket",
"objectName": "movies.docx"
},
"output": {
"target": "OBJECT_STORAGE",
"namespace": "vbauto",
"bucketName": "shaybucket",
"objectName": "Tickets/movies.pdf",
"contentType": "application/pdf"
}
}
Update the namespace, bucketname and objectnames/filenames in the payload above to match your storage bucket. Test the REST endpoint in Visual Builder to make sure a document is generated based on the sample files you loaded.
Generating JSON File Dynamically
The function picks up dynamic content that get injected into the template from a JSON file. So, we need to generate this JSON file dynamically in our app and load it to the object storage. We can leverage JS code to generate a file variable in our action chain, for example:
const myfile = new File(['{ "movie" : { "title": "' + $page.variables.getId.title + '", "rating": "' + $page.variables.getId.vote_average + '", "overview": "' + $page.variables.getId.overview + '"} }'], "movies.json", {
type: "application/json",
});
Adjust this content to match the content your JSON file needs to contain. Note that we specify the file name and type here too – this info is now available in our myfile variable that we can pass as the body for the REST call that will load this into your object storage. Here is a blog that introduce you to working with the object storage API from VB. If you rather not have the bucket be public, you simply need to set authentication for the REST endpoint in a similar way we did for the function's endpoint.
In our action chain, after we load the file successfuly we call the REST endpoint to invoke the function and generate the document.
Accessing the Result
In the demo we simply use the Open URL action to open the pdf file that was generated in a new browser tab. While our bucket is private, we generated the output to a separate directoy – and for that directory we enabled read access using Pre-Authenticated Request – this allows all the users of the app to access that directory to get access to the output. An alternative approach could be to use a separate REST call to download the file to the browser.
