net.sf.jasperreports.engine.export.JRPrintServiceExporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.engine.export;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.List;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.print.JRPrinterAWT;
import net.sf.jasperreports.export.ExporterInputItem;
import net.sf.jasperreports.export.ExporterOutput;
import net.sf.jasperreports.export.PrintServiceExporterConfiguration;
import net.sf.jasperreports.export.PrintServiceReportConfiguration;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleGraphics2DExporterOutput;
import net.sf.jasperreports.export.SimpleGraphics2DReportConfiguration;
/**
* Prints a JasperReports document using the Java Print Service API.
*
* There are four ways of using the Java Print Service with the Java 2D API:
*
* - Printing 2D graphics using
java.awt.print.PrinterJob
* - Streaming 2D graphics using
java.awt.print.PrinterJob
* - Printing 2D graphics using
javax.print.DocPrintJob
and a service-formatted javax.print.DocFlavor
* - Streaming 2D graphics using
javax.print.DocPrintJob
and a service-formatted javax.print.DocFlavor
*
*
* The {@link net.sf.jasperreports.engine.export.JRPrintServiceExporter}
* implementation takes the first approach and uses some of the methods added to the
* java.awt.print.PrinterJob
class:
*
* - Static convenience methods to look up print services that can image 2D graphics,
* which are returned as an array of
PrintService
or
* StreamPrintServiceFactory
objects depending on the method
* - Methods to set and get a
PrintService
on a PrinterJob
* - A
pageDialog()
method that takes a PrintRequestAttributeSet
parameter
* - A
printDialog()()
method that takes a PrintRequestAttributeSet
parameter
* - A print method that takes a
PrintRequestAttributeSet
parameter
*
* Looking Up a Printing Service
* This exporter tries to find a print service that supports the necessary attributes. The set of
* attributes can be supplied to the exporter in the form of a
* javax.print.attribute.PrintServiceAttributeSet
object that is passed as the
* value for the special
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#getPrintServiceAttributeSet() getPrintServiceAttributeSet()}
* exporter configuration setting. For more
* details about the attributes that can be part of such an attribute set, check the Java Print
* Service API documentation.
*
* The lookup procedure might return one or more print services able to handle the
* specified print service attributes. If so, the exporter uses the first one in the list. If no
* suitable print service is found, then the exporter throws an exception. As an alternative, a
* javax.print.PrintService
instance can be passed in using the
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#getPrintService() getPrintService()}
* exporter configuration setting when users do not want the Java Print Service to search for an
* available print service.
* Configuring the Printer Job
* Once a print service has been located, it is associated with a PrinterJob
instance.
* Further customization is made by passing a
* javax.print.attribute.PrintRequestAttributeSet
instance when calling the
* print()
method on the PrinterJob
object to start the printing process.
*
* To supply the javax.print.attribute.PrintRequestAttributeSet
object
* containing the desired javax.print.attribute.PrintRequestAttribute
values to
* the exporter, set the special
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#getPrintRequestAttributeSet() getPrintRequestAttributeSet()}
* exporter configuration setting.
* Displaying Print Dialogs
* If this exporter is invoked by a desktop or client-side Java application, you can offer the
* end user a final chance to customize the printer job before the printing process actually
* starts. The exporter has two other predefined configuration settings:
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPageDialog() isDisplayPageDialog()}
* and
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPrintDialog() isDisplayPrintDialog()},
* both receiving java.lang.Boolean
values, which show or
* suppress the page dialog and/or the print dialog associated with the PrinterJob
* instance.
*
* The two dialogs are cross-platform. They enable users to alter the print service attributes
* and the print request attributes that are already set for the current print service and printer
* job. They also allow canceling the current printing procedure altogether. When batch
* printing a set of documents, if
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPageDialog() isDisplayPageDialog()} or
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPrintDialog() isDisplayPrintDialog()} are
* set to true, a dialog window will pop up each time a document in the list is to be
* printed. This is very useful if you intend to set different printing options for each
* document. However, setting the same page/printing options each time would quickly
* become cumbersome. If same settings are intended for all documents in the list, the
* exporter provides two additional predefined export configuration settings:
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPageDialogOnlyOnce() isDisplayPageDialogOnlyOnce()} and
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPrintDialogOnlyOnce() isDisplayPrintDialogOnlyOnce()}. These
* are only effective if the corresponding
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPageDialog() isDisplayPageDialog()} or
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPrintDialog() isDisplayPrintDialog()} are
* set to true.
*
* If {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPageDialogOnlyOnce() isDisplayPageDialogOnlyOnce()}
* is true, then the page dialog will open only
* once, and the export options set within will be preserved for all documents in the list.
* The same thing happens when
* {@link net.sf.jasperreports.export.PrintServiceExporterConfiguration#isDisplayPrintDialogOnlyOnce() isDisplayPrintDialogOnlyOnce()}
* is set to true - the print dialog will open only once.
*
* Below is an example of configuring the print service exporter taken from the supplied
* /demo/ samples/printservice
sample:
*
* public void print() throws JRException
* {
* PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
* printRequestAttributeSet.add(MediaSizeName.ISO_A4);
*
* PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();
* //printServiceAttributeSet.add(new PrinterName("Epson Stylus 820 ESC/P 2", null));
* //printServiceAttributeSet.add(new PrinterName("hp LaserJet 1320 PCL 6", null));
* //printServiceAttributeSet.add(new PrinterName("PDFCreator", null));
*
* JRPrintServiceExporter exporter = new JRPrintServiceExporter();
*
* exporter.setExporterInput(new SimpleExporterInput("build/reports/PrintServiceReport.jrprint"));
* SimplePrintServiceExporterConfiguration configuration = new SimplePrintServiceExporterConfiguration();
* configuration.setPrintRequestAttributeSet(printRequestAttributeSet);
* configuration.setPrintServiceAttributeSet(printServiceAttributeSet);
* configuration.setDisplayPageDialog(false);
* configuration.setDisplayPrintDialog(true);
* exporter.setConfiguration(configuration);
* exporter.exportReport();
* System.err.println("Printing time : " + (System.currentTimeMillis() - start));
* }
*
* @see net.sf.jasperreports.export.PrintServiceExporterConfiguration
* @author Teodor Danciu ([email protected])
*/
public class JRPrintServiceExporter extends JRAbstractExporter implements Printable
{
protected static final String PRINT_SERVICE_EXPORTER_PROPERTIES_PREFIX = JRPropertiesUtil.PROPERTY_PREFIX + "export.print.service.";
public static final String EXCEPTION_MESSAGE_KEY_PRINT_SERVICE_NOT_FOUND = "export.print.service.not.found";
/**
*
*/
protected JRGraphics2DExporter exporter;
protected SimpleGraphics2DReportConfiguration grxConfiguration;
protected int reportIndex;
private PrintService printService;
private Boolean[] printStatus;
protected class ExporterContext extends BaseExporterContext
{
}
/**
* @see #JRPrintServiceExporter(JasperReportsContext)
*/
public JRPrintServiceExporter()
{
this(DefaultJasperReportsContext.getInstance());
}
/**
*
*/
public JRPrintServiceExporter(JasperReportsContext jasperReportsContext)
{
super(jasperReportsContext);
exporterContext = new ExporterContext();
}
@Override
protected Class getConfigurationInterface()
{
return PrintServiceExporterConfiguration.class;
}
@Override
protected Class getItemConfigurationInterface()
{
return PrintServiceReportConfiguration.class;
}
@Override
protected void ensureOutput()
{
//nothing to do
}
@Override
public void exportReport() throws JRException
{
/* */
ensureJasperReportsContext();
ensureInput();
initExport();
ensureOutput();
try
{
PrintServiceExporterConfiguration configuration = getCurrentConfiguration();
PrintServiceAttributeSet printServiceAttributeSet = configuration.getPrintServiceAttributeSet();
if (printServiceAttributeSet == null)
{
printServiceAttributeSet = new HashPrintServiceAttributeSet();
}
boolean displayPageDialog = false;
boolean displayPageDialogOnlyOnce = false;
boolean displayPrintDialog = false;
boolean displayPrintDialogOnlyOnce = false;
Boolean pageDialog = configuration.isDisplayPageDialog();
if (pageDialog != null)
{
displayPageDialog = pageDialog;
}
Boolean pageDialogOnlyOnce = configuration.isDisplayPageDialogOnlyOnce();
if (displayPageDialog && pageDialogOnlyOnce != null)
{
// it can be (eventually) set to true only if displayPageDialog is true
displayPageDialogOnlyOnce = pageDialogOnlyOnce;
}
Boolean printDialog = configuration.isDisplayPrintDialog();
if (printDialog != null)
{
displayPrintDialog = printDialog;
}
Boolean printDialogOnlyOnce = configuration.isDisplayPrintDialogOnlyOnce();
if (displayPrintDialog && printDialogOnlyOnce != null)
{
// it can be (eventually) set to true only if displayPrintDialog is true
displayPrintDialogOnlyOnce = printDialogOnlyOnce;
}
PrinterJob printerJob = PrinterJob.getPrinterJob();
JRPrinterAWT.initPrinterJobFields(printerJob);
printerJob.setPrintable(this);
printStatus = null;
// determining the print service only once
printService = configuration.getPrintService();
if (printService == null) {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, printServiceAttributeSet);
if (services.length > 0)
{
printService = services[0];
}
}
if (printService == null)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_PRINT_SERVICE_NOT_FOUND,
(Object[])null
);
}
try
{
printerJob.setPrintService(printService);
}
catch (PrinterException e)
{
throw new JRException(e);
}
List items = exporterInput.getItems();
PrintRequestAttributeSet printRequestAttributeSet = null;
if(displayPrintDialogOnlyOnce || displayPageDialogOnlyOnce)
{
printRequestAttributeSet = new HashPrintRequestAttributeSet();
setDefaultPrintRequestAttributeSet(printRequestAttributeSet);
setOrientation(items.get(0).getJasperPrint(), printRequestAttributeSet);
if(displayPageDialogOnlyOnce)
{
if(printerJob.pageDialog(printRequestAttributeSet) == null)
{
return;
}
else
{
displayPageDialog = false;
}
}
if(displayPrintDialogOnlyOnce)
{
if(!printerJob.printDialog(printRequestAttributeSet))
{
printStatus = new Boolean[]{Boolean.FALSE};
return;
}
else
{
displayPrintDialog = false;
}
}
}
List status = new ArrayList();
// fix for bug ID artf1455 from jasperforge.org bug database
for(reportIndex = 0; reportIndex < items.size(); reportIndex++)
{
ExporterInputItem item = items.get(reportIndex);
setCurrentExporterInputItem(item);
PrintServiceReportConfiguration lcItemConfiguration = getCurrentItemConfiguration();
exporter = new JRGraphics2DExporter(jasperReportsContext);
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
grxConfiguration = new SimpleGraphics2DReportConfiguration();
grxConfiguration.setProgressMonitor(lcItemConfiguration.getProgressMonitor());
grxConfiguration.setOffsetX(lcItemConfiguration.getOffsetX());
grxConfiguration.setOffsetY(lcItemConfiguration.getOffsetY());
grxConfiguration.setZoomRatio(lcItemConfiguration.getZoomRatio());
// exporter.setParameter(JRExporterParameter.CLASS_LOADER, classLoader);
// exporter.setParameter(JRExporterParameter.URL_HANDLER_FACTORY, urlHandlerFactory);
// exporter.setParameter(JRExporterParameter.FILE_RESOLVER, fileResolver);
grxConfiguration.setExporterFilter(filter);
grxConfiguration.setMinimizePrinterJobSize(lcItemConfiguration.isMinimizePrinterJobSize());
if(displayPrintDialog || displayPageDialog ||
(!displayPrintDialogOnlyOnce && !displayPageDialogOnlyOnce))
{
printRequestAttributeSet = new HashPrintRequestAttributeSet();
setDefaultPrintRequestAttributeSet(printRequestAttributeSet);
setOrientation(jasperPrint, printRequestAttributeSet);
}
try
{
PageRange pageRange = getPageRange();
int startPageIndex = (pageRange == null || pageRange.getStartPageIndex() == null) ? 0 : pageRange.getStartPageIndex();
int endPageIndex = (pageRange == null || pageRange.getEndPageIndex() == null) ? (jasperPrint.getPages().size() - 1) : pageRange.getEndPageIndex();
if (items.size() == 1)
{
printRequestAttributeSet.add(new PageRanges(startPageIndex + 1, endPageIndex + 1));
}
printerJob.setJobName("JasperReports - " + jasperPrint.getName());
if (displayPageDialog)
{
printerJob.pageDialog(printRequestAttributeSet);
}
if (displayPrintDialog)
{
if (printerJob.printDialog(printRequestAttributeSet))
{
status.add(Boolean.TRUE);
printerJob.print(printRequestAttributeSet);
}
else
{
status.add(Boolean.FALSE);
}
}
else
{
PageFormat pageFormat = printerJob.defaultPage();
Paper paper = pageFormat.getPaper();
switch (jasperPrint.getOrientationValue())
{
case LANDSCAPE :
{
pageFormat.setOrientation(PageFormat.LANDSCAPE);
paper.setSize(jasperPrint.getPageHeight(), jasperPrint.getPageWidth());
paper.setImageableArea(
0,
0,
jasperPrint.getPageHeight(),
jasperPrint.getPageWidth()
);
break;
}
case PORTRAIT :
default :
{
pageFormat.setOrientation(PageFormat.PORTRAIT);
paper.setSize(jasperPrint.getPageWidth(), jasperPrint.getPageHeight());
paper.setImageableArea(
0,
0,
jasperPrint.getPageWidth(),
jasperPrint.getPageHeight()
);
}
}
// setting the paper object back as getPaper() returns a clone
pageFormat.setPaper(paper);
printerJob.setPrintable(this, pageFormat);
printerJob.print(printRequestAttributeSet);
}
}
catch (PrinterException e)
{
throw new JRException(e);
}
}
printStatus = status.toArray(new Boolean[status.size()]);
printService = printerJob.getPrintService();
}
finally
{
resetExportContext();
}
}
@Override
protected void initExport()
{
super.initExport();
}
@Override
protected void initReport()
{
super.initReport();
}
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
{
if (Thread.interrupted())
{
throw new PrinterException("Current thread interrupted.");
}
if ( pageIndex < 0 || pageIndex >= jasperPrint.getPages().size() )
{
return Printable.NO_SUCH_PAGE;
}
SimpleGraphics2DExporterOutput output = new SimpleGraphics2DExporterOutput();
output.setGraphics2D((Graphics2D)graphics);
exporter.setExporterOutput(output);
grxConfiguration.setPageIndex(pageIndex);
exporter.setConfiguration(grxConfiguration);
try
{
exporter.exportReport();
}
catch (JRException e)
{
throw new PrinterException(e.getMessage()); //NOPMD
}
return Printable.PAGE_EXISTS;
}
private void setOrientation(JasperPrint jPrint,PrintRequestAttributeSet printRequestAttributeSet)
{
if (!printRequestAttributeSet.containsKey(MediaPrintableArea.class))
{
int printableWidth;
int printableHeight;
switch (jPrint.getOrientationValue())
{
case LANDSCAPE:
printableWidth = jPrint.getPageHeight();
printableHeight = jPrint.getPageWidth();
break;
default:
printableWidth = jPrint.getPageWidth();
printableHeight = jPrint.getPageHeight();
break;
}
printRequestAttributeSet.add(
new MediaPrintableArea(
0f,
0f,
printableWidth / 72f,
printableHeight / 72f,
MediaPrintableArea.INCH
)
);
}
if (!printRequestAttributeSet.containsKey(OrientationRequested.class))
{
OrientationRequested orientation;
switch (jPrint.getOrientationValue())
{
case LANDSCAPE:
orientation = OrientationRequested.LANDSCAPE;
break;
default:
orientation = OrientationRequested.PORTRAIT;
break;
}
printRequestAttributeSet.add(orientation);
}
}
private void setDefaultPrintRequestAttributeSet(PrintRequestAttributeSet printRequestAttributeSet)
{
PrintRequestAttributeSet configPrintRequestAttributeSet = getCurrentConfiguration().getPrintRequestAttributeSet();
if (configPrintRequestAttributeSet != null)
{
printRequestAttributeSet.addAll(configPrintRequestAttributeSet);
}
}
// artf1936
public static boolean checkAvailablePrinters()
{
PrintService[] ss = java.awt.print.PrinterJob.lookupPrintServices();
for (int i=0;ijava.lang.Boolean values, one for each appearance of the print dialog during the last export operation.
* A Boolean.TRUE value in this array means that for that particular occurrence of the print dialog, the OK button was hit.
* A Boolean.FALSE value means the respective print dialog was canceled.
*/
public Boolean[] getPrintStatus()
{
return printStatus;
}
/**
* Returns the {@link PrintService} instance used by the exporter last time the exportReport() method was run.
*/
public PrintService getPrintService()
{
return printService;
}
@Override
public String getExporterKey()
{
return null;
}
@Override
public String getExporterPropertiesPrefix()
{
return PRINT_SERVICE_EXPORTER_PROPERTIES_PREFIX;
}
}