Struts2 – Integrare JasperReports utilizzando il JasperReport plugin

Integrare Struts2 con JasperReports è veramente semplice. E’ possibile fare in modo che il risultato di una action sia generato da JasperReports e restituito sotto varie forme: PDF, HTML, XLS, CSV e files XML.

Per farlo occorre utilizzare il JasperReports Plugin che definisce, fra l’altro, il result type da utilizzare nella definizione della action. Il plugin non contiene le librerie di JasperReports, che quindi vanno aggiunte manualmente al progetto.

Le dipendenze

Se utilizzate maven, tutto questo si risolve con queste due dipendenze:

Il plugin:

<dependency>
	<groupId>org.apache.struts</groupId>
	<artifactId>struts2-jasperreports-plugin</artifactId>
	<version>2.3.15.1</version>
</dependency>

Le librerie di JasperReports (nel progetto di esempio ho dovuto dichiarare anche la iText):

<groupId>net.sf.jasperreports</groupId>
	<artifactId>jasperreports</artifactId>
	<version>5.1.2</version>
</dependency>
 
<dependency>
	<groupId>com.lowagie</groupId>
	<artifactId>itext</artifactId>
	<version>2.1.7</version>
</dependency>

Il Result Type

A questo punto abbiamo a disposizione un nuovo Result Type, che occorre aggiungere alla configurazione nel file struts.xml:

<result-types>
 
	...
	<result-type name="jasper" class="org.apache.struts2.views.jasperreports.JasperReportsResult"/>
</result-types>

L’esempio

In questo esempio viene creato un report utilizzando una lista di libri. La definizione dell’action è:

<action name="stampa" class="it.nicola.esempi.Biblioteca"
	method="stampa">
	<result name="success" type="jasper">
		<param name="location">/WEB-INF/report/biblioteca.jasper</param>
		<param name="dataSource">biblioteca</param>
		<param name="format">PDF</param>
 
		<param name="contentType">application/pdf</param>
		<param name="contentDisposition">inline; filename="biblioteca.pdf"</param>
	</result>
</action>

Questa action si aspetta di trovare il report già compilato in /WEB-INF/report/biblioteca.jasper.
Utilizzando il parametro dataSource viene passato un ArrayList di oggetti Libro definito in questo modo:

[...]
private List<Libro> biblioteca;
 
public List<Libro> getBiblioteca() {
	return biblioteca;
}
 
public void setBiblioteca(List<Libro> biblioteca) {
	this.biblioteca = biblioteca;
}
[...]

dove la classe Libro è un semplice oggetto POJO definito in questo modo:

public class Libro {
 
	private String isbn;
 
	private String autore;
 
	private String titolo;	
 
	// Elenco dei get/set
	[...]
}

La classe Biblioteca implementa l’Action, che in questo esempio compila al volo il report e crea il .jasper:

public Biblioteca() {
 
	Libro libro1 = new Libro();
	libro1.setIsbn("8871923030");
	libro1.setAutore("Bruce Eckel");
	libro1.setTitolo("Thinking in Java: 1");
 
	Libro libro2 = new Libro();
	libro2.setIsbn("8838667667");
	libro2.setAutore("Java. La guida completa");
	libro2.setTitolo("Herbert Schildt");
 
	biblioteca = new ArrayList<>();
	biblioteca.add(libro1);
	biblioteca.add(libro2);
 
}
 
public String execute() throws Exception {
 
	return SUCCESS;
}
 
public String stampa() {
 
	/*
	 * Tutto questo statement non serve se il report è già compilato
	 * */
	try {
 
		String contextPath = request.getSession().getServletContext().getRealPath(File.separator);
		String downloadPath = contextPath + "WEB-INF" + File.separator + "report" + File.separator;        	
 
		JasperCompileManager.compileReportToFile(downloadPath + "biblioteca.jrxml", downloadPath + "biblioteca.jasper");
 
	} catch (Exception e) {
 
		addActionError(e.getMessage());
		return ERROR;
	}
 
	return SUCCESS;    	
}

Non importo per intero il codice del report, solo un piccolo eatratto con la definizione dei campi e del dettaglio:

<jasperReport name="biblioteca">
 
  <field name="isbn" class="java.lang.String"/>
  <field name="titolo" class="java.lang.String"/>
  <field name="autore" class="java.lang.String"/>
 
  [...]
 
  <detail>
    <band height="20">
      <textField>
        <reportElement x="50" y="0" width="150" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{isbn}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="200" y="0" width="150" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{titolo}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="350" y="0" width="150" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{autore}]]></textFieldExpression>
      </textField>
    </band>
  </detail>
 
  [...]

Questa è l’homepage dell’esempio:

Struts2 - integrazione con JasperReports 1
Struts2 – integrazione con JasperReports 1

e questo è il risultato dell’action /stampa

Struts2 - integrazione con JasperReports 2
Struts2 – integrazione con JasperReports 2

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>