Search code examples
grailsjasper-reportsexport-to-pdfjasper-plugin

Jasper Report Plugin Generate PDF in Grails 2.4.2


I use jasper report plugin in grails 2.2.4 to generate PDF file. My code for the controller :

import org.codehaus.groovy.grails.plugins.jasper.JasperExportFormat
import org.codehaus.groovy.grails.plugins.jasper.JasperReportDef

class LabController {
    def jasperService
    def directpdf() {

        def reportDef = new JasperReportDef(name:'mbarang.jrxml', fileFormat:JasperExportFormat.PDF_FORMAT)

        response.contentType = 'application/pdf'
        response.outputStream << jasperService.generateReport(reportDef).toByteArray()


        return(false);
    }
}

Those code is working properly in grails 2.2.4. But when I run at grails 2.4.2 I got this error :

Error 500: Internal Server Error
Message
getOutputStream() has already been called for this response

why I got this error?


Solution

  • I change the way to send the byteArray I use the render method, so it's become :

    render(file: jasperService.generateReport(reportDef).toByteArray(), contentType: 'application/pdf')

    But I got another error :

    Error 500: Internal Server Error Class java.lang.ClassNotFoundException Message org.apache.commons.collections.ReferenceMap

    I think it's about the plugins issue, I think the jasper plugin is incompatible with grails 2.4.2. I decided to use the jasper library directly. Copy the required .jar to lib/ folder. I download this .jar :

    commons-beanutils-1.9.2.jar commons-collections-3.2.jar commons-digester-2.1.jar commons-logging-1.2.jar itext-2.1.7.jar jasperreports-5.6.0.jar

    Then change my controller become, something like this :

    import net.sf.jasperreports.engine.JRException;
    import net.sf.jasperreports.engine.JRExporter;
    import net.sf.jasperreports.engine.JRExporterParameter;
    import net.sf.jasperreports.engine.JasperCompileManager;
    import net.sf.jasperreports.engine.JasperFillManager;
    import net.sf.jasperreports.engine.JasperPrint;
    import net.sf.jasperreports.engine.export.JRPdfExporter;
    
    class LaporanController {
        def printbarang() {
            try {
                String reportName = "c:/xampp/halo"
                // compiles jrxml
                JasperCompileManager.compileReportToFile(reportName + ".jrxml");
                // fills compiled report with parameters and a connection
                // JasperPrint print = JasperFillManager.fillReport(reportName + ".jasper", parameters, connection);
                JasperPrint print = JasperFillManager.fillReport(reportName + ".jasper", null);
                ByteArrayOutputStream  pdfStream = new ByteArrayOutputStream();
                // exports report to pdf
                JRExporter exporter = new JRPdfExporter();
                exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
                // exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, new FileOutputStream(reportName + ".pdf")); // your output goes here
                exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, pdfStream); // your output goes here
                exporter.exportReport();
            } catch (Exception e) {
                render('something when wrong')
                throw new RuntimeException("It's not possible to generate the pdf report.", e); 
            } finally {
                render(file: pdfStream.toByteArray(), contentType: 'application/pdf')
            }
        }
    }