How to display a BI Publisher report in Visual Builder without an iFrame

December 22, 2020 | 4 minute read
Tim Bennett
CX Solution Architect
Text Size 100%:

Introduction

While it is possible to view a BI Publisher (BIP) report in a page using an iFrame, there are times when this may not be suitable or possible.

This article shows an alternative method that can be used to view a BIP report without the use of an iFrame, using Visual Builder (VB) as the "hosting" application. While the example assumes that the VB server and BIP are federated, it is also possible to perform this configuration using non federated instances by using Basic Authentication. This is not recommended, but is useful for testing.

 

Overview Solution

The example works by retrieving the pdf report via the BI Publisher SOAP service and rendering it in an <object> tag in the VB page.

Configuration Steps:

  1. Develop the BIP report and ensure that it has a PDF output format
  2. Test the report using /xmlpserver/services/ExternalReportWSSService and SOAP UI (or similar)
  3. In VB, create a Service Connection to the BI Publisher SOAP service
  4. Create a VB page with a DIV placeholder for the Report
  5. Add an event listener to vbEnter that runs an Action Chain that displays the report

 

Details

Steps 1 and 2

The detail of steps 1 and 2 are beyond the scope of this document. The key output of these steps is a SOAP request that is known to work with the report. The request is likely to contain parameters that can be supplied at runtime, for example:

 


   
   
      
         
            pdf
            English
            English
            /myPath/myReport.xdo
           -1
          
      
   

 

Note the use of the attributeTemplate and attributeLocale parameters - these enable a user to run a report using any locale and template that has been defined in the report. This is useful in regions where reports may have to be generated with a locale that differs from the user's default.

Step 3 - In VB, create a Service Connection to the BI Publisher SOAP service

Although Service Connections are designed to call REST services, they can also be used to call SOAP. The benefits of using a service connection are that the pre-built authentication mechanisms can be used, the proxy can be used to avoid CORS errors, and the VB REST helper API can be used to make the call from a module function. 

Use "Define by Endpoint" to create a service connection to the BI Publisher service. The key setting are:

Method: POST

URL: https:///xmlpserver/services/ExternalReportWSSService

Request static header: Content-Type: application/soap+xml;charset=UTF-8

Authentication: Oracle Cloud Account

The connection source should look something like:

 

{
    "openapi": "3.0.0",
    "info": {
        "title": "Xmlpserver Services",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https:///xmlpserver/services",
            "description": "Xmlpserver Services",
            "x-vb": {
                "authentication": {
                    "authenticated": {
                        "type": "cloud"
                    }
                }
            }
        }
    ],
    "paths": {
        "/ExternalReportWSSService": {
            "post": {
                "operationId": "postExternalReportWSSService",
                "responses": {},
                "x-vb": {
                    "headers": {
                        "Content-Type": "application/soap+xml;charset=UTF-8"
                  },
                    "actionHint": "custom"
                }
            }
        }
    }
}

 

Note - DO NOT use Basic Authentication unless you are testing in a non-federated environment. This article assumes that the VB instance being used is federated with the Fusion instance hosting the BI report, hence the use of Cloud Account as the authentication method. By using Cloud Account, the user must have the necessary permission to call the BIP service and run the report.

 

4. Create a VB page with a DIV placeholder

Using the VB page designer, drag a div onto the page and set its id to REPORT.   This div will be used as the target for the embedded pdf.

 

5. Add an event listener to vbEnter that runs an Action Chain that displays the report

In this step, an Action Chain is run on the vbEnter Event. The action chain has 1 step which is a module function that does the following:

  • Call the BI Service using the vb/helpers/rest  API to retrieve the report data
  • Create a new object element of type application/pdf containing the pdf report data
  • Place the new element into the DIV placeholder

It is assumed that the reader knows how to create an Action Chain that calls a module function. Assuming that the module function is called callBIPService, the complete Page Module is below. The comments explain the key steps.

 

//add reference to the vb REST helper API
define(['vb/helpers/rest'], function(Rest) {
  'use strict';

  var PageModule = function PageModule() {};

  PageModule.prototype.callBIPService = function() {
    
    //This is the output of steps 1 and 2, change the parameter placeholders as shown 
    const soapTemplate = `
    
    
     
      
         
            pdf
            TEMPLATE
            LOCALE
            REPORTPATH
           -1
          
      
     
    
    `;

    //parameters for SOAP call, likely to be provided by VB variables
    const reportPath = "/myPath/myReport.xdo";
    const template = "Arabic";
    const locale = "Arabic";

    //replace template placeholders 
    const soapBody = soapTemplate
      .replace('TEMPLATE', template)
      .replace('LOCALE', locale)
      .replace('REPORTPATH', reportPath);

    //this is the service connection endpoint
    //note the hostname and authentication are defined in the service connection 
    const endpoint = 'xmlpserverServices/postExternalReportWSSService';

    //use the Rest helper API to make the call
    Rest.get(endpoint).body(soapBody).fetch().then(
      response => {
        //convert the response to XML and get the reportBytes
        const reportBytes = $.parseXML(response.body).getElementsByTagName("ns2:reportBytes")[0].textContent;
        displayPDF(reportBytes,"REPORT");
     });

    //create a new element containing the pdf data and place it in the REPORT div
    function displayPDF(pdfData, target) {
      const myPDF = document.createElement('object');
      myPDF.style.width = '100%';
      myPDF.style.height = '850pt';
      myPDF.type = 'application/pdf';
      myPDF.data = 'data:application/pdf;base64,' + pdfData;
      document.getElementById(target).appendChild(myPDF);
    }

  };

  return PageModule;
});

 

The final step is to declare the BIP service in the web application's app-flow.json

  "services": {
      "xmlpserverServices": {
      "path": "./services/xmlpserverServices/openapi3.json"
    }
  },

 

That completes the config. At runtime, a few seconds after the VB page is loaded (depending on the complexity of the report) the PDF should render!

 

Conclusion and Other options

This example shows a PDF being rendered, but BIP has several other output options such as HTML, Excel, Word, and Powerpoint. The above technique can be modified and used to render different formats based on your requirement.

The selection of the locale may be of particular interest to some customers where end users need to view reports in several different locales.

Note also that much of the code used in the module function can be used in other applications (e.g. an OTBI static text) to do much the same thing.

 

Tim Bennett

CX Solution Architect

Solution Architect specialising in Oracle Sales Cloud configuration and integration, particularly security and scripting.


Previous Post

Preparing Network Gateways for Private Oracle Analytics Cloud Data Sources

Dayne Carley | 7 min read

Next Post


The CIO dilemma. Should you adopt a Cloud Native strategy?

Nick Goddard | 16 min read