En este post vamos a ver como se pasan parámetros desde java al reporte sin necesidad de una conexión a una BBDD, es decir, podemos pasar los parámetros que queramos.
Vamos a comenzar creando un proyecto nuevo (File/New Project) y una clase en java que utilizaremos para instanciar objetos ( botón derecho en el paquete y New/java Class) y así pasar los datos al datasource. Para usar de ejemplo, hemos creado la clase Asistentes.
public class Asistentes {
private Integer id;
private String nombre;
private String apellidos;
private String dni;
public Asistentes(){
}
public Asistentes(int id, String nombre, String apellidos, String dni) {
this.id = id;
this.nombre = nombre;
this.apellidos = apellidos;
this.dni = dni;
}
public int getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getApellidos() {
return apellidos;
}
public void setApellidos(String apellidos) {
this.apellidos = apellidos;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
private Integer id;
private String nombre;
private String apellidos;
private String dni;
public Asistentes(){
}
public Asistentes(int id, String nombre, String apellidos, String dni) {
this.id = id;
this.nombre = nombre;
this.apellidos = apellidos;
this.dni = dni;
}
public int getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getApellidos() {
return apellidos;
}
public void setApellidos(String apellidos) {
this.apellidos = apellidos;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
Esta clase tiene cuatro atributos, constructor por defecto y constructor parametrizado. También debemos incluir los getters and setters ya que los atributos son privados y necesitaremos asignar esos valores.
A continuación vamos a crear el reporte. Para ello botón derecho en el paquete y nuevo Empty report.
Para editar el reporte vamos a utilizar el programa de iReport, que previamente lo tenemos que tener instalado ( a parte del plugin de iReport para netbeans). Os lo podéis descargar del siguiente enlace:
En nuestro reporte vamos a asignar etiquetas para las columnas y para el nombre del reporte. Esto se hace con Static Text (Paleta que está a la derecha).
Una vez creados todos, pinchamos y los arrastramos al reporte. Así quedaría el nuestro:
Muy bien, ahora hay que crear la clase para pasar estos datos. Esta clase tiene que implementar la clase JRDataSource, y tiene dos métodos que son obligatorios sobreescribir, el método next() y getFieldValue(JRField jrf). En el método next incrementará el contador y JasperReport sabrá cuantos Asistentes van a existir. El método getFieldValue asignará los valores a los Fields correspondientes.
A parte en esta clase vamos a crear una variable que será una lista de Asistentes y también un método para ir agregando cada asistente a la lista. La clase quedaría así:
public class AsistentesDataSource implements JRDataSource{
private List<Asistentes> listaAsistentes = new ArrayList<Asistentes>();
private int indiceParticipanteActual = -1;
@Override
public boolean next() throws JRException {
return ++indiceParticipanteActual < listaAsistentes.size();
}
public void addAsistente(Asistentes Asistente){
this.listaAsistentes.add(Asistente);
}
@Override
public Object getFieldValue(JRField jrf) throws JRException {
Object valor = null;
if ("id".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getId();
}
else if ("nombre".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getNombre();
}
else if ("apellidos".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getApellidos();
}
else if ("dni".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getDni();
}
return valor;
}
}
private List<Asistentes> listaAsistentes = new ArrayList<Asistentes>();
private int indiceParticipanteActual = -1;
@Override
public boolean next() throws JRException {
return ++indiceParticipanteActual < listaAsistentes.size();
}
public void addAsistente(Asistentes Asistente){
this.listaAsistentes.add(Asistente);
}
@Override
public Object getFieldValue(JRField jrf) throws JRException {
Object valor = null;
if ("id".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getId();
}
else if ("nombre".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getNombre();
}
else if ("apellidos".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getApellidos();
}
else if ("dni".equals(jrf.getName())){
valor = listaAsistentes.get(indiceParticipanteActual).getDni();
}
return valor;
}
}
En el main() tenemos que inicializar jasperreport y la clase Asistentes. También crear los objetos y pasarlos al datasource además de crear el reporte. El método main() quedaría de la siguiente forma:
public static void main(String[] args) {
// TODO code application logic here
InputStream inputStream = null;
JasperPrint jasperPrint= null;
AsistentesDataSource datasource = new AsistentesDataSource();
for(int i = 0; i<=5; i++){
Asistentes asist;
asist = new Asistentes(i, "AsistenteNombre de "+i,"AsistenteApellidos de "+i, "Asistente dni de "+i);
datasource.addAsistente(asist);
}
try {
inputStream = new FileInputStream ("src/reportes/reporte01.jrxml");
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(null,"Error al leer el fichero de carga jasper report "+ex.getMessage());
}
try{
JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
jasperPrint = JasperFillManager.fillReport(jasperReport, null, datasource);
JasperExportManager.exportReportToPdfFile(jasperPrint, "src/reportes/reporte01.pdf");
}catch (JRException e){
JOptionPane.showMessageDialog(null,"Error al cargar fichero jrml jasper report "+e.getMessage());
}
}
// TODO code application logic here
InputStream inputStream = null;
JasperPrint jasperPrint= null;
AsistentesDataSource datasource = new AsistentesDataSource();
for(int i = 0; i<=5; i++){
Asistentes asist;
asist = new Asistentes(i, "AsistenteNombre de "+i,"AsistenteApellidos de "+i, "Asistente dni de "+i);
datasource.addAsistente(asist);
}
try {
inputStream = new FileInputStream ("src/reportes/reporte01.jrxml");
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(null,"Error al leer el fichero de carga jasper report "+ex.getMessage());
}
try{
JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
jasperPrint = JasperFillManager.fillReport(jasperReport, null, datasource);
JasperExportManager.exportReportToPdfFile(jasperPrint, "src/reportes/reporte01.pdf");
}catch (JRException e){
JOptionPane.showMessageDialog(null,"Error al cargar fichero jrml jasper report "+e.getMessage());
}
}
Ejecutamos el proyecto ya tenemos nuestro reporte:
Hay problemas con la versión de iReport y Windows. Al ejecutar el proyecto nos puede aparecer dos tipos de errores.
- Error uuid: no está permitido que el atributo uuid aparezca en el elemento jasperreport
- Error cast: can not cast from Integer to String.
Para el error del uuid simplemente en la vista del xml del reporte hay que borrar todos los campos donde venga el uuid. Para el error del cast, hay que añadir en los <textFieldExpressions> la clase correspondiente (String, Integer,Float,...)
Podéis descargaros el proyecto en GitHub -> Reportes GitHub