cómo generar dinámicamente pdf usando servlet

I am generating a pdf using JasperInformes in JSP, servlet. I am passing string parameter to the report. When I try to generate single pdf, the pdf is generated nicely but when I try to generate two pdf, for the 1st parameter, pdf is generated but for the 2nd parameter, pdf is not generate.

I'm passing the parameters through a loop.

String array[]={"1233","234"};
HashMap params = new HashMap();
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection cn=DriverManager.getConnection("jdbc:oracle:thin:@103.179.1.218:1521:tims","scoot","tiger");

for(int i=0;i<array.length;i++) {
    params.put("seller_name",array[i]);

    JasperDesign jasperDesign = JRXmlLoader.load(getServletContext().getRealPath("/")+"report\\CForm.jrxml");
    JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
    JasperPrint jasperprint = JasperFillManager.fillReport(jasperReport,params, cn);
    byte[] pdfasbytes = JasperExportManager.exportReportToPdf(jasperprint);
    ServletOutputStream outstream=response.getOutputStream();
    response.setContentType("application/pdf");
    response.setContentLength(pdfasbytes.length);
    String fileName="report"+i+".pdf";
    response.setHeader("Content-disposition", "attachement; filename="+fileName);
    outstream.write(pdfasbytes);
    JRExporter exporter = new JRPdfExporter();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperprint);
    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outstream);
    params.clear();

}

preguntado el 28 de agosto de 12 a las 12:08

U mean u try to output two files in the response output stream? -

in both the case i found the same result,,thats why i close the output stream. -

3 Respuestas

There are ways to send multi-files in a response but it is inconsistent among browsers. I believe the best approach would be to return a pdf in case of a single file and a zip file in case of multi-files in case you want that single file to open directly in a browser.

I changed your code to return a zip file containing the reports but you should cater for the hard coded strings you have there(seller_name) and also move some functionality to other classes rather than a single method.

protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
    ZipOutputStream zipfile = null;

    try {
        String array[] = {"1233", "234"};
        HashMap params = new HashMap();

        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@103.179.1.218:1521:tims", "scoot", "tiger");

        // Wrap the servlet output stream with a zip output stream
        zipfile = new ZipOutputStream(response.getOutputStream());

        for (int i = 0; i < array.length; i++) {
            params.put("seller_name", array[i]);

            JasperDesign jasperDesign = JRXmlLoader.load(getServletContext().getRealPath("/") + "report\\CForm.jrxml");
            JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);                
            JasperPrint jasperprint = JasperFillManager.fillReport(jasperReport, params, cn);

            byte[] pdfAsBytes = JasperExportManager.exportReportToPdf(jasperprint, params, cn);

            // Create and add the zip entry 
            ZipEntry zipentry = new ZipEntry("report" + i + ".pdf");                                
            zipfile.putNextEntry(zipentry);                
            zipfile.write(pdfAsBytes);                                
        }            

        // Add the response headers
        response.setHeader("Content-disposition", "attachement; filename=" + UUID.randomUUID().toString() + ".zip");                
        response.setContentType("application/zip");            
    } catch (Exception ex) {
        log("An error occured", ex);
    } finally{
        try {
            // Flush the stream
            zipfile.flush();
        } catch (Exception e) {                
        }

        try {
            // Close the stream
            zipfile.close();
        } catch (Exception e) {                
        }
    }
}

¡Espero que ayude!

Respondido 28 ago 12, 17:08

Some comments/suggestion

  1. The response of the servlet is per request. i.e. one request followed by one response.
  2. You are closing the ServletOutputSteam at the end of loop and hence stopping any further responses.
  3. You approach might now work for multiple PDF. One way out is create a list of PDF in the loop, create zip of all the PDFs and send that to the end user.

Respondido 28 ago 12, 13:08

If you want to generate two pdf using the same output stream is impossible. You can generate only one file using an output stream.

If you want to generate 2 or more pdf file i suggest you to create a zip file and write it in the output stream.

Analyzing your code it is clear you can't generate two files because during the loop you close the output stream and flush the data.

You should obtain in such way a Response already commeted or something like that.

Respondido 28 ago 12, 12:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.