Problema VRaptor + PDF + Browser

Estou com problemas na hora de mostrar um PDF, em uma nova window do browser.

EStamos utilizado o plug0in VRaptor-jasperreports, para retornar por download o pdf a ser mostrado.

Na parte js, estamos fazendo a requisição Ajax, esta é executada com sucesso, reponse.responseText, aparentemente tem o PDF gerado… mais mostra com caracteres inválidos.

Se chamar o mesmo metodo do controller, via url do browser ele mostra corretamente o pdf. Só que precisamos fazer isto no extJs.

Requisição Ajax no extjs:

Ext.Ajax
								.request({
									url : 'sen/parametroPisCofinsRelatorio',
									method : 'Get',
									jsonData : data,
									success : function(response, opts) {
										window.open("data:application/pdf," + escape(response.responseText));
									},
									failure : function(response, opts) {
										Ext.MessageBox
												.alert(
														'Erro ao gerar Relatório de parâmetro do Pis/Cofins!',
														response.responseText);
									}
								});

Quando executa… chama o leitor de pdf… só que não carrega… dá Falha ao carregar documento PDF (Format error: not a PDF or corrupted)

Se alguem puder ajudar.

Obrigado

Rodrigo

e sem o escape, funciona?

Rodrigo, o problema é que para isso funcionar os browsers exigem que o retorno seja em base 64.

Uma forma de fazer isso é da seguinte forma:

@Get("/report/json") 
public void jsonReport(ReportExporter exporter) {
   byte data[] = exporter.export(report()).to(pdf());
   result.use(json()).withoutRoot().from(Base64.encodeBytes(data)).serialize();
}

Obs: se vc esta usando o vraptor 3.4 receba ReportExporter dessa forma, senão receba no construtor do seu controller.

Agora basta modificar sua view para:

Ext.Ajax.request({
			url : '/report/json',
			method : 'Get',	
			success : function(response, opts) {
				var reportContent = Ext.util.JSON.decode(response.responseText); 
				window.open('data:application/pdf;base64,' + reportContent);
			},
			failure : function(response, opts) {
				Ext.MessageBox.alert('Erro ao gerar Relatório de parâmetro do Pis/Cofins!', response.responseText);}
			});

se funcionar abre uma issue no github que eu posso criar um helper no vraptor-jasperreports.

Então Rodrigo, subi para o vraptor-jasperreports um helper:

@Get("/clients.json") 
public void jsonReport(ReportDataURIBuilder builder) {
    String uri = builder.build(report(), pdf());
    result.use(json()).withoutRoot().from(uri).serialize();
}

no jsp

$("#reportButton").click(function() {
    $.getJSON('/clients.json', function(uri) {
        window.open(uri);
    });
});

espero que te ajude…

Eu estou tentando jogar o relatório em outra aba, mas não está funcionando.

quando uso o window.open, o objeto pesquisa vem nulo. Quando uso sem o window.open (como está no código) funciona, mas ai vem na mesma página.

Esse é o melhor jeito de colocar esse relatório em outra aba ? Se sim, como passo o(s) objeto(s) como parâmetro ?

jquery

        //window.open(principal.action + 'vendedorImprimir'); 
        principal.action = principal.action + 'vendedorImprimir';
        principal.submit();

vraptor

    @Get("/vendedorImprimir")
    public Download vendedorImprimir(Pesquisa pesquisa) throws SQLException, JRException {

        if (pesquisa == null) {
            pesquisa = new Pesquisa();
            pesquisa.setDescOrdem(" id ");
            pesquisa.setOrdem(2);
        }
        
        arrumaPesquisa(pesquisa);        
        List<Vendedor> lista = dao.getLista( campos, valores, pesquisa.getDescOrdem() );
                                
        Map<String, Object> parametros = new HashMap<String, Object>();  
                
        String contextDir = context.getRealPath("/");
        String jasperDir = contextDir.concat("WEB-INF/jsp/vendedor/");
        String jasperFile = jasperDir.concat("report1.jasper");
                 
        parametros.put("contextPath", contextDir);
        parametros.put("jasperPath", jasperDir);
        
        JRDataSource jrds = new JRBeanCollectionDataSource(lista);                  
        JasperPrint print = JasperFillManager.fillReport(jasperFile, parametros, jrds);
        
        JRExporter exporter = new JRPdfExporter();
        ByteArrayOutputStream exported = new ByteArrayOutputStream();
        
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, exported);
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
           
        exporter.exportReport();
           
        byte[] content = exported.toByteArray();   
        return new InputStreamDownload(
            new ByteArrayInputStream(content),
            "application/pdf",
            "listadevendedor",
            false,
            content.length);        
        
    }

se vc quer abrir em outra aba, Keep It Simple:

<a href="urlDoRelatorio" target="_blank">Relatorio</a>

não precisa de ajax nem nada =)

Oi Lucas, obrigado pela ajuda, mas o objeto Pesquisa continua chegando em branco.

Nesse objeto eu guardo os filtros utilizados na pesquisa, por isso ele é importante chegar no vraptor.

então ao invés de usar um link, use um form com os dados da pesquisa com o target="_blank" pra abrir em outra janela/aba:

<form action="urlDoRelatorio" target="_blank" method="post">
    <input name="pesquisa.algumAtributo".../>
    <input name="pesquisa.outroAtributo".../>
</form>

Obrigado Lucas, deu certinho.