Viewed   4.3k times

I'm new to JasperReports and find myself getting pretty lost with it. I've got a webapp in JSF that I want to use to print a PDF. I've built the report, and am able to successfully compile and fill it with all my parameters. However, I'm lost on the actual output portion. I'd like it go to a printer as a PDF. I don't care about ever seeing it on screen, straight to printer would be the ideal (from the server would be ideal, but client would also be fine as we could setup the clients to print as necessary (it's an internal app)).

 Answers

1

I'd like it go to a printer as a PDF. I don't care about ever seeing it on screen, straight to printer would be the ideal

You can't do it with plain HTML/CSS/JS. As JSF is basically just a HTML/CSS/JS code generator, it can't do any magic for you. Closest what you can get is JavaScript's window.print(), but that would still show the user the printer settings and such (basically, it does the same as Ctrl+P).

Your best bet is to create an Applet which uses the javax.print API and then embed that Applet in your JSF page by HTML <applet> or <object> tag.

If you can live with seeing it straight on screen and delegating the print job to the enduser itself, then you can send a PDF file to screen by JSF as follows:

public void sendPdf() throws IOException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.setResponseContentType("application/pdf");
    externalContext.setResponseHeader("Content-Disposition", "inline; filename="filename.pdf"");
    yourJasperReportsClass.writePdfTo(externalContext.getResponseOutputStream());
    facesContext.responseComplete();
}

I have never worked with JasperReports, so the yourJasperReportsClass.writePdfTo() was just a random guess, but the hint should be clear enough. You basically need to instruct it to write the PDF to the response body.


Update: as per the comments, that printer is actually connected to the server, not to the client and you actually want to let the server print it to its printer. In that case, just use the javax.print API. At the bottom of that document you can find some code examples. Here's an extract of relevance:

Using the API

A typical application using the Java Print Service API performs these steps to process a print request:

  • Chooses a DocFlavor.
  • Creates a set of attributes.
  • Locates a print service that can handle the print request as specified by the DocFlavor and the attribute set.
  • Creates a Doc object encapsulating the DocFlavor and the actual print data, which can take many forms including: a Postscript file, a JPEG image, a URL, or plain text.
  • Gets a print job, represented by DocPrintJob, from the print service.
  • Calls the print method of the print job.

The following code sample demonstrates a typical use of the Java Print Service API: locating printers that can print five double-sided copies of a Postscript document on size A4 paper, creating a print job from one of the returned print services, and calling print.

FileInputStream psStream; 

try { 
  psStream = new FileInputStream("file.ps");
} catch (FileNotFoundException ffne) {
} 

if (psStream == null) { 
  return;
}

DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT; 
Doc myDoc = new SimpleDoc(psStream, psInFormat, null); 
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); 
aset.add(new Copies(5)); 
aset.add(MediaSize.A4); 
aset.add(Sides.DUPLEX); 

PrintService[] services = PrintServiceLookup.lookupPrintServices(psInFormat, aset); > 
if (services.length > 0) { 
  DocPrintJob job = services[0].createPrintJob(); 

  try {
    job.print(myDoc, aset); 
  } catch (PrintException pe) {
  }
} 

It's not relevant if the above code called by a JSF managed bean. It's after all just Java. You might only want to modify the DocFlavor and other settings.

Saturday, October 8, 2022
 
1

I finally worked it out.

I can't post my code here, but here's what I did:

I rendered the PDF onto 2 canvases, one small for the thumbnail and one huge for printing (hidden). I then had a print button that opened a new window containing an img tag containing the contents of the huge canvas using toImageURL(). The print() function was called on the new window, followed by close() to close it automatically once printed.

This resulted in an almost-full-size print of the PDf, albeit with the usual page no and datestamp from the browser.

Saturday, November 5, 2022
2

Apache PDFBox. It is currently in incubation, but the PDF printing functionality has been around before that. Internally, it uses the Java Print Services to create a print job, and it also supports silent printing.

Do note that it requires Fontbox as well, and the current (upcoming 0.8.0 release) has included graceful fallback for documents with Type 0 fonts. Type 1 fonts are printed correctly; however in 0.7.3, attempts to print documents with Type 0 fonts will result in an exception being thrown.

Wednesday, November 9, 2022
 
josefn
 
3

Is there an equivalent of Java '==' for Objects in EL?

Looks like it is not, but you don't really need it. EL == (and eq) will use the equals method when comparing object references, and it already supports null comparison. If your class happens to not override equals, then it will use Object#equals that ends using Java == for equality check.

If your class happens to override equals method, make sure to write a good implementation. As example:

public boolean equals(Object o) {
    if (o == null) {
        return false;
    }
    if (this == o) {
        return true;
    }
    if (...) {
        //add here the rest of the equals implementation...
    }
    return false;
}

More info:

  • Java EE tutorial: Expression Language: Operators
Tuesday, November 1, 2022
5

Is that chunk of independent code placed in the right place?, Or it is wrong, the user should not be allowed to see that from the URL?

Put it somewhere in /WEB-INF. Direct access to this folder is disallowed by the container.


Is that place save to have other components like login, register...?

I don't understand you. Perhaps you meant to say "safe" instead of "save"? What do you mean with "other components"?


To avoid user access directly the component i could place it in WEB-INF folder, but then i have a problem that the include tag does not find the path. What should i do?

Your path was apparently plain wrong. Facelet templates, includes, tags and compositions (not composite components) can perfectly be placed in /WEB-INF.


What would be the best practice, where to place this independent chunks of code?

Put it in /WEB-INF. Best practice is to use absolute paths, i.e. start the path with /. It will be resolved relative to the webcontent root. E.g.

<ui:include src="/WEB-INF/languageChanger.xhtml" />

Only the "main" page (the one which is to be requested by URL) cannot be placed in /WEB-INF.

Tuesday, October 4, 2022
 
dpayne
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :