Using the svyPDFViewer to view Jasper Reports in the browser

Hello everyone!

Has anyone used the the svyPDFViewer component to view PDFs that are generated by a Jasper Report? Currently, when viewing reports from the Ngclient, our reports get automatically downloaded by the browser and the user has to click on the file to open with their installed PDF viewer.

We are looking to change this and allow the user to view the PDF with the svyPDFViewer, this way the control stays within our application and there is one less step for the user.

Thanks in advance for any tips.

Regards,
Juan Diego

I have seen that in action, looks pretty cool and more user friendly than downloading the pdf first. Have you tried it yet?

I have seen that in action, looks pretty cool and more user friendly than downloading the pdf first. Have you tried it yet?

It is pretty cool! Yes, I’ve tried it loading PDFs hosted online but haven’t tried it with Jasper Reports where the PDF is downloaded to the client machine. As I write this though, I figure I should just try saving the PDF to the Server and setting that as source for the viewer component. I will try that and post back!

Here is a snippet from demo.servoy.com:

function loadDocument() {
	//Download the remote file
	var file = plugins.http.getMediaData(documentURL);
	
	//Write the file to a remote file
	var remoteFileName = application.getUUID().toString() + '.pdf';
	var remoteFile = plugins.file.convertToRemoteJSFile('/'+remoteFileName)
	remoteFile.setBytes(file,true);
	
	//Convert the remote file to a url, and display it in the PDF viewer
	var remoteUrl = plugins.file.getUrlForRemoteFile('/'+remoteFileName);
	if(remoteUrl) {
		elements.pdfViewer.documentURL = remoteUrl;
	}
}

Thanks Jan!

I got it it work using that code (image attached) and it’s super neat! So what I am currently doing is executing ```
plugins.jasperPluginRMI.runReport


The only thing I'd like to avoid is the process of downloading the PDF first and then re-uploading it to make it accesible to the plugin. I noticed that when using

plugins.file.convertToRemoteJSFile

this file is then accesible through URL such as this one: *http://serverIp:8080//servoy-service/file/8FF21ADB-254E-4C3A-9E229-85CAEDE3E862.pdf* 

So I was wondering if I could skip a step and have the Jasper Plugin directly save the PDF to the directory that is related to that *http://serverIp:8080//servoy-service/file/* URL.

![tmpViewPDF.PNG|1788x816](upload://wngYXvoNJnQFUZVLR6djc91TYry.png)

Hi jdprudot,

jdprudot:
So I was wondering if I could skip a step and have the Jasper Plugin directly save the PDF to the directory that is related to that http://serverIp:8080//servoy-service/file/ URL.

Since the runReport function is returning a byte array, you can use that to set the bytes for the remote file, instead of saving the report to temporary file first, so something like this.

function loadDocument() {
   //Download the remote file
   var byteArray = plugins.jasperPluginRMI.runReport(<YOUR PARAMS>);
   
   //Write the file to a remote file
   var remoteFileName = application.getUUID().toString() + '.pdf';
   var remoteFile = plugins.file.convertToRemoteJSFile('/'+remoteFileName)
   remoteFile.setBytes(byteArray,true);
   
   //Convert the remote file to a url, and display it in the PDF viewer
   var remoteUrl = plugins.file.getUrlForRemoteFile('/'+remoteFileName);
   if(remoteUrl) {
      elements.pdfViewer.documentURL = remoteUrl;
   }
}

You might want to add some error capture, in case the runReport fails and you won’t have any byteArray to set.
For that purpose you could create a nice ‘Error pdf’ and use that as a fallback document. (Can have that ready on a known location, so no need to create it on the fly)

Hope that helps

Since the runReport function is returning a byte array, you can use that to set the bytes for the remote file, instead of saving the report to temporary file first, so something like this.

Thank you Marc! This worked out beautifully. It took me a several tries with the jasper plugin to figure out what parameters to send so that the browser would not ask me to save the PDF file. In the end, this is what worked:

var byteArray = plugins.jasperPluginRMI.runReport([myFoundset, reportName , {FILENAME: fileName, DOWNLOAD:false}, plugins.jasperPluginRMI.OUTPUT_FORMAT.PDF);

I then use that byteArray as in the code you suggested.

For that purpose you could create a nice ‘Error pdf’ and use that as a fallback document. (Can have that ready on a known location, so no need to create it on the fly)

This is a fantastic idea too, I’ll certainly do it.

Thanks for the help, guys!

Just wondering what version of Servoy are you guys using? I was able to get this code to work correctly in Servoy 8.3, however when I run under Servoy 2019.06 my jasper report plugin does not generate reports. Is there an update to the Jasper report plugin?

jdprudot:

It took me a several tries with the jasper plugin to figure out what parameters to send so that the browser would not ask me to save the PDF file. In the end, this is what worked:

var byteArray = plugins.jasperPluginRMI.runReport([myFoundset, reportName , {FILENAME: fileName, DOWNLOAD:false}, plugins.jasperPluginRMI.OUTPUT_FORMAT.PDF);

For me it doesn’t work with the uppercase properties. It works if I use “download” in lowercase.

If you are using the latest version of the PDF viewer plugin then you should be able to skip the step of having to create a file and simply assign the bytes to a data provider on the PDF viewer:

/**
 * The content of the document to be displayed - set to the blank document by default
 *
 * @type {Array<byte>}
 *
 * @author Steve Hawes
 * @since  2020-09-17
 *
 * @protected
 *
 * @properties={typeid:35,uuid:"6EA7B4D6-4C74-4EDA-9AC9-1023F30AC5B7",variableType:-4}
 */
var reportData = solutionModel.getMedia('blank.pdf').bytes;

function loadDocument() {
   // Assign the output to the data provider 
   reportData = plugins.jasperPluginRMI.runReport(<YOUR PARAMS>);
}

Just make sure the dataProvider property of the PDF viewer is set to be the reportData variable.