PrimeFaces and JasperReports

14,493

Solution 1

Have you tried using the p:fileDownload component inside your commandLink?

See: http://www.primefaces.org/showcase/ui/fileDownload.jsf

That way, instead of messing around with responseComplete or having to make a separate servlet, you just have another controller/managed bean method that returns an instance of StreamedContent (primefaces class).

Solution 2

You are modifying the response after "responseComplete()". Calling "responseComplete()" should be the last thing you do.

Solution 3

Best way to deal with jasper-methods is to disable ajax in the commandButton/commandLink. Thats how it is possible to stay with the Jasper-conversion.

<p:commandButton title="EK Preview" icon="fa fa-file-pdf-o" actionListener="#{ctrlFiDoc.doReport_PC}" ajax="false"/>

There is no need to stay strictly to the p:fileDownload-element if its not necessary.

Share:
14,493
Mythox
Author by

Mythox

Updated on September 14, 2022

Comments

  • Mythox
    Mythox over 1 year

    i'm trying to develop a web app for reporting, and have built a site with EJB3 + primefaces already. Now i'm head aching how to integrate Jasperreport into primefaces... I found no guide or discussion about this topic, I wonder is it not possible? or actually it is not a right way to do? I'm actually quite new to develop JavaEE6, dont plan to use frameworks like spring and seam yet.


    model

    @Stateless
    @LocalBean
    public class BookEJB {
        // @Override
        public void printReport() throws ClassNotFoundException, IOException, JRException, SQLException {
            Connection connection;
            Map parameterMap = new HashMap();
    
            FacesContext ctx = FacesContext.getCurrentInstance();
    
            HttpServletResponse response = (HttpServletResponse) ctx
                    .getExternalContext().getResponse();
    
            InputStream reportStream = ctx.getExternalContext()
                    .getResourceAsStream("reports/report1.jasper");
    
            ServletOutputStream servletOutputStream = response.getOutputStream();
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost/bookdb?user=root&password=******");
    
            ctx.responseComplete();
            response.setContentType("application/pdf");
    
            JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parameterMap, connection);
    
            connection.close();
            servletOutputStream.flush();
            servletOutputStream.close();
    
        }
    }
    

    Controller

    @ManagedBean(name = "bookCtrl")
    @RequestScoped
    public class BookController {
    
        @EJB
        private BookEJB bookEJB;
    
        public void doPrintReport() throws ClassNotFoundException, IOException, JRException, SQLException {
            bookEJB.printReport();
        }
    }
    

    view (JSF)

    <body>
    <f:view>
        <h:outputText value="Click on the link below to generate the report." />
        <h:form>
            <h:commandButton action="#{bookCtrl.doPrintReport}" value="Generate Report" />
        </h:form>
    </f:view>
    </body>
    

    Jasper

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Created with Jaspersoft Studio -->
    <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report1" language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
        <property name="ireport.zoom" value="1.0"/>
        <property name="ireport.x" value="0"/>
        <property name="ireport.y" value="0"/>
        <queryString language="SQL">
            <![CDATA[SELECT
         *
    FROM
         `book` book]]>
        </queryString>
        <field name="Id" class="java.lang.Integer"/>
        <field name="title" class="java.lang.String"/>
        <field name="price" class="java.lang.String"/>
        <background>
            <band splitType="Stretch"/>
        </background>
        <title>
            <band height="45" splitType="Stretch"/>
        </title>
        <pageHeader>
            <band height="35" splitType="Stretch"/>
        </pageHeader>
        <columnHeader>
            <band height="21" splitType="Stretch">
                <staticText>
                    <reportElement x="0" y="0" width="100" height="20"/>
                    <textElement/>
                    <text><![CDATA[Id]]></text>
                </staticText>
                <staticText>
                    <reportElement x="100" y="0" width="100" height="20"/>
                    <textElement/>
                    <text><![CDATA[title]]></text>
                </staticText>
                <staticText>
                    <reportElement x="200" y="0" width="100" height="20"/>
                    <textElement/>
                    <text><![CDATA[price]]></text>
                </staticText>
            </band>
        </columnHeader>
        <detail>
            <band height="24" splitType="Stretch">
                <textField>
                    <reportElement x="0" y="0" width="100" height="20"/>
                    <textElement/>
                    <textFieldExpression class="java.lang.Integer"><![CDATA[$F{Id}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="100" y="0" width="100" height="20"/>
                    <textElement/>
                    <textFieldExpression class="java.lang.String"><![CDATA[$F{title}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="200" y="0" width="100" height="20"/>
                    <textElement/>
                    <textFieldExpression class="java.lang.String"><![CDATA[$F{price}]]></textFieldExpression>
                </textField>
            </band>
        </detail>
        <columnFooter>
            <band height="45" splitType="Stretch"/>
        </columnFooter>
        <pageFooter>
            <band height="54" splitType="Stretch"/>
        </pageFooter>
        <summary>
            <band height="42" splitType="Stretch"/>
        </summary>
    </jasperReport>
    

    The error occurred when I click the button of JSF, below log is from glassfish

    WARNING: A system exception occurred during an invocation on EJB BookEJB method public void blah.BookEJB.printReport() throws java.lang.ClassNotFoundException,java.io.IOException,net.sf.jasperreports.engine.JRException,java.sql.SQLException
    javax.ejb.EJBException.....
    
    SEVERE: javax.ejb.EJBException
    javax.faces.el.EvaluationException: javax.ejb.EJBException
        at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    
    WARNING: #{bookCtrl.doPrintReport}: javax.ejb.EJBException
    javax.faces.FacesException: #{bookCtrl.doPrintReport}: javax.ejb.EJBException...
    
    Caused by: javax.faces.el.EvaluationException: javax.ejb.EJBException...
    
    SEVERE: javax.faces.FacesException: #{bookCtrl.doPrintReport}: javax.ejb.EJBException...
    
    Caused by: javax.faces.FacesException: #{bookCtrl.doPrintReport}: javax.ejb.EJBException...
    
    Caused by: javax.faces.el.EvaluationException: javax.ejb.EJBException...
    
    Caused by: javax.ejb.EJBException...
    
    Caused by: java.lang.NullPointerException...
    
    WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
    java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response.....
    
    WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
    java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response.....
    
    WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
    java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response.....