Pesquisar neste blog

Mostrando postagens com marcador subreport. Mostrar todas as postagens
Mostrando postagens com marcador subreport. Mostrar todas as postagens

quinta-feira, 19 de julho de 2012

iReport 4.5.1 - Somando valor de uma váriavel do subReport no relatório principal

Quando for necessário somar os valores ou efeturar algum outro tipo de cálculo com valores de um supreport é possível usar a propriedade return values do componente subreport. Para isso, crie no subreport uma váriavel para armazenar o valor e faça o mesmo do relatório principal. Veja o exemplo abaixo:




Váriavel do relatório Principal:
Nome: TotalGeral
Variable Class: java.lang.Double
Calculation: System
Reset Type: report;


Váriavel do relatório Principal:
Nome: Total
Variable Class: java.lang.Double
Calculation: Nothing
Reset Type: report; 
Variable Expression: O campo ou a referência que conterá os valores a serem calculados.

Feito isso, no relatório principal deve ser selecionado o componente subreport e aberta a propriedade return values. Nesta tela deverá ser feito o vinculo entre a varial do subreport e do relatório principal. Atenção! O nome da váriavel do subreport não aparecerá de deverá ser digitada. Veja exemplo na tela abaixo:




Configurando retun values no subreport
Agora basta adicionar a váriavel TOTALGERAL no relatório e emitir para testar.



Claudir Pereira dos Santos

Matelândia, 19 de julho e 2012.




iReport 4.5.1 - Efetuando consulta em multiplos bancos de dados com connection expression

INTRODUÇÃO


Não é muito comum, mas as vezes pode ser necessário emitir um relatório com base em informações em duas ou mais bases de dados. Para resolver esse problema pode ser usado um subreport no iReport. Nesse exemplo será usado a base de dados do sistema Sisaih01 do Datasus que usa o Firebird como SGDB. Esse sistema possui três bases de dados, sendo a sisaih00.gdb, sisaih01.gdb e a sisaih99.gdb. A sisaih00.gdb armasena tabelas que podem ser alimentadas e alteradas pelo Datasus mensalmente como por exemplo de procedimentos, cid10, clinicas entre outras. A sisaih01.gdb armazena informações inseridas pelos hospitais como dados do paciente, procedimentos realizados, internações entre outros. A sisaih99.gdb armazena tabelas que são alteradas raramente como de cep, nacionalidade entre outros.




O PROBLEMA


O problema que levou a pesquisa sobre como usar o iReport para emitir um relatório usando multiplas bases foi a necessidade de um relatório com nome de pacientes, código e descrição do procedimento, valor do procedimento, número da Autorização de Internação Hospitalar (AIH), mês de apresentação e de competência da internação entre outros dados. Como a tabela de procedimentos que contem o valor e a descrição não fica na mesma base onde são armazenados os dados da internação do paciente, foi necessário buscar a solução.


CRIANDO CONSULTA DO BANCO SISAIH01.GDB PARA RELATÓRIO PRINCIPAL DO IREPORT


Antes de criar a consulta sql, lembre-se de adicionar o jar do drive jaybird no classpath do iReport e configurar a conexão. Abaixo segue uma cópia da tela de configuração como exemplo:


Configurando conexão


Deverá ser criada uma configuração para cada base que será usada para que seja possível usar em tempo de desenvolvimento. Para gerar o relatório principal será usado o comando sql abaixo. Clique com o botão direito do mouse sobre o relatório na janela do Report Inspector e escolha a opção Edit Query  e cole a consulta abaixo em Report Query:


select serv.sp_apres,serv.sp_cmpt_uti_acomp,serv.sp_num_aih,
serv.sp_dt_int,aih.aih_pac_nome,serv.sp_ato_prof,vlr.va_linha,aih.aih_car_int
from tb_serv_prof serv
inner join  tb_valor_aih vlr on serv.sp_num_aih=vlr.va_num_aih
inner join tb_aih aih on vlr.va_num_aih= aih.aih_num_aih

where
(
/*Procedimentos componente II - competência 07/2012*/
(serv.sp_ato_prof in (0404010016,0404010024,0404010032,0404010105,0404010210,0404010229,
                      0404010237,0404010350,0405020015,0405020023,0405030134,0405030142,
                      0406020566,0406020574,0408040076,0408040084,0408040092,0408050055,
                      0408050063,0408050160,0408050888,0408050896,0409010235,0409010561,
                      0409030040) and serv.sp_cmpt_uti_acomp=201207
)
)
and vlr.va_linha=1 and vlr.va_tipo_valor=1 and serv.sp_linha=1
and aih.aih_car_int=01 and (serv.sp_apres=$P{P_APRES})
order by serv.sp_apres





Com isso já é possível montar o relatório principal com a estrutura da figura abaixo:

Relatório Principal


Após desenhar o relatório principal, salve o mesmo como o nome Eletivas.
 



CRIANDO CONSULTA DO BANCO SISAIH00.GDB PARA SUBREPORT DO IREPORT


Agora que já foi criado o relatório principal, é hora de criar o subreport. Lembre-se de mudar na caixa de seleção a conexão para o banco sisaih00.gdb. Feito isso, crie um novo relatório com o nome Eletivas_subreport, adicione dois parâmetros no sub-relatório (P_COMP e P_CODPROC) e cole a seguinte consulta:


select pr.proc_cod,pr.proc_descr,pr.proc_vl_sh,pr.proc_vl_sp,pr.proc_cmpt_ini,pr.proc_cmpt_fim
from tb_proc pr where pr.proc_cod=$P{P_CODPROC} and pr.proc_cmpt_ini=$P{P_COMP}



Feito isso basta estruturar o subreport com os campos conforme imagem abaixo e adicionar uma váriavel com expressão para receber o total dos campos do serviço médico e hospitalar:


Componentes subreport e expressão da váriavel total

Dica: Usa a propriedade pattern  dos campos para formatar como moeda.

Neste exemplo o subreport deve ficar o mais estreito possível pois ele vai ficar abaixo das linhas do relatório principal conforme pode ser visto na figura abaixo:


Relatório principal com subreport
Na figura acima já foi adicionado um componente subreport da palheta do iReport no relatório principal. Esse componente tem por função fazer a ligação entre os dois relatórios. Nesse exemplo o componente foi colocado dentro da banda detalhes, logo abaixo das informações que serão exibidas pelo relatório principal, dessa forma, a cada linha do principal, logo abaixo será exibido as linhas do sub-relatório.




ADICIONANDO O SUBREPORT NO RELATÓRIO PRINCIPAL DO IREPORT


Ao adicionar o componente subreport o iReport iniciará um assistente para auxiliar nas configurações do componente. Na primeira tela marque para usar um relatório existente e selecione o Eletivas_subreport conforme figura abaixo:


Adicionando relatório do componente subreport
Na tela seguinte marque para não usar conexão pois iremos configurar manualmente:

Configurando conexão

Na tela seguinte é feita a vinculação dos dois parâmetros (P_COMP e P_CODPROC) criados no subreport com valores do relatório principal. Esses dois parâmetros foram usados na consulta sql, lembra? Dessa forma, vamos especificar quais valores devem ser buscados no outro banco a cada nova linha gerada no relatório principal. Se isso não fosse aplicado, para cada linha da tabela mestre seria exibido todos os registros da tabela detalhe. Nesse caso o critério de busca é o procedimento e a competência do mesmo, sendo que dessa forma sempre será retornado apenas um registro. A configuração ficará conforme tela abaixo:

Vinculando parâmetros do subreport com fields no principal
Como pode ser visto na figura acima, foi vinculado os parâmetros do detalhe aos fields do principal. Dessa forma será usado o valor desses fields na busca da tabela detalhe. Na tela seguinte defina que o caminho do subreport será armazenado em um parâmetro, conforme abaixo:

Configurando armazenamento do diretório do subreport

Feito isso o subreport está quase pronto. Agora vamos definir como será feita a conexão dos dados. Selecione o componente subreport e na janela de propriedades altere connection type para Use a connection Expression. Com isso, logo abaixo essa propriedade será ativada, clique no botão ao lado dela e adicione o seguinte valor:


java.sql.DriverManager.getConnection("jdbc:firebirdsql:192.168.0.1/3050:c:/Arquivos de Programas/Datasus/sisaih01/sisaih00.gdb","SYSDBA","masterkey")

O endereço obviamente deve ser o de seu banco caso vá fazer um teste. Feito isso, o relatório principal já pode ser visualizado, dessa forma ele irá pedir a apresentação. Se ao executar o relatório você receber um erro conforme abaixo não se assuste:

...
Caused by: java.sql.SQLException: No suitable driver found for jdbc:firebirdsql:192...
...

Isso pode ser corrigido mudando a propriedade language no relatório principal de Grovy para Java como pode ser visto na figura abaixo. Para isso, basta clicar com o botão direito sobre o relatório na janela Report Inspector e escolher a opção Propriedades. Feito isso, o relatório deve funcionar.

Alterando propriedade language do relatório de grovy para Java


Seria isso, caso tenha alguma sugestão ou dúvida é só postar nos comentários.


Claudir Pereira dos Santos


Matelândia/PR, 19 de julho de 2012.







terça-feira, 14 de junho de 2011

Usando iReport 4.0.2 para gerar um relatório jasper com fonte de dados JavaBeans set datasource

O iReport é uma ferramenta muito conhecida no mundo Java para desenvolvimento de relatórios no formato jasper. Dessa forma, não serão abordados neste pequeno artigo minúcias do mesmo. Você pode encontrar o iReport em http://jasperforge.org/projects/ireport. Um dos fatores que cabe ressaltar aqui é a diferença na interface e mecanismos do programa entre uma versão e outra. Então fique atento, para testar os procedimentos descritos aqui recomenda-se a versão 4.0.2 do iReport. Neste artigo será usado a opção de acesso aos dados por meio de  JabaBeans set datasource, que permite popular o relatório com informações, por exemplo, de um list.






CONFIGURANDO ACESSO AOS DADOS

Como foi dito, será usado como fonte de dados a opção de  JabaBeans set datasource. Para que seja possível a criação do relatório é necessário gerar um jar da aplicação onde será inserido os relatórios jasper. Caso esteja usando o Eclipse, basta clicar sobre o projeto com o botão direito e escolher a opção export e seguir os procedimentos indicados.
Após gerado o jar da aplicação, é necessário agora adicionar o mesmo ao classpath do iReport. Para isso acesse o menu "Ferramentas\Opções". Veja um exemplo na imagem abaixo onde foi adicionado o arquivo "E:\iReports\Agenda.jar".




Agora que foi adicionado o jar com os arquivos beans, nesse caso entities, já é possível usar os mesmos para criar o relatório. Na etapa seguinte vai ser criado um relatório master que se refere a entity Pessoa que está dentro do pacote br.claupers.agenda.entities. Em seguida será criado o sub-relatório para a entity Fone. Segue abaixo o código fonte de ambas as entities:


Pessoa:

package br.claupers.agenda.entities;

@Entity
public class Pessoa extends AbstractModelObject implements Serializable {
    private static final long serialVersionUID = 1L;    

    @Id
    @GeneratedValue(strategy=SEQUENCE, generator = "COD_PESSOA")
    @Column(name="COD_PESSOA")
    
    private int codPessoa;

    @Column(name="BAIRRO_PESSOA")
    private String bairroPessoa;

    @Column(name="COMPLEMENTO_PESSOA")
    private String complementoPessoa;

    @Column(name="ENDERECO_PESSOA")
    private String enderecoPessoa;

    @Column(name="NOME_PESSOA")
    private String nomePessoa;

    @Column(name="OBS_PESSOA")
    private String obsPessoa;

    //bi-directional many-to-one association to Fone
    @OneToMany(mappedBy="pessoa")
    private List<Fone> fones;

    //bi-directional many-to-one association to Cidade
    @ManyToOne
    @JoinColumn(name="COD_CIDADE")
    private Cidade cidade;
 
    public Pessoa() {
    }
    //getters e setters omitidos
           
}
Fone:

package br.claupers.agenda.entities;

@Entity
public class Fone implements Serializable {
 private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(strategy=SEQUENCE, generator = "COD_FONE")
 @Column(name="COD_FONE")
 private int codFone;

 @Column(name="NUM_FONE")
 private String numFone;

 @Column(name="TIPO_FONE")
 private String tipoFone;

 //bi-directional many-to-one association to Pessoa
    @ManyToOne
 @JoinColumn(name="COD_PESSOA")
 private Pessoa pessoa;

    public Fone() {
    }
   //getters e setters omitidos 
}







CRIANDO RELATÓRIOS E CARREGANDO OS DADOS DOS JAVABEANS

Agora que os beans já foram adicionados ao classpath do iReport, é hora de criar os relatórios. Para isso acesse o menu "Arquivo\new...". Na tela que irá abrir selecione o template Blank A4 e clique em "Open this template". Na tela seguinte, em Report name digite Pessoas, escolha um local para salvar e clique Próximo. Na tela seguinte clique em Finalizar. Com esse procedimento foi criado um relatório em branco. Agora é hora de adicionar a fonte de dados. Para isso clique no botão Report Query, ao lado de Preview. Com isso será aberto a tela para editar a query. Clique na aba JavaBean Datasource, em Class name digite o nome da classe juntamente com o caminho dos pacotes. Neste exemplo o valor é br.claupers.agenda.entities.Pessoa. Em seguida, clique no botão Read attributes. Se tudo foi feito corretamente até aqui será carregado todos os atributos da entidade informada. Agora deve ser selecionado todos os atributos e em seguida clicado em Add selected field(s) e depois Ok. Feito isso os campos estarão disponíveis para criação do relatório. Veja exemplo abaixo do procedimento que foi descrito:



Feito isso, o relatório já pode ser desenhado. Veja abaixo uma sugestão de Layout para o relatório:



Na imagem acima pode ser visto a esquerda todos os campos disponíveis. No relatório foi usado apenas o field nomePessoa que irá trazer apenas o nome do contato e logo abaixo todos os telefones do mesmo. Para isso será usado o componente Subreport que será tratado na seção seguinte. Também foi usado um componente que já vem no iReport para informar o número da página e o total de páginas. Sobre isso não será detalhado pois o uso deste componente não é complexo.

ADICIONANDO UM SUBREPORT NO iREPORT

A opção de subreport do iReport permite exibir no relatório os relacionamentos master/detail existente no sistema. Os procedimentos para isso são:
1) Criar um relatório com os campos de entity Fone e salvar na mesma pasta do relatório mestre. Nesse exemplo o relatório detalhe terá o nome pessoas_fones.
2)Adicionar um componente Subreport no relatório principal. Nesse exemplo o relatório principal é o Pessoas criado anteriormente.
3) Informar no componente Subreport a fonte de dados.

A etapa 1, já foi explicada para a entity Pessoa, basta fazer o mesmo com a entity Fone. O que deve ser observado é a necessidade de salvar o relatório detalhe na mesma pasta do mestre.
A etapa 2 consiste em arrastar o componente da palheta para o relatório mestre. Ao fazer isso ele irá solicitar que se crie um relatório ou informe o que será usado. Nesse exemplo o relatório é o "E:\iReports\pessoas_fones.jrxml". Selecione o relatório e clique em Próximo. Na tela seguinte marque a opção Use the same connection used to fill the master report e clique em Próximo duas vezes e na tela final marque a opção Store the directory name in a parameter. Essa é uma configuração importante pois caso seja mantido o caminho estático, quando o relatório for adicionado ao projeto não irá funcionar pois irá buscar o arquivo no local onde o relatório foi criado. Marque a opção indicada e clique em Finalizar.
Feito isso, agora é hora de informar de onde o subreport irá carregar os dados. Como pode ser observado no código da entity Pessoa loca acima, existe um atributo do tipo List que carrega objetos do tipo fone. Essa será a fonte da dados do subreport, veja:

//bi-directional many-to-one association to Fone
    @OneToMany(mappedBy="pessoa")
    private List<Fone> fones;

A questão é, como fazer isso? Não se assuste, o procedimento é bem simples, para isso basta clicar sobre o componente subreport que está no relatório Pessoas e nas propriedades do componente localizar Data Source Expression. Clique no botão ao lado e insira os seguintes parametros:

new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{fones})

Clique em Ok para salvar. Com isso o relatório será capaz de carregar as informações no subreport.
Agora falta apenas configurar o caminho do arquivo jasper do subreport no relatório principal, pois quando o relatório for carregado pelo programa java ele deve saber onde se encontra o arquivo do relatório detalhe. Para isso basta editar o Parameter  SUBREPORT_DIR e colocar o caminho do pacote onde serão armazenados os relatórios, neste exemplo "br/claupers/agenda/report/". Muita atenção para o tipo da barra, pois caso contrário não irá funcionar. Veja imagem abaixo para maiores detalhes sobre a configuração desse parâmetro:


Se todas as etapas acima foram feitas corretamente, o relatório pode ser compilado e movido para o projeto java. Não copie, mova os arquivos jasper pois se a referência ao relatório estiver buscando onde foi compilado vai gerar um erro e permitir a correção, caso contrário o erro só ocorrerá para o usuário final. Na seção seguinte será demonstrado como usar o relatório no projeto.


USANDO O RELATÓRIO JASPER GERADO NO iREPORT EM UM PROJETO JAVA SWING

Uma vez que os relatórios foram gerados e os arquivos jasper movidos para o pacote "br.claupers.agenda.report", para usa-los basta fazer o seguinte:


btnImprimir.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                List <Pessoa> listaDePessoas = new ArrayList<Pessoa>();
                listaDePessoas.addAll(controlaListaPessoas.getListaDePessoas());
                JRDataSource jrds = new JRBeanCollectionDataSource(listaDePessoas);
                URL jasper = this.getClass().getResource("/br/claupers/agenda/report/Pessoas.jasper");  
                try {
                    InputStream fs;  
                      fs = (InputStream) jasper.getContent();
                      JasperPrint impressao = JasperFillManager.fillReport(fs,null,jrds);
                      JasperViewer viewer = new JasperViewer(impressao, false);                    
                      viewer.setVisible(true);
                   }
                   catch(Exception ex) {
                       ex.printStackTrace();
                   }
            }
        });

Seria isso. Sugestões e dúvidas, favor postar um comentário.


Cordialmente;


Claudir Pereira dos Santos

Matelândia, 14 de junho de 2011.