前言:
jasperReport(4.5最新版,下面用ireport代替)大家都很熟悉,但是打印用到jatoolsPrinter的,应该不多吧、这里介绍下struts2的ireport插件,以及jatoolsPrinter打印。
1、首先得准备支持ireport的几个常用包,根据ireport版本的不同,包的新旧也不同,我用的ireport最新版的,所以用到的包也得是最新的,下面还会列出我遇到的包的问题;
a>groovy-all-1.7.5.jar
b>iText-2.1.0.jar[生成pdf文档用]
c>iTextAsian.jar[语言支持]
d>jasperreport_4.5.0.jar[必备包]
e>poi-3.7.jar[导出excel时候用]
f>commons-collections-3.2.jar
g>commons-beanutils-1.7.1.jar
h>commons-digester-1.7.jar
i>org-netbeans-core.jar[可有可无,当你对报表进行样式处理时候(styles)会用到,比如:奇偶换色等]
jasper和struts2所需要的包:
列举几个包的问题:
Ⅰ、导出excel时候报错:
org.apache.jasper.JasperException: javax.servlet.ServletException: java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFSheet.setRightToLeft(Z)V
解决方法:你使用的poi-xxx.jar版本过低,换个高版本的jar包即可。
Ⅱ、生成PDF格式文档时候报错:
java.lang.NoSuchMethodError: com.lowagie.text.pdf.PdfWriter.setRgbTransparencyBlending(Z)V
解决方法:iText.jar文件过旧,将之改为2.1.X就可以了。
Ⅲ、使用ireport时候报错:
java.lang.NoClassDefFoundError: org/codehaus/groovy/control/CompilationFailedException
解决方法:添加groovy-all-1.7.5.jar。ps:像这样的错误(java.lang.NoClassDefFoundError)最好解决,一看就是少了Jar包,找到添加上就OK了。
Ⅳ、使用ireport时候报错:
net.sf.jasperreports.engine.JRRuntimeException: Unknown hyperlink target 0
解决方法:版本不搭配的问题,可能会是当前使用的iRrport 的版本高于操作时的包的版本。
Ⅴ、在使用PDF格式预览的时候报错:
net.sf.jasperreports.engine.JRRuntimeException: Could not load the following font :
pdfFontName : STSong-Light
pdfEncoding : UniGB-UCS2-H
isPdfEmbedded : false
解决办法:添加语言包支持,iTextAsian.jar。ps:这里需要注意,有中文字的field,如果想在PDF格式文档中正常显示,一定需要设置其两个属性pdfFontName和pdfEncoding为STSong-Light,UniGB-UCS2-H;否则不显示。
2、和struts2结合,肯定得需要一个插件包struts2-jasperreports-plugin-2.0.11.2.jar,这里需要注意它里面的struts-plugin.xml文件中的包并没有继承自struts-default,需要把它拿出来改一下
<package name="jasperreports-default" extends="struts-default">
定义Result类型为jasper时,需要指定三个参数:
1、location:指定.jasper文件的位置.
2、format:指定生成的报表文件的格式,如果不指定,默认生成PDF文件(XLS:excel格式,HTML:html格式,CSV,XML,。。。).
3、dataSource:指定一个集合属性名,JasperReports报表将自动迭代输出该集合中的数据。
项目中,我对该插件进行了改进和升级。如果按照原插件的原理,我每次都需要查询得到一个结果集,传递给ireport进行显示。既然ireport设计器可以直接连接JDBC数据源查询数据,我们何不把查询结果集的事情也交给ireport来做呢。
于是修改插件源代码,思路如下:
1、首先需要给ireport提供一个数据源(c3p0或者dbcp),使其能够进行数据库操作【属性名:connection】。
2、再提供一个Map格式数据,向ireport传递参数【属性名:reportParameters】。
3、还有两个参数location和format,以及dataSource。
核心代码修改如下:
1.//定义两个变量,传递参数和数据源连接。 2.protected String reportParameters; 3.protected String connection; 4. 5.ValueStack stack = invocation.getStack(); 6.//先从stack获取数据源,如果为null,判断其是否为JRDataSource,若是转换成JRDataSource,否则,再采用ValueStackDataSource方式赋值给JRDataSource接口 7.Connection conn = (Connection) stack.findValue(connection); //获取提供的数据源 8.if (conn == null){ 9.Object obj = stack.findValue(dataSource); 10.if(obj instanceof JRDataSource) { 11. jrDataSource = (JRDataSource) obj; 12.}else { 13. jrDataSource = new ValueStackDataSource(stack, dataSource); 14.} 15.} 16.... 17.ServletContext servletContext = (ServletContext) invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONTEXT); 18.String systemId = servletContext.getRealPath(finalLocation); 19.File directory = new File(systemId.substring(0, systemId.lastIndexOf(File.separator))); 20.Map parameters = new ValueStackShadowMap(stack); 21.parameters.put("reportDirectory", directory); 22.parameters.put(JRParameter.REPORT_LOCALE, invocation.getInvocationContext().getLocale()); 23.//获取向ireport传递的参数 24.Map reportParams = (Map) stack.findValue(reportParameters); 25.if (reportParams != null) { 26. parameters.putAll(reportParams); 27.} 28...... 29.if (conn == null){ 30. jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, jrDataSource); 31.}else{ 32. jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn); 33.} 34. 35.然后写一个公用的Action,代码如下: 36./** 37. * @author aokunsang 38. * @date 2012-1-20 39. */ 40.@Component("jasperReportAction") 41.@Scope("prototype") 42.public class JasperReportAction extends ActionSupport { 43. 44. private List<?> list; //相当于dataSource,集合属性,查询的结果集[如果想使用list,则connection一定为null,否则没用] 45. private Connection connection; //数据源连接 46. @Resource(name="dataSource") 47. private PooledDataSource dataSource; //数据源 48. private Map<String,?> para; //传递的参数 49. 50. public String execute() throws Exception { 51. this.connection = dataSource.getConnection(); 52. if(connection != null ){ 53. this.list = null ; 54. } 55. return SUCCESS; 56. } 57. setter和getter.... 58.}
1.<package name="aa" extends="struts-default"> 2.<!-- 设置JasperReport的type类型 --> 3.<result-types> 4. <result-type name="jasper" class="xxx.report.JasperReportsResult"/> 5.</result-types> 6.<!-- 报表输出Action --> 7.<action name="JR_*_*" class="jasperReportAction"> 8. <result name="success" type="jasper"> 9. <param name="location">/reports/{1}.jasper</param> 10. <param name="connection">connection</param> 11. <param name="format">{2}</param> 12. <param name="reportParameters">para</param> 13. <!--<param name="dataSource">list</param>--> <!-- 注意:connection和dataSource不能共存。两个共存时,优先级是connection高。 --> 14. </result> 15.</action> 16.</package>
Okay,到这里ireport和struts2的结合就完成了,其难点就在于插件中对数据源的修改,接下来说说jatoolsPrinter打印。Okay,到这里ireport和struts2的结合就完成了,其难点就在于插件中对数据源的修改,接下来说说jatoolsPrinter打印。Okay,到这里ireport和struts2的结合就完成了,其难点就在于插件中对数据源的修改,接下来说说jatoolsPrinter打印。Okay,到这里ireport和struts2的结合就完成了,其难点就在于插件中对数据源的修改,接下来说说jatoolsPrinter打印。Okay,到这里ireport和struts2的结合就完成了,其难点就在于插件中对数据源的修改,接下来说说jatoolsPrinter打印。