Gerar PDF Jasper Reports com API Restful Java (JAX-RS)

10 respostas Resolvido
jasperjavarest
G

Boa tarde!
Tenho uma API Restful Java (JAX-RS) e preciso retornar um PDF.

A ideia é a seguinte:
tenho um método GET que vai me passar uns parâmetros
e esse método vai chamar o gerarJasper que precisa retornar um .jasper e imprimir um PDF no navegador

segue abaixo o código

@Path("/Integracao")
public class Integracao{

@GET
@Path("/teste")
public void teste(){
	TrCboServiceImpl cS = new TrCboServiceImpl();
	List datasource = null;
	try {
		datasource = cS.listAll();
	} catch (ServiceException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	AbstractApplicationBean aab = new AbstractApplicationBean() {		
		@Override
		public boolean useMultiempresaService() {
			// TODO Auto-generated method stub
			return false;
		}
	}; 
	
	
	try {
		aab.gerarJasper("RelTrCbo", TipoRelatorioEnum.PDF.getType(), datasource, new HashMap());
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

}

e o método do jasper

public void gerarJasper(String name, String type, List data, Map params) throws IllegalArgumentException, RuntimeException, Exception {

    boolean found = false;
    for (int i = 0; i < VALID_TYPES.length; i++) {
        if (VALID_TYPES[i].equals(type)) {
            found = true;
            break;
        }
    }
    if (!found) {
        throw new IllegalArgumentException("Tipo solicitado '" + type + "' inválido");
    }

    // Procurar recurso de design de relatório compilado
    // dá NullPointerException na linha abaixo
    ExternalContext econtext = FacesContext.getCurrentInstance().getExternalContext();
    
    InputStream stream = econtext.getResourceAsStream(PREFIX + name + SUFFIX);
    if (stream == null) {
        throw new IllegalArgumentException("O relatório '" + name + "' não existe");
    }

    FacesContext fc = FacesContext.getCurrentInstance();
    ServletContext context = (ServletContext)fc.getExternalContext().getContext();
    String path = context.getRealPath(File.separator) + "resources/jasper" + File.separator;
    String logo = context.getRealPath(File.separator) + "resources/imagens" + File.separator;
    params.put("SUBREPORT_DIR", path);
    params.put("LOGO_DIR", logo);                
                            
    JRDataSource ds = new JRBeanArrayDataSource(data.toArray());
    JasperPrint jasperPrint = null;
    try {
        jasperPrint = JasperFillManager.fillReport(stream, params, ds);
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new FacesException(e);
    } finally {
        try {
            stream.close();
        } catch (IOException e) {
        }
    }

    JRExporter exporter = null;
    HttpServletResponse response = (HttpServletResponse) econtext.getResponse();
    FacesContext fcontext = FacesContext.getCurrentInstance();
    try {
        response.setContentType(type);
        if ("application/pdf".equals(type)) {
            exporter = new JRPdfExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        } else if ("text/html".equals(type)) {
            exporter = new JRHtmlExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());
            // Tornar imagens disponíveis para a saída HTML
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();
            request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, new HashMap());
            // A seguinte instrução requer mapeamento / imagem
            // para o imageServlet no web.xml.
            //
            // Este servlet serve imagens, incluindo imagens px
            // para espaçamento.
            //
            // Sirva as imagens diretamente para não
            // incorrermos em tempo extra associado a
            // a uma solicitação JSF para uma entidade não-JSF.
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");
        }else if("application/xlsx".equals(type)){
        	exporter = new JRXlsxExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        }else if("application/docx".equals(type)){
        	exporter = new JRDocxExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        } else if("application/rtf".equals(type)){
        	exporter = new JRRtfExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        }
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new FacesException(e);
    }

    try {
        exporter.exportReport();
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new FacesException(e);
    }
    fcontext.responseComplete();
}

alguém poderia me ajudar?

10 Respostas

B

vc pode retornar um xml com base64 do seu pdf e depois é só converter

D

Não, restful aceita o envio de arquivos pdf.

D

Alguma exceção?

G

Dá NullPointerException no método gerarJasper, na linha ExternalContext econtext = FacesContext.getCurrentInstance().getExternalContext();

Acho que é porque eu não uso uma página jsp, xhtml pra chamar o método, estou apenas invocando a URL

D

Peraí, vamos por partes.
Você tem uma aplicação JAX-RS ou uma aplicação JSF?

G

eu extraí o método que gera o PDF (gerarJasper) de uma aplicação JSF

mas eu preciso chamar ela de uma API Restful com JAX-RS

D

Então esquece o FacesContext, isso só existe se você estiver numa aplicação JSF.
Para trabalhar com JAX-RS, você precisa de algo assim ou assim

G

eu preciso de usar o jasper report pra gerar o pdf de forma dinâmica, de acordo com os dados retornados pela datasource

você conhece alguma forma do jasper montar esse pdf de forma dinâmica darlan?

D

Cara, faça uma coisa por vez.
Veja e tente tirar o que precisa para gerar o pdf.
Lembrando, você não vai enviar, efetivamente, um pdf pronto, vai enviar um array de bytes que representam este pdf.

G
Solucao aceita

Consegui resolver Darlan!
Segui este seu último post como norte,
Precisei importar algumas bibliotecas barbecue-1.5, barcode4j-2.0, jasperserver-ireport-plugin-2.0.1, jdt-compiler-3.1.1 jars na pasta lib do meu projeto (Restful API)

segue abaixo o codigo
Classe de recurso

@Path("/Integracao")
public class Integracao {

@Context
private HttpServletRequest httpServletRequest;

@GET
@Path("/gerarPdf")
public Response geraPDF(@QueryParam("relatorio") String arquivoJrxml,
                    @QueryParam("autorizacao") String autorizacao){

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Map fillParams = new HashMap(); 
fillParams.put("IMPRAUTORIZACAO", autorizacao);
PdfGenerator pdf = new PdfGenerator();
byte[] bytes= pdf.generateJasperReportPDF(httpServletRequest, arquivoJrxml, outputStream, fillParams);

String nomeRelatorio= arquivoJrxml + ".pdf";
return Response.ok(bytes).type("application/pdf").header("Content-Disposition", "filename=\"" + nomeRelatorio + "\"").build();
}

classe utilitária

public class PdfGenerator {

public byte[]  generateJasperReportPDF(HttpServletRequest httpServletRequest, String jasperReportName, ByteArrayOutputStream outputStream, Map parametros) {
JRPdfExporter exporter = new JRPdfExporter();
try {
    String reportLocation = httpServletRequest.getRealPath("/") +"resources\\jasper\\" + jasperReportName + ".jrxml";

    InputStream jrxmlInput = new FileInputStream(new File(reportLocation)); 
    //this.getClass().getClassLoader().getResource("data.jrxml").openStream();
    JasperDesign design = JRXmlLoader.load(jrxmlInput);
    JasperReport jasperReport = JasperCompileManager.compileReport(design);
    //System.out.println("Report compiled");

    //JasperReport jasperReport = JasperCompileManager.compileReport(reportLocation);
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parametros, HibernateUtils.currentSession().connection()); // datasource Service

    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);   
    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outputStream);
    exporter.exportReport();
} catch (Exception e) {
    e.printStackTrace();
    System.out.println("Error in generate Report..."+e);
} finally {
}
return outputStream.toByteArray();
}
}
Criado 18 de abril de 2018
Ultima resposta 19 de abr. de 2018
Respostas 10
Participantes 3