java PrimeFaces 和 JasperReports
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5115176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PrimeFaces and JasperReports
提问by Mythox
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.
我正在尝试开发一个用于报告的 Web 应用程序,并且已经使用 EJB3 + primefaces 构建了一个站点。现在我很头疼如何将 Jasperreport 集成到 primefaces ......我没有找到关于这个主题的指南或讨论,我想知道这是不可能的吗?或者实际上这不是正确的做法?其实我对JavaEE6的开发还是很陌生的,暂时不打算用spring和seam这样的框架。
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)
视图 (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
单击JSF的按钮时发生错误,下面的日志来自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.....
回答by wrschneider
Have you tried using the p:fileDownload component inside your commandLink?
您是否尝试过在 commandLink 中使用 p:fileDownload 组件?
See: http://www.primefaces.org/showcase/ui/fileDownload.jsf
请参阅: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).
那样的话,你就不用处理 responseComplete 或创建一个单独的 servlet,你只需有另一个控制器/托管 bean 方法,它返回一个 StreamedContent(primefaces 类)的实例。
回答by Aaron
You are modifying the response after "responseComplete()". Calling "responseComplete()" should be the last thing you do.
您正在修改“responseComplete()”之后的响应。调用“responseComplete()”应该是你做的最后一件事。
回答by DanielK
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.
处理 jasper-methods 的最佳方法是在commandButton
/ 中禁用 ajax commandLink
。这就是如何继续使用 Jasper 转换。
<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.
p:fileDownload
如果不需要,则无需严格遵守 -元素。
回答by SDReyes
Probably this line is causing the issue:
可能这一行导致了问题:
InputStream reportStream = ctx.getExternalContext() .getResourceAsStream("reports/report1.jasper");
InputStream reportStream = ctx.getExternalContext() .getResourceAsStream("reports/report1.jasper");
See this question
看到这个问题