Visualizar JasperReports no browser

Olá pessoal tudo bem?

Estou tentando visualizar um relatório no browser usando uma api que construí com Jersey, porem estou recebendo erro abaixo, para ser sincero não entendi muito bem como fazer essa API visualizar PDF no browser e gostaria de um help para entender melhor esse processo.

javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.io.FileNotFoundException: \tmp.pdf (O cliente não tem o privilégio necessário)

public void printGuia(int empresa, String guia, OutputStream saida) {
try {
	// compila jrxml em memoria
	JasperReport jasper = JasperCompileManager.compileReport(this.getClass().getClassLoader().getResource("GuiaANS.jrxml").getPath());

	// preenche relatorio
	JasperPrint print = JasperFillManager.fillReport(jasper, null, new JRBeanCollectionDataSource(master));

	// exporta para pdf
	JRExporter exporter = new JRPdfExporter();
	exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
	exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, saida);
	exporter.exportReport();

} catch (Exception e) {
	throw new RuntimeException("Error", e);
}

}

	@GET
@Path("/pdf")
@Produces("application/pdf")
public javax.ws.rs.core.Response getPdf() throws Exception {
	OutputStream fileInputStream = new FileOutputStream("\\tmp.pdf");
	new GuiaAnsBusiness(em).printGuia(3, "NR GUIA PRESTADOR", fileInputStream);

	javax.ws.rs.core.Response.ResponseBuilder responseBuilder = javax.ws.rs.core.Response.ok((Object) fileInputStream);
	responseBuilder.type("application/pdf");
	responseBuilder.header("Content-Disposition", "filename=tmp.pdf");
	return responseBuilder.build();
}

Olá, boa tarde.

Aparentemente, o problema está com a forma que você passa seu diretório.(\tmp.pdf).
Para melhor entender, se você estiver usando Windows, crie dentro do C: uma pasta para guardar os relatórios.

Depois direcione o pdf para essa pasta, simplificando assim:

String caminho = "C:"+System.getProperty("file.separator")+[nome_da_pasta_criada]+System.getProperty("file.separator")+"tmp.pdf";
OutputStream fileInputStream = new FileOutputStream(caminho);

Um dia, caso considere viável, você pode passar os bytes diretamente para o browser, gerando assim o pdf sem a necessidade de aloca-lo como arquivo em alguma pasta.

A grosso modo, você precisaria de um método que retorne os bytes pelo Jasper:

public static byte[] relaltorio_WEB(Collection<ListaDeAlgo> lista, Map<String, Object> parametros) throws JRException {
		JasperReport relatorioJasper = JasperCompileManager.compileReport(this.getClass().getClassLoader().getResource("GuiaANS.jrxml").getPath());
		byte[] bytes = JasperRunManager.runReportToPdf(relatorioJasper, parametros, new JRBeanCollectionDataSource(lista));
		return bytes;
	}

Depois faria a chamada do método, como por exemplo:

Map<String, Object> parametros = new HashMap<String, Object>();
parametro.put("nomeRelatorio", "Relatório de Guias");
byte[] bytes = ClasseRelatorio.relaltorio_WEB(null , parametros);
String header = "inline; filename=tmp.pdf";
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", header);
response.setContentLength(bytes.length);
ServletOutputStream ouputStream = response.getOutputStream();
ouputStream.write(bytes, 0, bytes.length);
ouputStream.flush();
ouputStream.close();

Bem, só para clarear um pouco as idéias =)

3 curtidas

@Mstanguine muito obrigado por responder usando byte ficou bem mais genérico já que não preciso me prender a diretório.

Abraço