VRaptor 3 - JasperMaker (para JasperReporter)

Uma solução para transformar o resultado do jasperReporter em um download no browser… escolhendo nome, e podendo ou não forçar download.
além de oder enviar parametros, e enviar uma Coleção como DataSource

http://pastebin.com/8ABRRHE7

coloca esse componente no seu projeto

e dentro da sua lógica faz assim

[code]
@Resrouce
public class MeuController{
private final JasperMaker jasperMaker;

 //Injeta no construtor o jasperMaker
 public MeuController(JasperMaker jasperMaker) {
      this.jasperMaker = jasperMaker
 }


 public Download minhasLogica() {
       //aqui vc monta a coleção para ser usada como DataSource no jasper
       //e coloca seus parametros (se quiser) em um mapa de parametros...

       return jasperMaker.makePdf(
           "seuArquivoJasper.jasper",
           suaColecaoComOsBeansParaDataSource, 
           "nomeDoArquivoQueSeraExibidoParaUsuario.pdf", 
           desejaForcarODownload, 
           opicionalmenteObjetosParametrosPodemSerEnviadosOuNao);
 }

} [/code]

Pronto… é isso

por padrão, o jasperMaker usa a pasta “WEB-INF/jasper/” para procurar seus arquivos *.jasper

caso queria trocar esse lugar padrão, é só trocar o lugar no web.xml colocando o seguinte

<context-param>
	<param-name>vraptor.jasperMaker</param-name>
	<param-value>WEB-INF/jasper/</param-value>
</context-param>

caminho que inicia com “/” é conciderado caminho absoluto da maquina
caminho que inicia sem a barra, que é o caso do exemplo que passei, usa como base o caminho do contexto, ou seja, o caminho do seu WebContent

dentro do jasper, vc vai ter dois parametros pra usar se quiser… o 1° é o “jasperPath” que contémo caminho para a pasta dos arquivos .jasper, que é útil para sub-relatorios, e o 2° é o “contextPath” que é o caminho do WebContent, e é útil pra encontrar qualquer arquivo dentro do container web.

é isso

boa sorte pra quem for usar

Agradecimentos ao Lucas, que ajudou a colocar o resultado do jasper dentro do objeto Download do vraptor.

Libs necessários para usar jasper, com essa solução (pelomenos as que eu precisei)

  • commons-digester-1.7.jar
  • commons-beanutils-1.7.0.jar
  • groovy-all-1.5.5.jar
  • iText-2.1.0.jar
  • jasperreports-3.7.0.jar

Oi Lavieri!
Estou usando o JasperMaker, agora preciso criar um form para passar parâmetro e gerar o relatório com os parâmetros passado:

public Download geraRelatorioImoveisProprietario(Proprietario proprietario) {
	      //aqui vc monta a coleção para ser usada como DataSource no jasper
	      //e coloca seus parametros (se quiser) em um mapa de parametros...	
		List<Imovel> imoveis = imovelDAO.lista();
	      return jasperMaker.makePdf(
	      "relatorioImoveis.jasper",
	      imoveis, 
	      "relatorio-imoveis-proprietario.pdf", 
	      true, proprietario.getIdProprietario()); // passagem de parâmetros
	}		

Como eu poderia passar parâmetros ali? Outra dúvida é quanto a subrelatório, fiz um aqui pra teste, ao chamar o relatório principal o subrelatório será chamado automáticamente?
Abraço!! o/

[quote=Guevara]Oi Lavieri!
Estou usando o JasperMaker, agora preciso criar um form para passar parâmetro e gerar o relatório com os parâmetros passado:

public Download geraRelatorioImoveisProprietario(Proprietario proprietario) {
	      //aqui vc monta a coleção para ser usada como DataSource no jasper
	      //e coloca seus parametros (se quiser) em um mapa de parametros...	
		List<Imovel> imoveis = imovelDAO.lista();
	      return jasperMaker.makePdf(
	      "relatorioImoveis.jasper",
	      imoveis, 
	      "relatorio-imoveis-proprietario.pdf", 
	      true, proprietario.getIdProprietario()); // passagem de parâmetros
	}		

Como eu poderia passar parâmetros ali? Outra dúvida é quanto a subrelatório, fiz um aqui pra teste, ao chamar o relatório principal o subrelatório será chamado automáticamente?
Abraço!! o/[/quote]

vc tem que criar um MAP, e dentro do map colocar, a srtring do nome do parametro no chave, e o objeto que será enviado como parametro no value.

veja a assinatura do método

public Download makePdf(String jasperFile,Collection<?> dataSource, String fileName, boolean doDownload, Map<String,Object> parametros) { //... }

como pode ver Map<String,Object> parametros

os sub-relatórios são chamados pelo jasper, elechama automaticamente, só colocar o caminho relativo, e os manter na mesma pasta do relatório principal.

Beleza Lavieri! Consegui gerar o relatório, mas só veio o que têm os dados do proprietário, o subrelatório com os dados do imóvel que ele possui não veio. Lá no iReport ao criar o subrelatório, foi gerado outro jasper e os dois estão juntos na mesma pasta jasper do projeto. Preciso colocar mais alguma coisa no método ou era pra ter puxado automáticamente o subrelatório?
Veja como estão:

Abraço!!

[quote=Guevara]Beleza Lavieri! Consegui gerar o relatório, mas só veio o que têm os dados do proprietário, o subrelatório com os dados do imóvel que ele possui não veio. Lá no iReport ao criar o subrelatório, foi gerado outro jasper e os dois estão juntos na mesma pasta jasper do projeto. Preciso colocar mais alguma coisa no método ou era pra ter puxado automáticamente o subrelatório?
Veja como estão:

Abraço!![/quote]

na referencia do seu relatório principal, para o subrelatório, tem que estar o caminho relativo, e não o absoluto…

ou então vc pode colcar “P{jasperPath}relProprietarios_subreportImovel.jasper”

confira o nome, posso ter digitado errado… o P{jasperPath} para usar ele, vc precisa declarar a propriedade no relatorio principal, colocando ela como string.

o parametro jasperPath é enviado automaticamente para o jasper, quando usado esse código q desenvolvi.

Oi Lavieri!
Pelo iReport está trazendo os dados dos dois, mas pela aplicação não.

No Controller, estou passando a id assim:

public Download geraRelatorioProprietarios(Long idProprietario) {	
		List<Proprietario> proprietarios = proprietarioDAO.lista();		
		Map<String, Object> map = new HashMap<String, Object>(); 
		map.put("idProprietario", idProprietario); // passo a id do proprietario pro relatorio Master, deveria repassar pro subrelatorio

	      return jasperMaker.makePdf(
	      "relProprietarios.jasper",
	      proprietarios, 
	      "relatorio-proprietarios.pdf", 
	      true,
	      map 
	   );
	}	

Parece que o subrelatório não está recebendo a id do Master.

Veja como consegui linkar os dois usando HQL:
http://www.guj.com.br/posts/list/218802.java

Abraço!

Continuo com o problema, testei agora passando o CPF como parâmetro, no iReport o subrelatório é embutido no Master, mas pelo JasperMaker não. Só vêm os dados do proprietário. =/

public Download geraRelatorioImoveisProprietario(Proprietario proprietario) {
		  List<Proprietario> prop = proprietarioDAO.getImoveisPorCpf(proprietario);
		  Map<String, Object> map = new HashMap<String, Object>(); 
		  map.put("cpf", proprietario.getPessoa().getCpf());		  
		  return jasperMaker.makePdf(
		  "relImoveisProprietario.jasper",
		  prop, 
		 "relatorio-imoveis-proprietario.pdf", 
		  true,
		  map 
	   );
	}		

Abraço!

Relatório feito no iReport:

Refiz o relatório umas 5 vezes, mas pelo JasperMaker só vêm os dados do proprietário. =/

Lá no iReport coloquei assim o “subreport expression”:

$P{SUBREPORT_DIR} + "relImoveisProprietario_subreport.jasper"

O jrxml do Master na parte do sburelatório está assim:

<subreport>
				<reportElement x="0" y="97" width="555" height="53"/>
				<parametersMapExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}]]></parametersMapExpression>
				<subreportParameter name="SUBREPORT_DIR">
					<subreportParameterExpression><![CDATA[$P{SUBREPORT_DIR}]]></subreportParameterExpression>
				</subreportParameter>
				<subreportParameter name="cpf">
					<subreportParameterExpression><![CDATA[$P{cpf}]]></subreportParameterExpression>
				</subreportParameter>
				<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
				<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "relImoveisProprietario_subreport.jasper"]]></subreportExpression>
			</subreport>

Deve ser ai que o JasperMaker não está achando o caminho para o subrelatório…

Abraço!

é algo assim

Obs.: eu não fiz pelo XML, eu fiz pelo jasper reporter mesmo, abre o IReport, e configurei o subrelatorio


&lt;subreport&gt;
	&lt;reportElement mode="Opaque" x="0" y="0" width="595" height="5"&gt;
		&lt;printWhenExpression&gt;&lt;![CDATA[$P{contador}.renderiza($P{mensuracao}.getT(),$F{this})]]&gt;&lt;/printWhenExpression&gt;
	&lt;/reportElement&gt;
	&lt;subreportParameter name="dateUtil"&gt;
		&lt;subreportParameterExpression&gt;&lt;![CDATA[$P{dateUtil}]]&gt;&lt;/subreportParameterExpression&gt;
	&lt;/subreportParameter&gt;
	&lt;subreportParameter name="counter"&gt;
		&lt;subreportParameterExpression&gt;&lt;![CDATA[$P{contador}]]&gt;&lt;/subreportParameterExpression&gt;
	&lt;/subreportParameter&gt;
	&lt;dataSourceExpression&gt;&lt;![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource(java.util.Collections.singletonList($F{this}))]]&gt;&lt;/dataSourceExpression&gt;
	&lt;subreportExpression class="java.lang.String"&gt;&lt;![CDATA[$P{jasperPath} + ($F{this} != null ? $P{resolver}.getSubRelatorio($F{this}): "GEOR-FichaMensuracao_ABERTA.jasper")]]&gt;&lt;/subreportExpression&gt;
&lt;/subreport&gt;

o que importa mesmo desse trecho todo ???

E o que importa desse trecho menor ??

ou seja, no link do subreporter eu aponto como sendo

isso quer dizer que, ele vai usar como o relatorio de subreporter a pasta passada no argumento jasperPath + o nome do subreporter

se vc quer usar, $P{SUBREPORT_DIR} vc precisa passar esse parametro para dentro do jasper…

o parametro que eu passo é o $P{jasperPath}

Tá brabo, deixei parecido com o seu, só que além do cpf, pede o jasperPath, preencho o cpf e me pede o jasperPath, deixando em branco ou colocando o nome do subrelatório, só vêm os dados do proprietário:

<subreport>
				<reportElement x="0" y="97" width="555" height="53"/>
				<parametersMapExpression><![CDATA[$P{cpf}]]></parametersMapExpression>
				<subreportParameter name="cpf">
					<subreportParameterExpression><![CDATA[$P{cpf}]]></subreportParameterExpression>
				</subreportParameter>
				<dataSourceExpression><![CDATA[$P{jasperPath} + "relImoveisProprietario_subreport.jasper"]]></dataSourceExpression>
			</subreport>

Tava querendo usar o $P{SUBREPORT_DIR}, ai eu substituo no lugar do jasperPath criado? Crio lá SUBREPORT_DIR?

Eu preciso usar esta configuração que está funcionando no JasperMaker:

Com essa configuração vêm td certo.
Valeu!!

nop, se pareceu brabo devo ter me expressado errado ^^…

[quote=Guevara]Com essa configuração vêm td certo.
Valeu!![/quote]

se funcionou agora então blz ^^

Não não :smiley:
Está perfeito no iReport, no JasperMaker vêm só os dados do proprietário, os dados dos imóveis não vêm. hehehe
Por algum motivo o JasperMaker não traz os imóveis com aquela configuração do print. =/

o que deve estar faltando então é o campo “Data Source Expression”, no meu caso o meu valor é

no seu pode ser outra coisa… ^^

Então Lavieri, como eu tenho um atributo em Proprietario List imoveis, usei imoveis como data source:
connection type:

Use a datasource expression

Data Source Expression

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

Mesmo assim os dados dos imóveis não são puxados.

Consegui Lavieri!
Era isso ai que acabei de passar mesmo, o “imoveis” é passado como data source pro subrelatório, o que precisava era deletar a query que ainda estava no subrelatório. heheh
Valeu pela força!!
Abraço!!!

Guevara BOA TARDE !

Esse projeto que vc ta fazendo é o WebChat ?

Onde ta os fontes ?

jr

Lavieri, não quer colocar esse plugin no vraptor-contrib, por favor?

pode ser em outro repositório do git, daí eu adiciono como submodulos

Lavieri Cara esse plugin e uma mae ! nossa

PARABÉNS ! tu tem um DEMO usando ele ?

jr

A classe JasperMaker tem como argumento no construtor um ServletContext
Como vocês criaram o ServletContext para passar para o teste junit?