This content has been archived and is no longer being updated. Links may not function; however, this content may be relevant to outdated versions of the product.
LinkedIn
Copied!

Exporting a chart in a scheduled report to a PDF file

When a scheduled report with a chart is exported to a PDF file, the chart is not automatically included in the PDF file. However, you can use the pyEmbedChartUsingPhantomJS HTML rule and the pyCallPhantomJS activity rule to implement a solution that can export the chart in a scheduled report to a PDF file.

This behavior is different from when you export reports from the Report Viewer. When you export a report with a chart from the Report Viewer, the chart is included in the PDF file. Including charts when you export a report is an effective way to visually communicate report details.

This solution uses PhantomJS. You can download PhantomJS from the following website: http://phantomjs.org/

Prerequisites

Before you begin:

  • Comment out the code in the pyEmbedChartUsingPhantomJS HTML rule.
  • Comment out all steps in the pyCallPhantomJS activity rule.

Process

1. Create a JavaScript file (for example, chartURL.js), and copy the following code into that file. Include a user ID and password in this file.

[*]Code for the JavaScript file[*]

[*]

// Passing hard coded user id and password and passing URL and chartName dynamically
var page = require('webpage').create();
page.viewportSize = {
    width: 2000,
    height: 3000
};
page.settings.userName = ""; //username to be used to run the report
page.settings.password = ""; //password to be used to run the report
page.settings.clearMemoryCaches = true;
/*getting variables passed from activity*/
var reportURL = phantom.args[0];
var chartName = phantom.args[1];
var phantomLocation = phantom.args[2];
var chartPath=phantomLocation+chartName+".png";
phantom.clearCookies();
try{
page.open(reportURL, function() {
    var waitNRun = function() {
        console.log("In wait");
        result = page.evaluate(function() {
            var divs = document.getElementsByTagName('div');
            var chartDiv;
            for (var i = 0; i < divs.length; i++) {
                if (divs[i].getAttribute('id') != null && divs[i].getAttribute('id').indexOf('ichartDiv') == 0) {
                    var reg = /^\d+$/;
                    if (reg.test(divs[i].getAttribute('id').split('ichartDiv')[1])) {
                        chartDiv = divs[i];
                        break;
                    }
                } else if (divs[i].getAttribute('id') != null && divs[i].getAttribute('id').indexOf('staticChart') == 0) {
                    var reg = /^\d+$/;
                    if (reg.test(divs[i].getAttribute('id').split('staticChart')[1])) {
                        chartDiv = divs[i];
                        break;
                    }
                }
            }
            var curtop = 0,
                curleft = 0;
            var chartDivForTop = chartDiv;
            if (chartDivForTop.offsetParent) {
                do {
                    curtop += chartDivForTop.offsetTop;
                    curleft += chartDivForTop.offsetLeft;
                } while (chartDivForTop = chartDivForTop.offsetParent);
            }
            return [chartDiv.offsetHeight, chartDiv.offsetWidth, curtop, curleft];
        });
        try {
            console.log('Crop brand new to : ' + result[0] + "x" + result[1] + "x" + result[2] + "x" + result[3]);
            page.clipRect = {
                top: result[2] + 10,
                left: result[3],
                width: result[1],
                height: result[0] - 45
            };
            window.setTimeout(function() {
                             
                page.render(chartPath);
                phantom.exit();
            }, 20000);
        } catch (err) {
            console.log('exception');
            phantom.exit(1);
        }
    }
    setTimeout(waitNRun, 5000);
});
}catch(err){
console.log("error occured in js file");
}

[*]

 

2. Use the pyEmbedChartUsingPhantomJS HTML rule to call the activity to obtain the image byte stream and append the image byte stream to the PDF stream.

[*]pyEmbedChartUsingPhantomJS HTML rule[*]

[*]

<%  
 HashStringMap keys = new HashStringMap();
        keys.putString("pxObjClass", "Rule-Obj-Activity");
        keys.putString("pyClassName", "Rule-Obj-Report-Definition");
        keys.putString("pyActivityName", "pyCallPhantomJS");
    ParameterPage paramsPage = new ParameterPage();  
    paramsPage.putString("InsHandle", tools.getPrimaryPage().getString(".pyReportDefinition.pzInsKey"));
    ClipboardPage chartPage=tools.getPrimaryPage().getPage(".pyReportDefinition.pyUI.pyChart");
String ChartName=chartPage.getString(".pyGraphType")+chartPage.getString(".pySubType")+com.pegarules.generated.pega_rules_datetime.getCurrentTimeStampUnique().replace(".","").replace("GMT","");
       ChartName = ChartName.trim();
    paramsPage.putString("ChartName",ChartName);
tools.doActivity(keys , null, paramsPage);

String encodedImage = tools.getPrimaryPage().getString("encodedImage");
String imgTag = "<img src='data:image/png;base64,"+ encodedImage +"' />";
imgTag = imgTag.trim();
%>
 <%
  =imgTag
  %>

[*]

 

3. Use the pyCallPhantomJS activity rule to invoke the PhantomJS WebKit, which calls the JavaScript file that you created (chartURL.js).

[*]a. Obtain the report URL dynamically and set the URL to a variable.[*]

[*]

ClipboardPage cp=tools.findPage("pxRequestor"); /*Get the requestor page*/
if(cp!=null){
    String reqContextURI= cp.getProperty(".pxReqContextURI").getStringValue()+"/PRServlet";
   String reqPathInfoReal= cp.getProperty(".pxReqPathInfoReal").getStringValue();
  String insHandle=tools.getParamValue("InsHandle");
  insHandle=insHandle.replaceAll(" ","%20").replaceAll("#","%23");
reportURL=reqContextURI+reqPathInfoReal+"?pyActivity=%40baseclass.WBRun&InsHandle="+insHandle;
}else{
  oLog.infoForced("requestor page is null");
}

[*]

 

[*]b. Set the PhantomJS location and the JavaScript file location as local variables by using the Property-Set method of an activity.[*]

[*]

Local.phantomPath=”"\\\\ shared_location \\phantom\\phantomjs"
Local.phantomLocation=”"\\\\ shared_location \\phantom\\"
Local. chartURL="\\\\ shared_location \\phantom\\chartURL.js"

[*]

 

[*]c. Call PhantomJS by using the Java step of an activity.[*]

[*]

try{
  
  java.lang.Process process = java.lang.Runtime.getRuntime().exec(phantomPath+" "+chartURL+" "+reportURL+" "+tools.getParamValue("ChartName")+" "+phantomLocation);
process.waitFor(); 
    
}
catch(Exception e)
{
oLog.error("Exception occurred while calling phantom JS ",e);    
}

[*]

 

[*]d. Obtain the chart bytecode and add it to the primary page.[*]

[*]

try{
  String chartPath = phantomLocation+tools.getParamValue("ChartName")+".png"; 
  oLog.infoForced("chartPath=="+chartPath);
  java.awt.image.BufferedImage image = javax.imageio.ImageIO.read(new java.io.File(chartPath));
  java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(); 
  javax.imageio.ImageIO.write(image, "png", baos); 
  byte[] res=baos.toByteArray();
  String encodedImage = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode(baos.toByteArray());
  oLog.infoForced("encodedImage=="+encodedImage);
 tools.findPage("TmpExportResultsPage").putString("encodedImage",encodedImage);
} catch(Exception e) { 
  oLog.infoForced("In exception=="+e.getMessage());
}

[*]

 


0% found this useful

Have a question? Get answers now.

Visit the Collaboration Center to ask questions, engage in discussions, share ideas, and help others.