Printing PDF from JasperReports

2020-02-06 04:43发布

问题:

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

回答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.