RSS

Java : BIRT Report Printing Without User Interaction (Background Printing)

29 Feb

May 18, 2009 by laukik81

During one of my projects , I needed server side printing of BIRT report in which User Interaction was not required ie Background Printing. By the term “No User Interaction” , Print Dialog is not involved anywhere. It could be used for batch printing.
Or A copy of viewed report is printed on the server without letting the user to know it.

BIRT provides server side printing but again it comes to User Interaction.Here BIRT’s ReportEngine API Plays a important role.

Steps :

(1). Create a servlet which can be invoked from a simple Java Program or any stored procedure.

(2).In this servlet, run the report through ReportEngine API and generate a temp pdf of report

(3). Print this generated pdf through Java and delete it.

ReportPrintingServlet.java


import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.Properties;

import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.birt.core.framework.IPlatformContext;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.core.framework.PlatformFileContext;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.EngineConstants;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportEngineFactory;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.engine.api.PDFRenderOption;

import com.sun.pdfview.PDFFile;

public class ReportPrintingServlet extends HttpServlet{

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

System.out.println("Came for printing");
ServletContext servletContext = getServletConfig().getServletContext();
Object attribute = servletContext.getAttribute("reportprintproperties");
Properties properties = (Properties) attribute;
try
{
generatePDFFile(properties, request);
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void generatePDFFile(Properties properties,HttpServletRequest request) throws Exception
{
final String REPORT_ENGINE = Path of your ReportEngine
final String REPORTS_PATH = Path where .rptdesign files are kept
final String OUTPUT_LOCATION = Location where pdf is to be generated

PDFRenderOption options = new PDFRenderOption();
EngineConfig config = new EngineConfig();
config.setEngineHome(REPORT_ENGINE);
IPlatformContext context = new PlatformFileContext();
config.setEngineContext(context);
IReportEngineFactory factory = (IReportEngineFactory) Platform
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);

IReportEngine engine = factory.createReportEngine(config);
IReportRunnable runnable = null;
try {
runnable = engine.openReportDesign(REPORTS_PATH);
} catch (EngineException e) {
System.err.println("Design " + REPORTS_PATH + " not found!");
e.printStackTrace();
engine.destroy();
}

IRunAndRenderTask task = engine.createRunAndRenderTask(runnable);

ByteArrayOutputStream fso = new ByteArrayOutputStream();
options.setOutputStream(fso);
options.setOutputFormat(PDFRenderOption.OUTPUT_FORMAT_PDF);
options.setSupportedImageFormats("PNG");
options.setOutputFileName(OUTPUT_LOCATION); //
task.setRenderOption(options);

Enumeration names = request.getParameterNames();

while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String value = request.getParameter(name);
task.setParameterValue(name, value);
}

task.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY,Thread.currentThread().getContextClassLoader());
task.run();
System.out.println("Created Report " + OUTPUT_LOCATION + ".");
engine.destroy();

String printerName = request.getParameter("printer");
if(printPDF(OUTPUT_LOCATION,printerName))
{
deletePDFFile(OUTPUT_LOCATION);

}
}

private boolean printPDF(String filename,String printerName) throws Exception{

FileInputStream fis = null;
BufferedInputStream bufferedInputStream = null;
ByteBuffer bb = null;

try {
File f = new File(filename);
fis = new FileInputStream(f);
//FileChannel fc = fis.getChannel();
//ByteBuffer bb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
bufferedInputStream = new BufferedInputStream(fis);
byte bytes[] = new byte[fis.available()];
bufferedInputStream.read(bytes);
bb = ByteBuffer.wrap(bytes);
PDFFile pdfFile = new PDFFile(bb); // Create PDF Print Page
PDFPrintPage pages = new PDFPrintPage(pdfFile);

// Create Print Job
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
pjob.setJobName(f.getName());

/**
* Use the printer which comes as parameter from URL.
* So that we can redirect the print at runtime to any of the printer.
*/
PrintService selectedPrinter = null;
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService printService : services) {

System.out.println(printService.getName()+" = "+printerName);
if(printService.getName().equalsIgnoreCase(printerName))
{
selectedPrinter = printService;

break;
}

}
pjob.setPrintService(selectedPrinter);

Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
System.out.println("Printer : " + pjob.getPrintService().getName());
// Send print job to default printer

pjob.print();
System.out.println("Sent for Printing : ....");

return true;

} catch (Exception e) {
e.printStackTrace();
return false;
}
finally{

bb.clear();
try
{
fis.close();
bufferedInputStream.close();
}
catch(Exception e)
{
throw new Exception(e);
}
finally
{
fis = null;
bufferedInputStream = null;
}

}

}

private void deletePDFFile(String OUTPUT_LOCATION) throws Exception
{

File file = new File(OUTPUT_LOCATION);
boolean deleted = false;
if(file != null && file.exists())
{
// file.renameTo(new File(OUTPUT_LOCATION.replace(".", "_")));
deleted = file.delete();
}
System.out.println(" Generated PDF Deleted "+deleted);
}

}

Sample URL :

http://infotraksrv:8080/BirtReportPrinting/print?__report=reports/myreport.rptdesign&printer=printserverprinter_name

In above URL,

print : Is the ReportPrintingServet
printer : Parameter specifies the printer location.
__report : Parameter specifies which report is to be printed

PDFRenderer needs to be in your classpath for printing PDF files.
You can download it from here

Note

Loading Report Engine is costly task so it is recommended to have it one time only.

Referenced by: http://laukik.wordpress.com/2009/05/18/java-birt-report-printing-without-user-interaction/

Advertisements
 
1 Comment

Posted by on February 29, 2012 in Birt Report

 

One response to “Java : BIRT Report Printing Without User Interaction (Background Printing)

  1. Hans-Georg

    December 8, 2014 at 10:33 PM

    i have a question:
    from where comes “BirtReportPrinting” in the URL?

     

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: