Relatorio saindo em branco via browser

Ola,
Montei o fluxo do realtorio da seguinte forma:

Preencho os filtros na tela e carrego as informacoes numa tabela. Coloquei um botao para pegar o conteudo da tabela e enviar para o servidor que devolve o pdf num array de bytes. O browser mostra a janela para salvar e baixa o arquivo. Porem o relatorio fica em branco. O numero de paginas condiz com o resultado, mas as folhas ficam embranco, sequer aparece o template. Se eu mandar salvar o relatorio em disco la no service, sem passar pelo navegador, o relatorio fica certo. Entao o que nao estou sabendo fazer é o tratamento correto do metodo success do ajax. Como seria para pegar esse pdf? coloquei os metodos e como estou fazendo

Classe controller

@PostMapping("/sugestaoCompra")
	public @ResponseBody ResponseEntity<byte[]> gerarRelatorioVendasEmitidas(@RequestBody List<ProdutoConsumo> itens) throws JRException {		
		byte[] relatorio = relatorioService.gerarSugestaoCompra(itens);
		return ResponseEntity.ok()
				.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_PDF_VALUE)
				.header(HttpHeaders.CONTENT_DISPOSITION, "attachment")
				.body(relatorio);
	}

Classe service

@Service
public class RelatorioService {

	public byte[] gerarSugestaoCompra(List<ProdutoConsumo> itens) throws JRException {
		InputStream inputStream = this.getClass().getResourceAsStream("/relatorios/relatorio_sugestao_compra.jrxml");
		JasperReport jasperReport = JasperCompileManager.compileReport(inputStream);
		JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(itens);

		Map<String, Object> parametros = new HashMap<>();
		parametros.put("createdBy", "Aratu");
		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parametros, dataSource);

        //coloquei essa linha so para verificar se saia em branco tambem
		JasperExportManager.exportReportToPdfFile(jasperPrint, "C:\\Users\\th1m0r\\Desktop\\sugestao_compra.pdf");

		return JasperExportManager.exportReportToPdf(jasperPrint);
	}

}

arquivo javascript

var itens = [];
	var exportPdf = $("#btnExportPdf");
	exportPdf.on("click", exportarSugestaoPdf.bind(this));
	
	function exportarSugestaoPdf(event) {	
		event.preventDefault();
    	
    	if(itens.length === 0) {
    		Swal.fire("Mensagem", "É necessário carregar os itens em tela", "error")
    		return;
    	}

		$.ajax({
			url : "/relatorios/sugestaoCompra",
			method : 'POST',
			contentType : 'application/json',
			data : JSON.stringify(itens),
			success : onSuccess.bind(this),
			error : onError.bind(this)
		});
	}
	
	function onSuccess(resposta) {
        var blob = new Blob([resposta], { type: 'application/pdf' });

        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(blob);
        }
        else {
            var arquivo = URL.createObjectURL(blob);
            var janela = window.open(arquivo);
            janela.focus();
        }
	}
	
	function onError(resposta) {
		Swal.fire("Mensagem", "Erro ao gerar relatorio", "error")
	}

Para receber binários como response, lembro que precisei usar algo assim:

responseType: 'arraybuffer'

Com isso, o seu Blob vai funcionar. Porém, se esse ajax for com jquery, não sei se ele suporta esse responseType.

FONTE: Receiving binary data using JavaScript typed arrays

1 curtida

Pois é tive que alterar o metodo e nao usar o ajax. Dessa forma funcionou. Utilizei tambem um plugin, o download.js

	function exportarSugestaoPdf(event) {	
		event.preventDefault();
    	
    	if(itens.length === 0) {
    		Swal.fire("Mensagem", "É necessário carregar os itens em tela", "error")
    		return;
    	}
    	
    	var x = new XMLHttpRequest();
		x.open("POST", "/relatorios/sugestaoCompra", true);
		x.responseType = 'blob';
    	x.setRequestHeader($('input[name=_csrf_header]').val(),$('input[name=_csrf]').val())
    	x.setRequestHeader("Content-Type", "application/json");
		x.onload=function(e){download(x.response, "sugestao_compra.pdf", "application/pdf"); }
		x.send(JSON.stringify(itens));
	}