segunda-feira, 4 de agosto de 2014

Relatórios com IReport usando JRBeanCollectionDataSource


Eae galera!Esse é meu primeiro post, minha intenção e mostrar uma das muitas formas de gerar relatórios no iReport Designer usando JRBeanCollectionDataSource mas antes pra quem não sabe segue uma breve descrição.


O que é JasperReports ?

JasperReport é uma biblioteca escrita em java de código aberto e gratuito,conhecido pelo mundo todo por sua facilidade de gerar documentos com dados provenientes de qualquer tipo de fonte e serem visualizados ou exportados nos formatos HTML, PDF, Excel, OpenOffice e Word. 

O que é iReport Design ?

É uma ferramenta também escrita em java e de código aberto onde criamos o layout do nosso relatório usando por exemplo gráficos,imagens e sub-relatório(s). É possível acessar dados com JDBC, TableModel, Java Beans(na qual sera usado como exemplos), XML, Hibernate, CSV ou qualquer outra fonte personalizada e exportar nos formatos PDF, RTF, XML, XLS, CSV, HTML, XHTML, textos, DOCX ou OpenOffice.



Para o exemplo precisamos ter configurado em nosso seguinte:



  • iReport Designer 5.6.0 ( que pode ser baixado clicando aqui ).
  • A biblioteca jasperreports-5.6.0 ( que pode ser baixado clicando aqui ).
  • IDE Eclipse ( que pode ser baixado clicando aqui ).



Crie um projeto java no eclipse e na raiz uma pasta com o nome lib
(mostras print com projeto e pasta criado)

Descompacte a pasta jasperreports-5.6.0, copie os jars listado abaixo e cole dentro da pasta lib do eclipse


...\jasperreports-5.6.0\lib\commons-beanutils-1.8.0.jar
...\jasperreports-5.6.0\lib\commons-collections-3.2.1.jar
...\jasperreports-5.6.0\lib\commons-digester-2.1.jar
...\jasperreports-5.6.0\lib\commons-logging-1.1.1.jar
...\jasperreports-5.6.0\lib\groovy-all-2.0.1.jar
...\jasperreports-5.6.0\lib\iText-2.1.7.jar
...\jasperreports-5.6.0\dist\jasperreports-5.6.0.jar
...\jasperreports-5.6.0\dist\jasperreports-fonts-5.6.0.jar


Feito isso selecione todas os jars, clique com segundo botão e clique em add build path.






Para o nosso exemplo vamos ter um Aluno com muitas Disciplinas


Classe Aluno:



package com.example.model;
import java.io.Serializable;
import java.util.List;
public class Student implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7944514266528757334L;
private Integer id;
private String firstName;
private String lastName;
private String semester;
private List<Discipline> disciplines;
public Student(Integer id, String firstName, String lastName, String semester, List<Discipline> disciplines) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.semester = semester;
this.disciplines = disciplines;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getSemester() {
return semester;
}
public void setSemester(String semester) {
this.semester = semester;
}
public List<Discipline> getDisciplines() {
return disciplines;
}
public void setDisciplines(List<Discipline> disciplinas) {
this.disciplines = disciplinas;
}
}


Classe Disciplina:


package com.example.model;

import java.io.Serializable;

public class Discipline implements Serializable {

/**

*/
private static final long serialVersionUID = -8380986441750684280L;

private Integer id;
private String hours;
private String name;

public Discipline(Integer id, String hours, String name) {
this.id = id;
this.hours = hours;
this.name = name;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getHours() {
return hours;
}

public void setHours(String hours) {
this.hours = hours;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


}

Exporte um jar do pacote com.example.model

  • Clique com segundo botão no pacote com.example.model e clique em Export...
  • Escolha a opção JAR file, clique em Next e Finish


Descompacte o ireport e execute o arquivo ireport.exe


...\iReport-5.6.0\iReport-5.6.0\bin\ireport.exe

Vamos criar um documento que contem um aluno com muitas disciplinas

  • Vá em File > New...
  • Na opção Report escolha Blank Letter e clique em Open this Templete
  • Coloque o nome do relatório como "report" depois clique em Next e Finish

 Adicione o jar que criamos no iReport


  • Na barra de menu clique em Tools e escolha Options
  • Na aba classpath clique em Add JAR e escolha o jar que criamos
  • Marque a opção Reloadable e (caso necessário gerar um novo jar não sera necessário fechar e abrir a aplicação) clique em Ok.

Crie um Data source JavaBean

  • Em Report Inspector clique com segundo no projeto e em seguida Edit Query 

  • Clique na aba JavaBean Datasource 
  • No campo Class name insira o nome do pacote junto com o nome da classe: com.example.model.Student e clique em Read attributes
  • Marque todos os atributos exceto class e clique em Add selected field(s) e em seguida Ok


  • Na janela Report Inspector expanda Fields e vera os atributos da classe Aluno como abaixo:

Com isso não vamos precisar criar todos os fields com seus tipos na mão  


Na janela Palette clique, segure e arraste o botão Subreport para Band Detail


  • Marque a opção Create a new Report e depois clique em Next
  • Escolha o layout Blank Letter e clique em Next
  • Vamos usar um Data source vazio, clique em Next 3 vezes
  • De um nome ao sub relatório e clique em Next
  • Marque a opção Use an empty data source e clique em Finish
  • Nas propriedades do subreport adicione em Data Source Expression o codigo:
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{disciplines}) passando uma lista de Discipline.

  • Agora no sub report crie um Data Source Java Bean como fizemos para o Student  passando: com.example.model.Discipline
  • Remova todas as bandas exceto detail
  • Arraste todos os atributos para banda detail

Compile o report principal e o subreport e adicione os arquivos jasper no pacote: com.example.report





Vamos criar uma classe main responsável por gerar o relatório, adicione a classe abaixo dentro do pacote: com.example.report


public class ReportGenerator {

public static void main(String[] args) {

try {

Collection<Student> Students = new LinkedList<Student>();

for(int x=1; x<=5; x++ ){

Student student = new Student();

List<Discipline> lsDiscipline = new ArrayList<Discipline>();

student.setId(x);
student.setFirstName("Student "+x);
student.setLastName("Student 0"+x);
student.setSemester(x+"º semestre");

for (int y = 1; y <= 5; y++) {
Discipline discipline = new Discipline();
discipline.setId(y);
discipline.setName("Discipline "+y);
discipline.setHours(Integer.toString((x+y))+" hs");
lsDiscipline.add(discipline);
}

student.setDisciplines(lsDiscipline);
Students.add(student);
}

JasperPrint p = JasperFillManager.fillReport(ReportGenerator.class.getResourceAsStream("report.jasper"),new HashMap<String, Object>(), new JRBeanCollectionDataSource(Students));
JasperExportManager.exportReportToPdfStream(p,(OutputStream) new FileOutputStream("C:\\Users\\renato.rudolf\\Desktop\\report.pdf"));
System.out.println("Report generated!");

} catch (JRException e) {
e.printStackTrace();
System.out.println("Error in ireport");
} catch (FileNotFoundException e) {
System.out.println("File not found");
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
System.out.println("General error");
}
}
}

Ao final será gerado o seguinte relatório: