Printing in NG (Desktop)-Client

Hi all

I’m working on migration form Smart- to NG-Client. One thing I’m stuck on is the way of printing. I’m aware that printing directly from the browser is not possible. But it really not possible to print in NG Desktop-Client? At least I couldn’t find a way to do that.

In the Smart-Client for example we used to print like this:

plugins.jasperPluginRMI.runReport(fs,
       "myJasperReport.jasper", 
       "NameOfMyPrinter", 
       plugins.jasperPluginRMI.OUTPUT_FORMAT.PRINT,
       parameterObjekt,
       i18n.getCurrentLanguage() + "_" + i18n.getCurrentCountry())

The printer “NameOfMyPrinter” has all the required printer settings (such as the tray for example). So if I run this report, the output is sent directly to the printer and the output goes to the correct tray.

In the NG-Environment I check, if the user is in the “NG-Desktop”-Client:

plugins.ngdesktoputils.isNGDesktop()

and if so, I try the same code as above. But then I get a JavaScript-Error.

Is there another way to do so? Maybe get the ByteArray that will be produced by Jasper and then send this somehow to a methode? I didn’t find something like that. Maybe someone else has a solution for that.

We use Jasper-Plugin Version 6.12.2 and Servoy 2020.12.0.3622

I would be grateful for any suggestion.

Many thanks in advance
Roland

Hi Roland,

To print a jasper report from NG Client (browser) you could do the following:

// Create a temporary file in the server (needs to start with '/')
var remoteFileName = '/temp_file.pdf';
var remoteFile = plugins.file.convertToJSFile(plugins.file.getDefaultUploadLocation() + remoteFileName);
// Print report to PDF
plugins.jasperPluginRMI.runReport(foundset, reportName, remoteFile, plugins.jasperPluginRMI.OUTPUT_FORMAT.PDF, params);
// Launch the print dialog for the PDF report file
plugins.ngclientutils.printDocument(plugins.file.getUrlForRemoteFile(remoteFileName));

For NG Desktop I haven’t done printing directly to the printer, what error do you get?

Hi Danny

Thanks a lot for your reply!

Yes, I’ve already tried this “plugins.ngclientutils.printDocument”. But this basically just opens the browsers “Print Dialog”. The user still has to choose the printer and then click the print-Button. This is ok, if I just have a few documents to print. But if I run a process that produces a lot of documents (for example a billing-process), then it’s not very handy, if the user has to commit each printing job.

The error I got in the NG-Desktop-Client is the following:

A JavaScript error occurred in the main process

Uncaught Exception:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received
null
   at validateString (internal/validators.js:120:11)
   at Object.join (path.js:375:7)
   at Session.<anonymous>
(C:\Servoy\workspaces\OfficeNG\.metadata\plugins\com.servoy.eclipse.debug\servoy....:42)
   at Session.emit (events.js:315:20)

Hi Roland,

I assume you already updated the Jasper plugin to a NG-compatible version?

A generic way to use the result of a Jasper report is by generating the byteArray.
Then you can decide what you want to do with that.

So generate the report should be like this:

var byteArray = plugins.jasperPluginRMI.runReport(fs,
       "myJasperReport.jasper", 
       true, 
       plugins.jasperPluginRMI.OUTPUT_FORMAT.PDF,
       parameterObjekt,
       i18n.getCurrentLanguage() + "_" + i18n.getCurrentCountry())

After that you could write it into the download folder like this:

plugins.file.writeFile('myJasperReport.pdf', byteArray);

I don’t think you’ll be able to print it directly.
Instead you could preview it in the PDF viewer component, which has a print button and users can print it right away.

Hope that helps.

Hi,

Once you have created your PDF as a file take a look at Silent Print in Servoy – Pradipta's Blog. Works nicely in NG Client.

Richard

Hi Marc

First of all: thanks for your inputs!

mboegem:
I assume you already updated the Jasper plugin to a NG-compatible version?

Yes, we have.

A generic way to use the result of a Jasper report is by generating the byteArray.
Then you can decide what you want to do with that.

So generate the report should be like this:

var byteArray = plugins.jasperPluginRMI.runReport(fs,
   "myJasperReport.jasper", 
   true, 
   plugins.jasperPluginRMI.OUTPUT_FORMAT.PDF,
   parameterObjekt,
   i18n.getCurrentLanguage() + "_" + i18n.getCurrentCountry())



After that you could write it into the download folder like this:

plugins.file.writeFile(‘myJasperReport.pdf’, byteArray);


I don't think you'll be able to print it directly.
Instead you could preview it in the PDF viewer component, which has a print button and users can print it right away.

That’s what we do so far, because we don’t have a better solution.

As I wrote in my initial post: I know, that we couldn’t print directly out of the WebBrowser (NG-Client). But what we would expect is, that we can do this in the NG-Desktop-Client. I would expect the function, that Richard mentioned in his post, but we need this on the client and not on the server side.

Best
Roland

Hi Richard

Thanks for your input!

Richard1521662995:
Once you have created your PDF as a file take a look at Silent Print in Servoy – Pradipta's Blog. Works nicely in NG Client.

We already use this solution (in NG and in SmartClient). But the problem is: in NG-Client only the printers that are reachable on the server are available. This is perfect, as long as I don’t host my solution in the cloud. But when we host the the server in the cloud, then we don’t have access to the printers on the client-side.

Best
Roland

Hi Roland,

At the moment all our customers have on premise servers, so at the moment we are fine, but will be a problem for us as well if we host with a cloud server.

Richard.

Hi Roland,

The only way to have access to client-side printers is by using NG Desktop

Best,

rph:
As I wrote in my initial post: I know, that we couldn’t print directly out of the WebBrowser (NG-Client). But what we would expect is, that we can do this in the NG-Desktop-Client. I would expect the function, that Richard mentioned in his post, but we need this on the client and not on the server side.

Hi Roland,

sorry, missed that bit.

Have a look at the ngclientutils plugin.
This plugins has a function printDocument.

The sample code look like this:

// if url is not from same domain we must create a temporary file
var file = plugins.http.getMediaData(url);
var remoteFileName = application.getUUID().toString() + '.pdf';
var remoteFile = plugins.file.convertToRemoteJSFile('/'+remoteFileName)
remoteFile.setBytes(file,true);  //Convert the remote file to a url, and print it
var remoteUrl = plugins.file.getUrlForRemoteFile('/'+remoteFileName);
plugins.ngclientutils.printDocument(remoteUrl)

The function is using the browsers print dialog, so no further control on trays etc.

Another option to explore might be to use the ngdesktoputils plugin.
From there you can execute commands, so if you’re able to find a command line solution to print pdf documents this could work.

Hi Marc

Thanks for these inputs again!

mboegem:
The sample code look like this:

// if url is not from same domain we must create a temporary file

var file = plugins.http.getMediaData(url);
var remoteFileName = application.getUUID().toString() + ‘.pdf’;
var remoteFile = plugins.file.convertToRemoteJSFile(‘/’+remoteFileName)
remoteFile.setBytes(file,true); //Convert the remote file to a url, and print it
var remoteUrl = plugins.file.getUrlForRemoteFile(‘/’+remoteFileName);
plugins.ngclientutils.printDocument(remoteUrl)




The function is using the browsers print dialog, so no further control on trays etc.

That’s what Danny also suggested. But as you write, it shows the browsers print dialog and the user has to confirm each printing. This isn’t really handy if you run a job that generates a lot of document to print (for example a billing process). And it’s even worser when you run a job in the background that finally should print the result.

mboegem:
Another option to explore might be to use the ngdesktoputils plugin.
From there you can execute commands, so if you’re able to find a command line solution to print pdf documents this could work.

[/quote]

That sounds interesting. Maybe I’ll give it a try. But first of all, I’ll need to find a way to print from “outside of Servoy”, so I can call this command.

Best
Roland

Hi Danny

Thanks for your comment.

dcamargo:
The only way to have access to client-side printers is by using NG Desktop

I’m aware of that. And I would use the NG Desktop client. But the solution you previously described just show me the browser print dialog.

So I’m still looking for a possibility to start printing automatically on client side, similar to the way Richard suggested. But Richard’s suggestion only works on server-side.

Maybe it would be possible for Servoy to integrate this solution (https://pradiptab.wordpress.com/tag/sil … in-servoy/) into the NG Desktop and present a wrapper so we could call this wrapper like this: plugins.ngdesktopprinting.print(fileName, printerName);

Best
Roland

Just for the sake of completness: Servoy has integrated a solution in Servoy2021.09.

Now we can handle it like this:

function(localFile2Print, printerName, withDialog) {
        ...
	var options = {};

	if (printerName) {
		options.printer = printerName;
	}
	else {
		options.win32 = ['-print-to-default'];
	}
	
	if (withDialog) {
		options.win32 = ['-print-dialog'];
	}

	plugins.ngdesktoputils.printPDF(localFile2Print, options);
}