Choosing a printer programmatically in Jasper Reports
Jasper Reports is, in my opinion, by far the best report engine available for Java, even more, it's open source! On the project page, there is enough information available to build simple and more advanced reports. If you need more help you can buy some guides at the project's owner commercial page JasperSoft. There is also technical support available to be purchased.
Today I'll show you how to choose a printer programmatically.
1JasperPrint print = JasperFillManager.fillReport(
2 this.class.getResource("/classpath/yourReport.jasper").getPath(),
3 new HashMap(), new yourReportDataSource());
4PrinterJob job = PrinterJob.getPrinterJob();
5/* Create an array of PrintServices */
6PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
7int selectedService = 0;
8/* Scan found services to see if anyone suits our needs */
9for(int i = 0; i < services.length;i++){
10 if(services[i].getName().toUpperCase().contains("Your printer's name")){
11 /*If the service is named as what we are querying we select it */
12 selectedService = i;
13 }
14}
15job.setPrintService(services[selectedService]);
16
17PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
18MediaSizeName mediaSizeName = MediaSize.findMedia(4,4,MediaPrintableArea.INCH);
19printRequestAttributeSet.add(mediaSizeName);
20printRequestAttributeSet.add(new Copies(1));
21
22JRPrintServiceExporter exporter = new JRPrintServiceExporter();
23exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
24/* We set the selected service and pass it as a parameter */
25exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE,
26 services[selectedService]);
27exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET,
28 services[selectedService].getAttributes());
29exporter.setParameter(JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET,
30 printRequestAttributeSet);
31exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG,
32 Boolean.FALSE);
33exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG,
34 Boolean.TRUE);
35exporter.exportReport();
In the above code, you can see how to accomplish our purpose. The first part of all is generating our JasperPrint, this is common to all methods of report printing. Then comes the important part. First, we look for the available printServices
in the computer. Second, we scan the found services to see if there is anyone that suits our needs. Finally we set the selected print service in the exporter.
You will also find methods to choose the paper output and the number of copies to print.
Comments in "Choosing a printer programmatically in Jasper Reports"
Hi Mark!
Nice code!
I'm writing some articles about JasperReports library on http://voituk.kiev.ua (unfortunately on Russian). Can I post a translated version of this entry on my blog (of course, i'll post a link to this page)? Plz reply on email.
Is there a way to get rid of this window?
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.TRUE);
to
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.FALSE);
I have to solve a Problem like this, but don't know how. Cause I'm a beginner with Jasper and iReport I don't understand where to insert your code in my jrxml... and btw, I know exactly which printer I want to use, so do I have to search for the services...
Please, if you can/want help look at my request here: http://www.netbeans-forum.de/viewtopic.php?p=2767
Thank you!
The article shows the code you need to run/print a report from a java program. In your request, you talk about inserting the code in your report source which you CAN'T.
You must insert the code in your java application where you are calling the report to be printed. If you are running the report directly from iReport you will have to choose the printer manually.
Then you include another issue, which is printing one page to one tray and another to the second tray of the printer. Tray selection in java is not very well implemented, in fact, java printing API is not very good and causes some trouble across different platforms (things don't work the same in windows and in Linux for example). I would approach your problem by creating two different reports and then print them separately.
Finally, the search for the services is necessary (someone correct me if I'm wrong), because you need a way to grab your service and there's no such thing as PrintService.getInstance(String serviceName);
So even it is time-consuming it is necessary. Maybe you could store your service in a variable for future use so you don't have to look up the service each time.
It's right, I tried to insert the code into my report.
Inserting it in the Java App is not possible for me, because the Java App is not mine and can't be changed.
So I try to find out, how it may possible to commit control code with the Report so the printer changes the tray... If necessary with another app between report (Jasper) and Printer...
Thanks
You should be more explicit with your problem. Is the application running in JDeveloper the same as the one running in Tomcat?
I suppose that in JDeveloper you're running a standard j2se application and in tomcat you're trying to print from your webapplication. The problem with this code is that webApplications are run from the server and so you're program will be trying to print in the server and not in the client machine.
Quick Google query:
JASPERREPORTS SERVLET
Hello, I came across your post and it was extremely helpful in setting up my jasper servlet to allow for printing reports directly to a client's default printer once they've ran the reports.
I'm having one problem ... the servlet seems to be always selecting the default printer of the server and not the default printer of the client whose actually running the report via the web.
Does the printServiceLookup.lookupDefaultPrintService() function only pool those printers on the server?
If so is there a way to get the servicelookup to poll the client's printer list and select their default printer?
Here's my code ..
thanks for your help!So what happens is that the server is the computer who is printing the report and not the client.
To print the report from the client's computer you will have to implement another solution. I can think of a couple: run a java aplet which prints an input stream (not very elegant these days.) Export your report to html and let the servlet output an OutputStream, then print from clients computer and select the printer with javascript. Or export the report to pdf...
Hope it helps.
I was thinking that was the case. I would export the report to a PDF or HTML, but I'm trying to simulate batch reporting with the servlet. The servlet is iterating through a loop and running multiple reports one after another. A printer has to be installed on a server for the server to print for it correct? Does java have the functionality built in to resolve a printer on the network if you have the printer's network name?
Strange servlet yours... ;)
PrintServiceLookup.lookupPrintServices(null, null);
Will list all of the printers installed or accesible from your server. So if your os has the network printer installed, your servlet will list that printer even if it is a network printer.
If you want to install or resolve the printer during runtime, I don't know if java is capable of resolving the printer with non native methods (but I don't think so, java printing is very weak). The solution will be to implement any native method or run an os command. In windows "NET USE [port:] [\\computer\printer [password | ?]]".
Hope it helps.
Printing Problem in Client Machines(Printing Permission)
Hello, I came across a problem. I could display my report in applet which I have created with iReport tool. The problem is at the time of printing on the client machine is gives a error dialog box comes "Error In Printing". I have to configure my java.policy file with some extra code for printing permission. So this has become a problem. If I give report online how can I configure infinite clients on the web for pritning the report. Is there any other way to do so without configuring the java.policy file in the client machine?
Please Help..
Thanks in Advance
I need some help with the report I've made.
The case is this, I have to print a six page report with subreports in a whole master..
However, I will only be able to correctly layout the subreports on the whole 6-page layout if I customized the page height(e.i. totalling a 6-page customized height).
I used page break to separate subreports on each pages.
It worked.However, when viewing the whole report, what I viewed was the whole customized height I've made.printing was fine.
It was the viewing that concerns me.
What I wanted to view really was the part of the page that is to be printed not the whole long page I've made.
Can u suggest something to address my problem or is there any other way to layout subreports separately on multiple page format?
You can do:
First of all, thank you for your response.
Yes it's true, the search for the printer name is not necessary at all.
But the code above is very usefull if you use the program across several computers in windows environments.
Depending on how you install a network printer in windows (there are several ways), if you do it the easy way (double click the printer in a 'My Network Places' computer) you will get a printer with the name "PRINTER NAME in COMPUTERNAME". So your code won't be useful.
So if you know the exact name of the printer and you know that this name will remain in whatever computer you install your program, then you should Paulo's code. Your program will load faster.
Hello,
I have a similar problem: in your webservice application we use servlets to build custom report (about 15O subreports/ 50 pages). But if one more cliente click the print button the reports is not generated. Please, someone can help me?
Best regards
Roosewelt
I created a customized label using iReport and if I print it from PDFreader it prints fine. But, if I print it from my java program it prints extra 4 labels. It takes the default paper size as A4. I tried to set PRintImageableAra as shown below with no luck.
printRequestAttributeSet.add(new javax.print.attribute.standard.MediaPrintableArea(0,0,4,2,javax.print.attribute.standard.MediaPrintableArea.INCH ));
Can you please help me with this.
Thanks!
thanks for ur tutorial.it was very helpful for me.
i want to print three jasper file in one print job task and i dont want printer to stop and start between each report printing. i think this way we can speed up printing multiple reports.
can u help me please?
thanks for the code it was useful for me. but my req. is some what different, it is like my application provides the printer name in string format and jasper report related java code has to take the printer name,input xml,jrxml and has to print at the appropriate printer. so please any one help me out with sample code.
thanks for the code it was useful for me. but my requirement. is some what different, it is like my application provides the printer name in string format and jasper report related java code has to take the printer name,input XML and has to print at the appropriate printer. so please any one help me out with sample code.
Yo lo habia solucionado generando una impresora con un papel preestablecido y al imprimir con el printer manager funcionaba correctamente. Como hago con esta forma que vos planteas para pasar el tamañp y los margenes de la hoja que tiene que usar la impresora?
Muchas Gracias
Saludos
However, I now need to modify the code so that it specifies a specific tray on the printer to print the report.
All the reports are the same size so the media size will not change but I need to be able to specify tray 2, 3, or 4. The use of this application limited to a specific audience so I know they are printing to 1 of 4 printers which are the same exact model. Only the printer name changes between them.
Thanks,
Susan
Si bien le defino el area, tal como definiste mas arriba, me corta la etiqueta hacia la derecha. Como si agregara un margen.
Pense que era por el area imprimible de la impresora pero desde el Ireport se imprime completamente.
Este es mi codigo
Sabrias decirme que puede estar generando ese error? Gracias!
Cecilia.
Nice code.
When i try printing a jarper report using this code, it gives me Error java.awt.HeadlessException. Why does this happen.
It works if i use JasperPrintManager.printReport(jasperPrint, false); and prints the report in default printer.
I use windows.
Is there any way of printing the report in client printer?
Thanks.
nose si alguien tiene el mismo problema pero por favor ahi les dejo mi msn si alguien ya lo tiene resuelto
Good continuation
Here is what I have done to print Jasper Report, my code simply calls the JRPrintServiceExporter. exportReport(), provided JasperPrint and PrintServiceAttributeSet object parameters are set to JRPrintServiceExporter object. Also IgnorePagination property is properly set in the JasperPrint object which is getting passed into Jasper engine. Jasper engine prints the report to printer in a single page which is fine. But all the report data are not getting printed which is actual issue here.
I am using Jasperreport 5.6.0
Please suggest what should we do to overcome this problem.
please help me . thanks
This tutorial is useful for Swing, JavaFX or any other client-side java application. Probably you are sending print commands to a webapplication thus your prints will come out through a server printer.
To print through a client side configured printer you should implement an applet, jnlp or some other solution that receives the document to print from the server (pdf, ps, plain text...) and then issues the print command on the client's computer environment.
Thanks in advance..
Printing a JasperReport into a thermal printer would be the same as printing a PDF.
I've worked with Zebra and TEC label printers and most of them supported graphics. The main drawback is that this kind of printing is much slower than sending just plain text directly to the printer.