PrimeFaces and JasperReports
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.
Mythox
Updated on September 14, 2022Comments
-
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.....