Choosing a printer programmatically in Jasper Reports 50


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.

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.

Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+Pin on PinterestEmail this to someone

Leave a comment

Your email address will not be published. Required fields are marked *

50 thoughts on “Choosing a printer programmatically in Jasper Reports

  • Juriy

    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.

  • Juriy

    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?

  • Marc Nuri

    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);

  • Joerg

    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!

  • Marc Nuri

    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.

  • Joerg

    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…

  • cesar

    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

  • Marc Nuri

    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.

  • cesar

    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?

  • bm

    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!

  • Marc Nuri

    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.

  • bm

    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?

  • Marc Nuri

    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.

  • Rishiraj Barthakur

    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

  • domino

    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?

  • paulo

    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>

  • Marc

    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.

  • Roose

    <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

  • Sammy

    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!

  • akbar

    how to set paper size in custom ?.for example a half of A4. because the size is not exist in default MediaSizeName. thank

  • pegah

    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?

  • naveen

    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.

  • naveen at port

    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.

  • Romina

    Marc, buen dia, muy bueno tu articulo de como establecer la impresora en la que se va a imprimir y otros atributos preestablecidos, lo probe y me funciona perfectamente excepto que el reporte que yo imprimo tiene un tama

  • Steve

    I have a for loop in my java code that prints 1..n jasper reports. I would like the print dialog to show when I print the first report, but not for reports 2..n. How can I save the print properties from the first report and apply them to all other reports being printed?

  • Romina

    Hola yo nuevamente, solucione lo que te consultaba anteriormente. Pero tengo un problema un poco extra

  • Susan M

    I’ve inherited a java web app running on tomcat whose main purpose is to print jasper reports. We are passing the printer information and our successful in selecting the printer similar to what you are doing above. 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

  • Cecilia

    Hola, estoy teniendo un problema con una impresora de etiquetas. 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

    JasperPrint jp = JasperFillManager.fillReport(report, parameters, new ReportProvider(data));

    JRPrintServiceExporter exporter = new JRPrintServiceExporter();

    PrintRequestAttributeSet printRequestAttributeSet =

    new HashPrintRequestAttributeSet();

    PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);

    if(services[selectedService]!=null) {

    float w= (jp.getPageWidth());

    float h=(jp.getPageHeight());

    MediaSizeName mediaSizeName = MediaSize.findMedia(w,h,MediaPrintableArea.INCH);

    printRequestAttributeSet.add(mediaSizeName);

    int unidad = MediaPrintableArea.MM;

    // Busco el tama

  • nowhere

    My application needs tray selection. However, I cannot find any method to select different tray in JasperReport. Other than printer tray selection, I would like to see whether there is any method to change the top margin, left margin and right margin. Can anyone give me a quick solution?

  • good girl

    I created jasper report from windows OS. And my users using linux mandriva as their OS. My program and reports run well in their computer. But when they are trying to print (click the printer button), it appeared nothing. Although when I ran it in windows, the print dialog did show. Can you help me with this problem? Thx before.

  • Aerobie Disc

    Thank you for sharing to us.there are many person searching about that now they will find enough resources by your post.

  • kavitha

    Hi,

    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.

  • Peanut Butter

    I find this information very useful and it has considerably saved my time. You have shared a nice blog. I really want ot say you thanks for sharing this nice article with us.

  • writing? I have a presentation next week

    Thank you for another great article. Where else could anyone get that kind of information in such a perfect way of

  • David

    tengo un problema a la hora de imprimir una factura, lo que hace es que me sale solo una parte como si el margen o el tama

  • Security Companies St Davids

    Its a wonderful post and also informative. I would like to thank you for sharing this information. Thanks for sharing

  • Sabina Cao

    You write some great code. I’m learning but this is far more advanced than I am right now. I hope to be this good someday.

  • Shamseer pc

    thanks for the code,when i executed this code,report is getting printed on server side.can you please hel me,how to print on client side..? thanks in advance.

  • BENKHAOUA SIDAHMED

    hi, i have this proble i use a servlet

    java.awt.HeadlessException

    18:20:40,761 ERROR [stderr] (http-/0.0.0.0:8080-3) at sun.print.RasterPrinterJob.printDialog(RasterPrinterJob.java:795)

    18:20:40,761 ERROR [stderr] (http-/0.0.0.0:8080-3) at net.sf.jasperreports.engine.export.JRPrintServiceExporter.exportReport(JRPrintServiceExporter.java:258)

    18:20:40,762 ERROR [stderr] (http-/0.0.0.0:8080-3) at com.iconsoft.apps.gestioncommercial.web.servlet.PrintBarCode.print(PrintBarCode.java:204)

    18:20:40,762 ERROR [stderr] (http-/0.0.0.0:8080-3) at com.iconsoft.apps.gestioncommercial.web.servlet.PrintBarCode.doGet(PrintBarCode.java:115)

    18:20:40,763 ERROR [stderr] (http-/0.0.0.0:8080-3) at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)

    18:20:40,763 ERROR [stderr] (http-/0.0.0.0:8080-3) at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

    18:20:40,763 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)

    18:20:40,764 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

    18:20:40,764 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)

    18:20:40,765 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)

    18:20:40,765 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

    18:20:40,765 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)

    18:20:40,766 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)

    18:20:40,766 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)

    18:20:40,766 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)

    18:20:40,766 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)

    18:20:40,767 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)

    18:20:40,767 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)

    18:20:40,767 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)

    18:20:40,768 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

    18:20:40,768 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)

    18:20:40,768 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:161)

    18:20:40,768 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)

    18:20:40,769 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)

    18:20:40,769 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:165)

    18:20:40,769 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)

    18:20:40,769 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

    18:20:40,770 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

    18:20:40,770 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:372)

    18:20:40,770 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)

    18:20:40,771 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:679)

    18:20:40,771 ERROR [stderr] (http-/0.0.0.0:8080-3) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:931)

    18:20:40,771 ERROR [stderr] (http-/0.0.0.0:8080-3) at java.lang.Thread.run(Thread.java:722)

  • miren

    Here I was trying to print jasper report via java code silently using jasper API.

    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.

  • SHAIK RAHAMATHALI

    Every time i am printing jasper report, it printing on server side configured printer . i need to print jasper report on client side configured printer.
    please help me . thanks

    • Marc Nuri Post author

      Hello Shank
      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.