最近机缘巧合,霉运当头,糊里糊涂答应别人做一个简单的报表,结果是焦头烂额,缺觉少睡。。。。。。只怪以前结合struts、JasperReport做过报表,而最近看了几天Spring,技痒难耐。唉,长叹一声先,然后做点痛定思痛的安慰性的总结(或许我该先去提高智商)。
嘿嘿,人类总是喜欢炫耀嘛,所以先说我的JasperReport在Spring上应用的方法,其次呢,说一下和普通的web应用的不同(包括struts),最后呢,当然是去补觉了(想看我家丑的朋友,不要太失望啊),吼吼!!
我们知道,Spring内置了对多种输出格式的支持,如pdf,xls等,而报表通常也要求生产多种格式,那么他们结合,岂不是天造地设、王八绿豆??反正我这么认为。
由于每种格式的方法差不多,下面我只说pdf的过程。
开发web应用,当然是先要有个web.xml嘛,这里定义Spring的入口org.springframework.web.servlet.DispatcherServlet
<servlet>
<servlet-name>testReport</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
然后设定它处理的范围
<servlet-mapping>
<servlet-name>countries</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>countries</servlet-name>
<url-pattern>*.pdf</url-pattern>
</servlet-mapping>
这里的*.pdf是不能少的。如果想先提交到 XXX.htm,然后返回pdf,就会提示下载XXX.htm。
Spring对pdf的支持是通过AbstractPdfView,用户要继承这个类自己写pdf的内容,但JasperReport已经有生成pdf的功能了,而我们想要的,只是借助它的MVC框架,在需要时,返回给客户想要的pdf页面,所以,我们直接继承AbstractView(下边是一个通用程序具体代码)
public class IamPdfView extends AbstractView {
private Log logger = LogFactory.getLog(this.getClass());
public IamPdfView() {
setContentType("application/pdf");
}
/*
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map,
* javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
protected void renderMergedOutputModel(Map model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
JReportParam jReportParam = (JReportParam)model.get("jReportParam");
byte[] bytes = null;
try {
bytes = JasperRunManager.runReportToPdf(jReportParam
.getJasperFilePath(), jReportParam.getParameters(),
jReportParam.getDataSet());
} catch (JRException e) {
logger.info("zzzzzzzzzzzzzzzzz!IamPdfView Exception e:" + e);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(bytes);
response.setContentLength(baos.size());
response.setContentType(getContentType());
ServletOutputStream out = response.getOutputStream();
baos.writeTo(out);
out.flush();
out.close();
}
}
其中 JReportParam 是对报表参数的一个简单封装。
Spring提供了很多viewResolver,我选用的是org.springframework.web.servlet.view.ResourceBundleViewResolver,因为可以将页面相关信息写作配置文件中,如
pdfView.class=com.iam.testreport.report.view.IamPdfView
这样,当 return new ModelAndView("pdfView"...)时,就可以调用com.iam.testreport.report.view.IamPdfView了。
下面说一下和普通的web应用的不同(包括struts),其实就一点,就是Spring比他们多了viewResolver,而它的DEFAULT_CONTENT_TYPE = "text/html; charset=ISO-8859-1";所以我们需要扩展AbstractView或影射报表servlet为 name.pdf(这种方法不用扩展Spring的特有类)。