Using various Java exporters provided by Jasper Reports

In my previous blog, I demonstrate how to export a Jasper report with the Java class JRHtmlExporter to an HTML email. In this blog, I will include the codes I use to export a Jasper report to other commonly used file formats. In all cases, I start with a JasperPrint object from a given Jasper Reports template and create the resulting file as an attachment in a HTTP response.

PDF file

For PDF file, you may just use the static method exportReportToPdf in class net.sf.jasperreports.engine.JasperExportManager as shown below:

byte[] pdfBytes = JasperExportManager.exportReportToPdf(print);
response.setContentType(“application/pdf”);
response.setHeader(“Content-Disposition”, “attachment;filename=example.pdf”);
response.getOutputStream().write(pdfBytes);
response.flushBuffer();

MS Excel xlsx file

For MS Excel 2007 or 2010 file, use class net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter:

JRXlsxExporter exporter = new JRXlsxExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
ByteArrayOutputStream os = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
exporter.exportReport();

response.setContentType(“application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”);
response.setHeader(“Content-Disposition”, “attachment;filename=example.xlsx”);
response.getOutputStream().write(os.toByteArray());
response.flushBuffer();

Note the content type set in the response header.

MS Excel xls file

If you need to export your report in older Excel file format, use class net.sf.jasperreports.engine.export.JRXlsExporter similar to codes above and replace the content type in the response header with “application/vnd.ms-excel” and filename suffix to xls:

JRXlsExporter exporter = new JRXlsExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
ByteArrayOutputStream os = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
exporter.exportReport();

response.setContentType(“application/vnd.ms-excel”);
response.setHeader(“Content-Disposition”, “attachment;filename=example.xls”);
response.getOutputStream().write(os.toByteArray());
response.flushBuffer();

CSV file

For csv files, use class net.sf.jasperreports.engine.export.JRCsvExporter

JRCsvExporter exporter = new JRCsvExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
StringBuffer buffer = new StringBuffer();
exporter.setParameter(JRExporterParameter.OUTPUT_STRING_BUFFER, buffer);
exporter.exportReport();

response.setContentType(“text/csv”);
response.setHeader(“Content-Disposition”, “attachment;filename=” + getFileName(name) + “.csv”);
response.getOutputStream().write(buffer.toString().getBytes());
response.flushBuffer();

Other file formats

The Jasper Reports API provides quite a few other exporters. Look at the Java Doc here .

Using Spring 3.1 Cache Abstraction and Ehcache

Spring 3.1 supports a new cache abstraction layer which allows you to implement caching in a web application beyond the L2 and query cache in Hibernate. This blog provides a quick walkthrough on how to setup and apply caching  in your codes using Spring and Ehcache.

Getting the jars

First, we need to add the spring context support and ehcache jar files to the project. I am using Maven and include the following dependencies in the pom file:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.5.2</version>
</dependency>

Configure Spring

As with any other Spring components, we need to configure some beans in a XML file. At a minimum, we will need the followings:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xmlns:cache=”http://www.springframework.org/schema/cache&#8221;
xsi:schemaLocation=”
http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd”&gt;

<cache:annotation-driven cache-manager=”cacheManager”/>

<bean id=”cacheManager”>
<property name=”cacheManager” ref=”ehcache”/>
</bean>

<!– Ehcache library setup –>
<bean id=”ehcache”
class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”>
<property name=”configLocation” value=”classpath:ehcache.xml”/>
</bean>

</beans>

Caching is setup via annotation, as configured in the tag cache:annotation-driven. Next a cache manager is defined and is referenced to a factory bean for instantiating Ehcache. The bean org.springframework.cache.ehcache.EhCacheManagerFactoryBean configLocation property is set to the ehcache.xml setup files where we will define the caches used by the application.

The ehcache.xml config file

I recommend starting with the ehcache-failsafe.xml found in the ehcache-core jar file and add the caches required by the application. An example for this blog is included below:

<!– Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes.

If there are more than 10000 elements it will overflow to the
disk cache,
–>
<cache name=”sampleCache1″
maxElementsInMemory=”10000″
eternal=”false”
overflowToDisk=”true”
timeToIdleSeconds=”300″
timeToLiveSeconds=”600″
/>

It is also necessary to set the directory to store the files when caches overflow into disk storage. To do this, update the path attribute in the diskStore tag:

 <diskStore path=”${CACHE_DIR}”/>

Note the use of variable CACHE_DIR above. This will allow us to define the directory using the Java JVM variable (-DCACHE_DIR) on different environments.

Adding Cache Annotations

Now we are ready to do something useful. To add caching to a method, use the @Cacheable annotation as shown below. I typically would add caching in the service layer.

    @Cacheable(value=”sampleCache1″, key=”#id”)
public Product load(String id) {
LOG.info(“load product with id” + id);
return repository.load(id);
}

I recommend setting the key explicitly instead of relying on the default key generator. Alternatively, you could configure your own key generator.

To evict an object in the cache, use @CacheEvict annotation. For example, we would have to evict the object in the cache in the update method.

    @CacheEvict(value=”sampleCache1″, key=”#product.id”, beforeInvocation=false /*default*/, allEntries=false /*default*/)
public void update(Product product) {
repository.update(product);
}

@CacheEvict annotation provides 2 handy attributes: beforeInvocation can be set to evict the object in the cache before or after (default) the method is executed. allEntries can be used to evict all objects in the cache. Only the object with the key is evicted by default.