jueves, 22 marzo 2007
Choosing a printer programmatically in Jasper Reports
« JVM for Windows Mobile (J2ME) // PocketPC - PDA | Main | Java App for PostgreSQL scheduled backups using pg_dump (Windows only) »Jasper Reports is in my opinion by far the best report engine available for Java, even more, it's open source! In the project page there is enough information available to build simple and some 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.
JasperPrint print = JasperFillManager.fillReport( this.class.getResource("/classpath/yourReport.jasper").getPath(), new HashMap(), new yourReportDataSource());
PrinterJob job = PrinterJob.getPrinterJob();
/* Create an array of PrintServices */
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
int selectedService = 0;
/* Scan found services to see if anyone suits our needs */
for(int i = 0; i < services.length;i++){
if(services[i].getName().toUpperCase().contains("Your printer's name")){
/*If the service is named as what we are querying we select it */
selectedService = i;
}
}
job.setPrintService(services[selectedService]);
PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
MediaSizeName mediaSizeName = MediaSize.findMedia(4,4,MediaPrintableArea.INCH);
printRequestAttributeSet.add(mediaSizeName);
printRequestAttributeSet.add(new Copies(1));
JRPrintServiceExporter exporter;
exporter = new JRPrintServiceExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
/* We set the selected service and pass it as a paramenter */
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE, services[selectedService]);
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET, services[selectedService].getAttributes());
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET, printRequestAttributeSet);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG, Boolean.FALSE);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.TRUE);
exporter.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.
Technorati Tags: java j2se print report jasper jasperReports printservice printerjob
Posted by at 9:02 AM in Jasper Reports
[Trackback URL for this entry]
Just one more question: when i've executed the code, i've got a "Printer Setup" window. That's a bit annoying, cause we've already selected the printer and privided all information needed for printer.
Is there a way to get rid of this window?
To remove the printer selection dialog, you just have to change
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.TRUE);
to
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.FALSE);
Choosing a printer programmatically in Jasper Reports
Nuri. Марк любезно дал согласие опубликовать этот сниппет в нашем блоге. Думаю, этот материал хорошо дополнит серию уроков о JasperReports. Оригинал статьи: Choosing a printer programmatically in Jasper
Hello Marc,
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 wich 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!
Hi, I've read your translation of http://www.netbeans-forum.de/viewtopic.php?p=2767 but don't really understand what you need to do.
The article shows the code you need to run/print a report from a java program. In yout 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 lookup the service each time.
Thanks for the quick answer.
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...
Hi, I have a little problem. I'm using the code on my application. When I run the application on jdeveloper works great, I can print the report, but when I run the application in tomcat, at the moment I press the print button nothing happens, no print dialog appears and stays that way until the application times out. Any tip on what's happening?
Thanks
Hi Cesar.
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 serve and not in the client machine.
Thanks for answering. You're right I didn't explain my problem very well. I'm running the same application with jdeveloper and tomcat. The application generates the report inside an iframe and I used javascript to print the report inside the iframe. But I didn't like that the printed report showed the url, date and page number. So I was looking for a way to print the report just with the information I want without any aditional information the web browser could add. Is ther a way to solve this?
To solve your problem you have to build a servlet to print your generated reports.
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 ..
PrinterJob job = PrinterJob.getPrinterJob();
/* Create an array of PrintServices */
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
PrintService default_service = PrintServiceLookup.lookupDefaultPrintService();
int selectedService = 0;
/* Scan found services to see if anyone suits our needs */
for(int i = 0; i < services.length;i++)
{
if(services[i].getName().toUpperCase().equals(default_service.getName().toUpperCase()))
{
selectedService = i;
}
}
job.setPrintService(services[selectedService]);
PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
printRequestAttributeSet.add(MediaSizeName.NA_LETTER);
printRequestAttributeSet.add(new Copies(1));
JRPrintServiceExporter exporter;
exporter = new JRPrintServiceExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
/* We set the selected service and pass it as a paramenter */
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE, services[selectedService]);
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET, services[selectedService].getAttributes());
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET, printRequestAttributeSet);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG, Boolean.FALSE);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.FALSE);
exporter.exportReport();
}
thanks for your help!
As you say in your post, your report is run from a servlet. Servlets are always run in the server which holds them.
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.
Thank you for your response. 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
hi.I nid 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?
Marc, the search for the services is NOT necessary .
You can do:
<code>
PrintServiceAttributeSet requestAttributeSet = new HashPrintServiceAttributeSet();
serviceAttributeSet.add(new PrinterName(printerName, null));
exporter.setParameter( JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET, serviceAttributeSet);
............
exporter.exportReport();
</code>
Hi Paulo,
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 whaterver computer you install your program, then you should Paulo's code. Your program will load faster.
<JASPER Multiples clientes via WEB>
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
How to display dynamically generated jasper report in -> iFrame jsp page - Please Help...
Marc,
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!
how to set paper size in custom ?.for example a half of A4. because the size is not exist in default MediaSizeName. thank
Hi
thanks for ur tutorial.it was very helpfull 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?
hi all,
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.
hi all,
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.
hi all,
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.
Hi!
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.