Para esta não ser uma postagem muito extensa, irei utilizar o mesmo projeto e o mesmo relatório criado na postagem: agrupando de dados com JasperReports. Para completar esse projeto, logo abaixo do agrupamento eu vou listar os dados dos cliente, ou seja, terei um relatório de clientes embutido no relatório de pedidos (claro que pode ser feito outras coisas, este é apenas um exemplo)
Começando...
Então lá no projeto Pedidos (link acima), dentro do pacote pedidos.dao, vamos criar uma classe Java como o nome de ClienteDAO, seguindo a mesma linha da classe PedidoDAO, temos:
public class ClienteDAO { EntityManagerFactory emf = Persistence.createEntityManagerFactory("PedidosPU"); EntityManager em = emf.createEntityManager(); public List<Cliente> listarClientes() { List<Cliente> clientes = null; try { Query query = em.createQuery("Select c from Cliente c order by c.nome"); clientes = query.getResultList(); } catch (Exception e) { e.printStackTrace(); } finally { em.close(); } return clientes; } }
No iReport, vamos editar o relatório pedidos.jrxml, criando também no link da postagem acima.
Precisamos criar um parâmetro que será enviado pelo projeto, para isso no Report Inspector, clique com o botão direito em Parameters, e em Adicionar Parameter:
Selecione o parameter1 e vá nas propriedades para configurá-lo, altere o nome para listaClientes e o Parameter class para java.util.List, pois passaremos por parâmetro uma lista de clientes:
Na paleta procure pelo elemento Subreport, arraste-o para a band Summary, a partir de agora siga as imagens abaixo:
Clique em próximo novamente, como estamos usando JavaBean datasource, e não utilizamos datasource, configure como na imagem:
Mais uma vez:
Na janela abaixo informe o nome do Subreport, nesse caso será chamado de pedidos_subreport:
No passo 7, habilite a opção "Use a JRDatasource expression", e clique no botão do lado da caixa de texto, a seguinte janela aparecerá, nela nós convertemos a listaClientes em um JRBeanCollectionDataSource :
E aqui basta finalizar...
Como será uma lista de clientes, precisamos pegar da classe Cliente os seguintes fields - codigo, nome e limiteCredito... para isso em Report Query, na aba JavaBean Datasource:
Feito isso...
Ah, lembre-se de nas propriedades do relatório alterar a linguagem para Java, já que estamos usando JavaBean datasource:Depois disto basta compilar nosso subreport, para poder gerar o pedidos_subreport.jasper
Voltamos ao pedidos.jrxml, e vamos fazer umas ultimas configurações, temos este resultado:
Precisamos criar mais um parâmetro que será uma String com o caminho de onde encontrar o pedidos_subreport.jasper, repita o mesmo passo que foi feito para criar o listaClientes, mas dessa vez use as seguintes propriedades:
Agora precisamos setá-lo no lugar certo... para isso: veja que na band Summary tem um elemento que representa o subreport, clique nele e vá nas propriedades, procure por Subreport Expression, e configure-o assim:
Feito todos esses passos, pode compilar novamente o relatório principal (pedidos)...
Caso não ocorra nenhum erro, voltamos ao projeto Pedidos no NetBeans.
No projeto..
No pacote pedidos,controle.relatorios, substitua o pedidos,jasper pelo que foi compilado agora, e adicione o pedidos_subreport.jasper, ficando assim:
Para finalizar de vez, precisamos fazer algumas alterações no método gerarRelatorio() da classe PedidoControle.java:
public void gerarRelatorio() { String arquivo = "src/pedidos/controle/relatorios/pedidos.jasper"; pedidoDAO = new PedidoDAO(); clienteDAO = new ClienteDAO(); Map parametros = new HashMap(); parametros.put("localizacaoPedidosSubreport", "src/pedidos/controle/relatorios/pedidos_subreport.jasper"); parametros.put("listaClientes", clienteDAO.listarClientes()); JRDataSource jrds = new JRBeanCollectionDataSource(pedidoDAO.listarPedidos()); gerarRelatorioDesktop(jrds, parametros, arquivo); }
No começo da classe lembre-se de adicionar a declaração do ClienteDAO, assim como foi feito para PedidoDAO...
Vamos ver o que foi alterado no método...
Primeiro, depois de declarado o atributo clienteDAO no inicio da classe, na linha 5 estamos inicializando-o.
Da linha 7 a 9, criamos um Map, com os parâmetros que criamos lá no iReport... e por fim... na linha 12, passávamos o parâmetro como null, agora este é substituído e passamos o Map parametros por parâmetro.
Assim podemos executar nosso projeto e ver o seguinte resultado:
Créditos da postagem: Altieres de Matos, pois ele salvou minha aula sobre Subrepot hehe (pois é, tive problemas ao usar Subreport com JavaBean datasource)
Andii, primeiramente parabens pelos tutoriais. Segue a risca seu tutorial sobre subreports, mas não consigo gerar o relatorio com o subrelatorio. Primeiro da o seguinte erro: new net.nf.jasperreports.engine.data.JRBeanCollectionDataSource cannot be resolved to a type. Então mudei o nf por sf e o erro sumiu.
ResponderExcluirPorem quando tento compilar novamente o erro a seguir é dado:
Compilation exceptions: com.jaspersoft.ireport.designer.compiler.ErrorsCollector@1f9fb0c net.sf.jasperreports.engine.JRException: An error has accurred compiling the subreport: C:\Users\PimentaAgro\Downloads\iReport-4.0.1\ireport\fonts. Não sei onde está o erro.
Conseguiu resolver ?? estou com o mesmo problema
Excluirclica nas propriedades do subreport vai em subreport Expression e concatena o seu arquivo jasper
Excluir$P{caminhoSubReport1} + "reportPay_subreport1.jasper"
O meu está dando o mesmo erro, Matheus Virtudes.
ResponderExcluirEle diz ainda: "Access Denied" apontado o caminho: c:\..\ireport\fonts.
Se alguém souber o que pode ser, por favor de um help!
Olá! Já tive o mesmo problema, mas recompilando ele, resolveu.
ResponderExcluirolá....
ResponderExcluirsabe o motivo do relatório não encontrar o sub-relatório no .jar da aplicação ?
obrigado?
Olá Lucas, também tive problemas desse tipo ao fazer testes mais a fundo com a parte de Desktop, acredito que tenha algum código que dê o caminho exato de dentro do .jar, mas até eu descobrir isso, a solução mais viável foi jogar os relatórios dentro de uma pasta no C:/ por exemplo, claro, essa não é a melhor solução, mas como mecho pouco com a parte Desktop acredito que não poderei te ajudar muito quanto a esse problema :(
ResponderExcluirAmigo como faco para passar um array list q eu mesmo estou populando...
ResponderExcluirList v = new ArrayList();
v.add(new vencimentos("20/04/2012", "30/12/2012"));
v.add(new vencimentos("20/04/2012", "30/12/2012") );
JRDataSource deps = new JRBeanCollectionDataSource(v);
p.put("subVencimento",deps);
mas gera um erro e nao sei como seguir se puder me ajudar fico grato
Vc criou o parâmetro com o nome "subVencimento"?
ExcluirMuito bacana suas explicações, mas tenho uma duvida posso passar nois parametros do visual para o Relatorio tipo
ResponderExcluirparametros.put( "data_inicio", campoFiltro.getText() );
parametros.put( "data_final", campoFiltro.getText() );
e tenho outra duvida não consigo passar uma data como parametro não sei como devo escrever.
se puder me ajudar agradeço
Clayton
Clayton... vc vai precisar criar no relatório parametros com o mesmo nome dos parametros que vc estiver passando. Caso vc crie um parametro com o nome data_inicio do tipo Date, aí vc precisa passar um parametro com data_inicio do tipo Date também.
ExcluirAndi eu criei o parametro no relatorio do tipo Date, mas por exemplo no codigo mesmo parametros.put( "data_final", campoFiltro.getText() );
Excluirnão pode ser ".getText" ele da erro. você tem algum exemplo que pode me ajudar? pois necessito demais disto para você ter ideia preciso apresentar isto hoje a noite e este parametro é o unico que não consigo fazer.
Clayton, quando vc dá um getText() ele retorna apenas uma string, vc precisa transformar isso num Date.
ExcluirSimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy");
Date data = formatador.parse(campoFiltro.getText());
Andi, no parametros.put( "data_final", campoFiltro.getText() ); vou passar assim parametros.put( "data_final", data ); ?
ExcluirIsso
ExcluirEste comentário foi removido pelo autor.
ExcluirAndi vou testar aqui, mas de qualquer forma muito obrigado pela sua atenção. tenha uma boa tarde.
ExcluirApenas uma sugestão.
ResponderExcluirEm vez de passar a lista por parametro, passa por JRBeanCollectionDataSource.
Todas as outras etapas funcionam normalmente.
Obrigado, com sua ideia, consegui resolver outra situação.
Abraço!
Pessoal to com um problemao aqui ve se alguem consegue me ajudar...
ResponderExcluirtenho o seguinte cenario...
uma lavanderia quand vai fazer uma receita de lavagem (uma receita Contem varias lavagens) e cada lavagem seu array de materia prima que e utilizado.
resumindo tenho um array de lavagems e dentro de cada lavagem um array de materia prima...
estou passand um array de lavagems para o Report porem nao estou conseguindo passar o array de materia prima pro subreport...
alguem pode me ajudar pelo amor de deus ? ><
Boa tarde pessoal, alguem sabe como manter o SubReport com tamanho estático? ou seja quando atinge o numero de registros dentro da banda Detail do subreport, ele não sobrepor os componentes a baixo, e listar o restante em uma nova pagina.
ResponderExcluirexcelente tutorial, foi de grande ajuda para min. muito obrigado.
ResponderExcluirComo anda? Muy buen aporte, pero tengo un problema. Puedo cargar el subreporte y no el reporte principal desde mi aplicacion.
ResponderExcluirO seu tutorial me ajudou muito!
ResponderExcluirConsegui achar como corrigir o erro do subreport.
Nas propriedades do subreport no summary, em Subreport Expression ao invés de colocar apenas $P{LocalizacaoPedidosSubreport}, coloque $P{LocalizacaoPedidosSubreport} + "pedidos_subreport.jasper".
Aí no método gerarRelatório deixe apenas o path da pasta em que está o .jasper do subrelatório. (src/pedidos/controle/relatorios/)
Alguém ainda da suporte neste post ? Tenho algumas dúvidas em relação ao relatórios do iReport/Jasper. Todos os exemplos, eu digo TODOS mesmo, que encontrei na web mostram sempre um JRBeanCollectionDataSource recebendo uma função que retorna todos os dados de uma tabela (select *). No entanto, a minha situação é a seguinte: Eu ja possuo um relatório onde busco todos os talhões de uma propriedade, dado o id dessa propriedade. Na chamada ao metodos que geram o relatorio eu tenho o trecho:
ResponderExcluirMap parametros = new HashMap<>();
parametros.put("propriedade", this.param_id);
JRDataSource jrds = new JRBeanCollectionDataSource(talhaoDao.readTalhaoByProp(param_id));
Notem que o método que vem da DAO e popula o dataSource, não eh uma lista geral (select *) mas sim um select com uma clausula where. A principio eu não sei se o método na DAO deveria de fato receber este parametro e me retornar apenas os talhoes da propriedade "param_id", ou se ele deveria ser mais genérico e o parametros passado no map restringiria de qual prorpiedade iria retornar os talhoes, meu código parece redundante e ate que o map dos parametros é inútil, o legal é que assim funciona.
O problema ta em um outro relatório que devo gerar, neste outro relatorio eu preciso mostrar para um determinado intervalo de talhoes em determinada propriedade, todos os plantios e erradicações existentes. Em outras palavras, eu preciso de um relatorio que tenha como parametros o id da propriedade que desejo avaliar, além de um intervalos entre talhaoes (definidos pelo "cod_talhao"). O chefe aqui deseja que neste relatorio seja impresso o cabeçalho do primiero relatorio (mais geral, de talhaoes por propriedade.) juntamente com as informações do plantio e erradicação dos talhaoes.
Imaginei o seguinte, um relatorio principal identico ao relatorio que ja tenho funcionando e um subRelatorio com as informações dos plantios e erradicações, a questão é que este relatorio esta vindo em branco, acredito que os parametros nao são lidos, ou minha busca no banco esta errada, tive que repetir a busca de talhoes porem com mais parametros, como talhaoDao.readTalhaoByProp(param_id, talhao_INI, talhao_FIM), também acrescentei esses parametros no map, e foi ai que comecei a pensar que estou usando errado o jasperReport.
Alguém pode me dar uma luz ?
Att,
Rafael
Muito bom o post, apenas duas observações:
ResponderExcluircorreto é: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource e não: new net.nf.jasperreports.engine.data.JRBeanCollectionDataSource, quando usar um JRDatasource expression.
Outro ponto que tive que me certificar é de colocar o caminho absoluto do relatório, não basta uma referência para a pasta apenas ...
Parabéns pelo tutorial.
ResponderExcluirEu gostaria de saber se eu consigo dentro do parâmetro passar um lista de opções. Tipo, clicar em uma alça lateral, como se fosse em alguns sites mesmo e nele eu conseguir colocar opções tipo : Data de vencimento, Dt. Emissão,etc" para que a possa possa escolher a opção desejada e assim gerar o relatório.