PrimeFaces and JasperReports
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}]]></textFieldExpre开发者_运维问答ssion>
</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.....
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).
You are modifying the response after "responseComplete()". Calling "responseComplete()" should be the last thing you do.
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.
Probably this line is causing the issue:
InputStream reportStream = ctx.getExternalContext() .getResourceAsStream("reports/report1.jasper");
See this question
精彩评论