一、Ireport中生成pdf中文字码显示,和自定义字体做法 ............................................... 3
1、自定义字体集(没成功,待研究) ......................................................................... 3 2、常规支持方案 ............................................................................................................. 4 二、使用jasperreports和irepoert生成的.jasper来实现pdf的生成 ................................. 4
1、字体在项目中的引入 ................................................................................................. 4 2、将自己制作做的静态报表在页面上用pdf的形式显示出来 .................................. 5 3、利用程序将.jrxml导出为.jasper文件并用PDF显示 .............................................. 5 小结:在前面我们使用的只是html中显示的静态的pdf,在大多数的情况下,打印的数据来自于一些变量 ................................................................................................... 6 三、填充报表数据 ................................................................................................................... 6
1、对参数进行填充打印到pdf到html ......................................................................... 6 2、对对象内部属性进行填充 ......................................................................................... 7 3、填充报表数据--使用JDBC向导作为数据源 ............................................................ 9 3.1 新建报表JDBC数据源 ............................................................................................. 9 3.2 新建报表模板文件 ................................................................................................. 11 四、报表的常用属性 ............................................................................................................. 15
4.1分列显示 ................................................................................................................... 15 4.2 Title和Summary在单独的页面打印 ................................................................... 16 4.3 报表的常用属性 ..................................................................................................... 17 4.4 Summary with Page Header and Footer属性 ........................................................ 17 4.5 Float column footer属性 ........................................................................................ 20 4.6 When No Data属性 .............................................................................................. 21
第二章 控件 ................................................................................................................................... 24
一、控件的常用知识 ............................................................................................................. 24 二、控件的对齐 ..................................................................................................................... 25
1. Align Top/Align Bottom/Align Left/Align Right的使用 ............................................... 26 2. Align Horizontal Axes和Align Vertical Axes的使用 .................................................. 27 3. Align To Top/Bottom/Left/Right Margin的使用 ......................................................... 27 4. Organize As Table的使用 ........................................................................................... 28 5. Join Left/Right的使用 ................................................................................................ 29 7. Same Width/Height(Min/Max)和Same Size的使用 ............................................ 33 8. Adapt to parent和Adapt to parent width/Height的使用 ........................................ 33 9. Center和Center Horizontally/Vertically的使用 ....................................................... 33 三、 控件的常用属性 ........................................................................................................... 33
3.1 Forecolor、Backcolor、Opaque属性 .................................................................... 33 3.2 Blank When Null属性(1) ................................................................................... 34 3.3 Position Type属性 .................................................................................................. 34 3.4 Stretch Type属性(重要) .................................................................................... 38 3.5、Stretch With Overflow ........................................................................................... 43 3.6 Print Repeated Values属性 .................................................................................... 43 3.7 Remove line when blank属性 ................................................................................ 44 3.8 Print When Detail Overflows属性 .......................................................................... 44 四、控件的使用方法 ............................................................................................................. 46
4.1 形状控件 ................................................................................................................. 46 4.2 Image控件(1) .................................................................................................... 47 4.3 Image控件的属性及应用效果 .............................................................................. 54 4.4、Image控件超链接设置 ......................................................................................... 60 4.4 文本控件(1) ....................................................................................................... 63
第5章 子报表Subreport ............................................................................................................ 64
5.1 子报表Subreport的示例--静态文本(1) .................................................................. 65
1. 创建主报表及子报表 ................................................................................................ 65 2. 两个.jrxml文件中的代码及编译 .............................................................................. 68 3. 在Web项目中使用两个.jrxml文件 ........................................................................ 70 5.2 子报表Subreport的示例--动态数据JDBC(1) ......................................................... 73
1. 创建userinfo数据表及内容 .................................................................................... 73 2. 创建主报表模板 ........................................................................................................ 73 3. 创建子报表模板 ........................................................................................................ 74 4. 在Web项目中预览 .................................................................................................. 79 5.3 子报表Subreport的示例--打印实体类中的List 1. 实体类的结构 ............................................................................................................ 82 2. 创建3个.jrxml报表模板文件.................................................................................. 83 3. 设计Servlet核心代码 .............................................................................................. 86 4. 运行效果 .................................................................................................................... 87 5.4 从Servlet传递一个Map类型的参数到子报表 .......................................................... 88 1. 创建Servlet代码 ...................................................................................................... 88 2. 在main.jrxml中添加两个Parameters参数对象 .................................................... 89 3. 在main.jrxml中显示showMainUsername参数值并添加Subreport控件 ........... 89 4. 设计sub.jrxml子报表模板 ....................................................................................... 90 5. 运行效果 .................................................................................................................... 91 5.5 对表达式进行计算后再传入子报表 ............................................................................. 91 5.6 对子报表传递List 1. 在Servlet对象中封装省市二级联动关系 ............................................................... 97 2. 添加Sheng.class、Shi.class及中文.jar文件路径 .................................................... 98 3. 逆向Sheng.java的属性 ............................................................................................ 98 4. 设计main.jrxml的报表模板 .................................................................................... 99 5. 显示省列表的运行效果 .......................................................................................... 100 6. 在main.jrxml中添加Subreport控件 .................................................................... 100 7. 设计sub.jrxml报表模板 ......................................................................................... 101 8. 省市一起显示的运行效果 ...................................................................................... 102 9. 统计每个省中市的数量 .......................................................................................... 102 10. 在main.jrxml中添加Variables变量并与子报表中的变量做关联映射 ............ 103 第一章 初识JasperReports 1.1 一、Ireport中生成pdf中文字码显示,和自定义字体做法 1、自定义字体集 将需要的字体.ttf文件打包,在ireport中引入jar包即可。 具体打包后的文件可以查看例子中的jasperreports-fonts-3.7.0.jar。打包方法如下,但是目前我试过打包的jar包在导出pdf是会出问题,等待解决。 注意一: 有一点不一样,它是将那个fonts文件夹打成jar包,而我是将整个文件夹引入的 注意二:ttf文件最好是不要有中文 注意三: 在字体加载 后他会在安装目录下的Jaspersoft\\iReport-5.6.0\\ireport\\fonts中添加ttf文件和更改配置信息,然后在工具-选项—classpath下面加入这个文件夹 所有要重新启动一次。在设置。 小结:现在在ireport中可以自定义字体,然后在预览和生成pdf中可以显示中文,找到字体。下一步就是使用生成的report1.jasper文件在IDE中来进行项目集成。 2、常规支持方案 最终解决方案:按照网上说的设置4个属性: Font Name: 宋体 (反正是支持中文显示的字体就可以) Pdf font name: STSong-Light; Pdf embedded:勾上(其实不打钩也可以) pdf enccoding: UniGB-UCS2-H (Chinese Simplified) 查看IReport 工具的输出信息(跟java的system.out.print出来的信息一个类型,查看的地方也差不多),发现有报一个错:....... Could not load the following font ... ... 这个是因为没有找到中文的jar包,这时如果你去网上辛辛苦苦找到IText的中文包的话,你会耗费大量时间,且不一定成功,其实,安装完IReport 后,它默认就有两个支持中文的IText包啦,的目录是: Jaspersoft\\iReport-4.5.1\\ireport\\modules\\ext 下的iText-2.1.7.jar 和 iTextAsian.jar 将那两个包导入到IReport的ClassPath里面(web项目中直接引入jar包),点击确定,然后再打开,在Font页签上面能够看得到这两个包,就说明成功啦,然后重启IReport 1.2 二、使用jasperreports和irepoert生成的.jasper来实现pdf的生成 1、字体在项目中的引入(目前自定义字体jar包未成功) 首先,选择你在使用ireport生成的.jasper选择的字体(自定义字体),现在需要把这个字体(.ttf文 件)拿出来放在项目中,具体的使用方法. 点击: 生成文件类型选择.jar或者.zip 名字fonts.jar这样将自己自定义且使用了的字体打成jar包,放在自己javaee使用的项目的lib中,把报表的.jasper也放在项目的响应位置,在程序中调用。 2、将自己制作做的静态报表在页面上用pdf的形式显示出来 .jrxml:是可视化编辑的xml文件; .jasper:经编译后生成的类文件,即报表模板文件。 然后使用jasperreport就可以了:一下是打印在页面用pdf显示的servlet核心方法。 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ServletOutputStream servletOutputStream=response.getOutputStream(); InputStream reportStream = getServletConfig().getServletContext() .getResourceAsStream(\"report1.jasper\"); JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream,new HashMap(), new JREmptyDataSource()); response.setContentType(\"application/pdf\"); servletOutputStream.flush(); servletOutputStream.close(); } 3、利用程序将.jrxml导出为.jasper文件并用PDF显示 前面的章节是直接在Web项目中使用.jasper文件,其实在软件项目开发时,.jrxml文件经常修改,而且.jrxml还要在项目中进行保留备份,所以较为流行的做法是在项目中使用.jrxml来生成.jasper文件,并用PDF文件显示出来 //获取当时要转为jasper文件的jrxml文件 { //D:\\apache-tomcat-6.0.41-windows-x64\\apache-tomcat-6.0.41\\webapps\estJasperreport\\jrx ml\\report1.jrxml String jrxmlSourcePath=this.getServletContext().getRealPath (\"/\")+ \"jrxml\\\\report1.jrxml\"; System.out.println(jrxmlSourcePath); String jrxmlDestSourcePath = this.getClass().getClassLoader().getResource(\"\").getPath().substring(1)+\"jasperreports/report1.jasper\"; ///D:/apache-tomcat-6.0.41-windows-x64/apache-tomcat-6.0.41/webapps/testJasperreport/WEB-INF/classes/ System.out.println( this.getClass().getClassLoader().getResource(\"\").getPath()); //此句是在jrxml来生成.jasper文件编译报表,完成对报表的编译工作 JasperCompileManager.compileReportToFile(jrxmlSourcePath,jrxmlDestSourcePath); InputStream isRef = new FileInputStream(new File(jrxmlDestSourcePath)); ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef,sosRef,new HashMap(), new JREmptyDataSource()); sosRef.flush(); sosRef.close(); 小结:在前面我们使用的只是html中显示的静态的pdf,在大多数的情况下,打印的数据来自于一些变量 1.3 三、填充报表数据 1、对参数进行填充打印到pdf到html 在JasperReports工具中传递数据并填充到报表只有两种方式,即使用Parameters参数和JRDataSource数据源,而 Parameters参数的使用方式就是从Servlet向报表传递参数,而JRDataSource数据源可以使用原始数据表中的数据在报表上进行显示 。 这两种方式都可以通过Servlet进行传递。 Static Text: 静态文字型态的文字类別,一般的整合开发工具或会称为标签(Label),就是固定不变的字串 Text Field: 文字栏位,为字串型态的文字类型,为合法的Java字串运算式,因此字串必須用双引号括住 刚开始使用时经常会搞错此二种形态,简单区分方法是: 在Static Text的输入视窗输入文字时不用加双引号(加了会出現在报表上) Text Field的文字要加双引号以符合Java语法 使用参数设置default value exception是使用java表达式来设置静态的值得。并且在使用Text Field的时候也必须对字体属性进行设置。和static text 一样的设置。 现在只是对一般的参数进行填充,一下通过javabean的方式来对对象属性进行填充。 2、填充报表数据--使用javabean作为数据源 首先在项目中新建要填充的JRBeanCollectionDataSource对象。Userinfo类 然后把Userinfo.class的路径配置到iReport软件中,将workplace中的classes包引 进来。 单击 按钮添加数据源,选择JavaBean,并且设置选项如图。 然后单击 选择 注意:在这里的javabean.UserInfo一定要和你项目中的类所在的路径一样,不然查询不到。 然后点击read attribute在将选中的加到Fields里面去,在左侧的Field中就可以看 见这些javabean的属性了。 然后在Field中将属性直接拖到detial中进行使用。注意这里使用Empty datasoource . 这个可以删除数据源,然后将生成的jasper放放到项目下面: try { List listUserinfo = new ArrayList(); for (int i = 0; i < 100; i++) { listUserinfo.add(new Userinfo(\"id\" + (i + 1), \"username\" + (i + 1), \"password\" + (i + 1))); } String jrxmlSourcePath = this.getServletContext().getRealPath(\"/\") + \"jrxml\\\\listUserinfo.jrxml\"; System.out.println(jrxmlSourcePath); String jrxmlDestSourcePath = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+\"jasperreports/listUserinfo.jasper\"; JasperCompileManager.compileReportToFile(jrxmlSourcePath, rxmlDestSourcePath); InputStream isRef = new FileInputStream(new File(jrxmlDestSourcePath)); ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef, sosRef, new HashMa p(), new JRBeanCollectionDataSource(listUserinfo)); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 这里使用的是将jrxml编译成jasper在填充然后print出来。注意,从parameters和Field两个对象拖出来的组件如果有参数值有中文也要在属性中将字体设置成自定义的值 小结:上边的数据也只是自己循环伪造的,我们一般情况下报表都是从数据库读出来的,所以小面我们使用jdbc查询出来的数据进行报表的填充。 3、填充报表数据--使用JDBC向导作为数据源 在iReport工具中可以直接连接数据表,把数据表中的数据显示出来。 3.1 新建报表JDBC数据源 单击\"新建报表数据源\"按钮,如图1.51所示。 弹出一个设置数据源类型的对话框,效果如图1.52所示。 选择Database JDBC connection以JDBC的方式连接数据源,单击Next按钮后输入连接MySQL数据库的相关参数,并且单击Test按钮来测试是否正确连接数据库,效果如图1.53所示。 连接成功后单击 按钮保存这个报表数据源,并且在连接资源中列出此选项,效果如图1.54所示。 数据库中的userinfo数据表内容如图1.55所示。 3.2 新建报表模板文件 选择\"文件\"→New命令,选中Report中的Blank A4报表纸张幅面,然后单击 按钮启动向导创建报表,设置此报表的名称及存储位置,如图1.56所示。 单击\"下一步\"按钮继续设置查询参数,效果如图1.57所示。 单击\"下一步\"按钮将所有的列作为报表的显示列,效果如图1.58所示。 单击\"下一步\"按钮继续配置分组,由于本示例并不分组,所以选择默认值即可,效果如图1.59所示。 单击\"下一步\"按钮确定是否修改配置,在此不修改,所以直接单击图1.60中的\"完成\"按钮。 3.2.1:建立好模板后通过html打印出pdf. Connection conn = DBUtil.getConnection(); ServletOutputStream servletOutputStream=response.getOutputStream(); InputStream reportStream = getServletConfig().getServletContext() .getResourceAsStream(\"report_jdbc.jasper\"); JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream,new HashMap(), conn); response.setContentType(\"application/pdf\"); servletOutputStream.flush(); servletOutputStream.close(); 需要打开数据库连接。上面是直接使用的jasper文件,而没有使用jrxml-jasper文件在进行写到html 3.2.2:建立好模板后生成各种文件,生成pdf 本示例要把.jasper文件导出到PDF文件,而不是像前面示例中使用IE显示PDF文件。在导出指定文件格式之前需要知道导出的一个大体过程,如图1.78所示。 导出的大体过程如下。 扩展名为.jrxml的文件为标准报表模板XML格式的文件,该文件定义了报表的格式和数据构成,可以使用iReport软件以可视化的方式生成并编辑.jrxml报表模板文件。 将创建出来的.jrxml模板文件经过JasperReports API编译后生成扩展名为.jasper的二进制文件。 可以调用JasperReports API针对.jasper文件进行数据和参数的填充,生成扩展名为.jrprint的文件。 再调用JasperReports API将.jrprint文件最终导出成PDF、Excel、HTML等各种格式的文件。 下面用代码的方式来演示上面4个步骤,首先新建一个.jrxml模板,最简单的.jrxml文件如图1.79所示。 其次要创建一个Servlet,核心代码如下 public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // (1)第1步取得jrxml文件路径 String jrxmlPath = this.getServletContext().getRealPath(\"/\"); jrxmlPathjrxmlPath = jrxmlPath + \"report2.jrxml\"; // (2)第2步编译成jasper JasperCompileManager.compileReportToFile(jrxmlPath, jrxmlPath + \"report2.jasper\"); // (3)第3步生成JasperPrint对象 JasperPrint jasperPrint = JasperFillManager.fillReport(jrxmlPath + \"report2.jasper\ // (4)第4步导出成PDF指定格式 JasperExportManager.exportReportToPdfFile(jasperPrint,\"c://demo.pdf\"); } catch (JRException e) { e.printStackTrace(); } } } 运行Servlet后在C盘出现demo.pdf文件,双击该文件将显示如图1.80所示的内容。 另外,导出指定文件格式的方式并不仅仅局限于上面固定的4个步骤,还可以使用下面的示例来进行导出PDF文件的操作。 使用jasper文件 String saveDiv = request.getRealPath(\"/\"); String fileName = saveDiv + \"report3.jasper\"; String outFileName = saveDiv + \"report3.pdf\"; HashMap hm = new HashMap(); JasperPrint print = JasperFillManager.fillReport(fileName, hm, new JREmptyDataSource()); JRExporter exporter=new net.sf.jasperreports.engine.export.JRPdfExporter(); exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,outFileName); exporter.setParameter(JRExporterParameter.JASPER_PRINT, print); exporter.exportReport(); 1.4 四、报表的常用属性 4.1分列显示 设置报表的列数为2,属性设置如图1.85所示。 双列的报表预览效果如图1.86所示。 4.2 Title和Summary在单独的页面打印 当然还可以将报表的Title和Summary设置在单独的页面打印,属性设置如图1.87所示。 重新对.jrxml进行界面布局,重新布局的Title示例如图1.88所示。 预览效果如图1.89所示,可以看到Title单独在第1页显示。 4.3 报表的常用属性 可以在\"属性\"面板中设置一些有关报表的属性,效果如图1.84所示。 图1.84 报表的属性 可以在此面板中设置报表的宽度、高度及打印的方向,还可以设置报表中列的数目、外边距等。其中最为重要的还是分列、分栏的显示,在默认的情况下是不分栏的,那分栏的效果,也就是多列的效果如何呢 4.4 Summary with Page Header and Footer属性 在第1.9.2小节中可以发现Summary是在报表的最后一页显示,其实还可以在最后一页将Page Header(页头)、Page Footer(页脚)和Summary(栏)设置在一起显示。 由于本示例要连接的是MySQL数据库,所以要在iReport中注册MySQL的JDBC驱动,如图1.94所示。 在默认的情况下Summary是最后一个打印的,设计的报表如图1.95所示。 在图1.95的右侧属性面板中,主要是勾选两个属性:Title on a new page、Summary on a new page。 运行报表后,报表最后一页的效果如图1.96所示。 在图1.96中仅打印了一个字符串 \"Summary band\",页头和页脚并没有打印,如果勾选属性Summary with Page Header and Footer,将是什么效果呢?效果如图1.97所示,可以看出最后一页显示出了3个元素,即页头、Summary和页脚。 而Summary Band也在最后一个单独的页面进行打印。 4.5 Float column footer属性 属性Float column footer的功能是:在最后一页,Column Foot(列脚)是否紧挨着最后一个Details Band。 设计的报表模板如图1.98所示。 在报表中不要添加任何的额外属性,运行效果如图1.99所示。 (点击查看大图)图1.99 不设置任何额外属性的报表运行效果 从图1.99中可以看到Column Foot显示在最下方,离Details 1还有一些距离,这时勾选Float column footer,如图1.100所示。 运行后的效果如图1.101所示,即列脚和Details 1紧挨着。 (点击查看大图)图1.101 列脚和Details 1紧挨着 4.6 When No Data属性 属性When No Data的作用是:当打印的报表数据源中没有数据的情况下,报表该如何处理的行为,一共有4种值:No Pages(不打印数据,因为返回数据的缓存为空,这是默认值),Blank Page(返回一个空白的页面),\"All Sections,No Details\"(打印除了Details之外的所有的段落),No Data section(把No Data的Band打印出来)。 设计报表的模板样式如图1.102所示。 当值设置为No Pages时打印的效果如图1.103所示。 当设置为Blank Page时,效果如图1.104所示。 当设置为\"All Sections,No Details\"时,效果如图1.105所示。 当设置为No Data section时,其功能是显示No Data这个Band,设计报表模板的样式如图1.106所示。 显示No Data段落的效果如图1.107所示。 第二章 控件 iReport中的控件主要包括:Line,Rectangle,Ellipse,Static Text,Text Field,Image,Frame,Subreport,Crosstab,Chart,Break。 其中,Static Text控件用于显示静态的文本字符,不可以添加Java的运算表达式。 1.5 一、控件的常用知识 Break控件用于强制分页,可以在Detail 1中设置如下结构的报表,在pdf中显示为多页分割开来。 将控件放入报表设计器时,在选中控件后可以按上下左右方向键来以1px级别进行控件的移动,还可以按下Shift键结合上下左右键进行每隔10px的移动。 为了对控件的位置进行整体风格对齐,建议勾选Show Grid和Snap To Grid菜单,这样可以实现报表设计器的表格显示,表格的边框其实就是对齐的参考线,并且可以将控件自动停靠到表格的参考线上,效果如图2.6所示。 参考线自动停靠的效果如图2.7所示。 当然,对齐控件的方式还可以使用标尺,效果如图2.8所示。 需要注意的是,标尺的功能和Snap To Grid是互斥的,同一时间只能使用一种。如果这两种功能都允许使用,则默认使用Snap To Grid功能。 另外,控件不能跨多个Band对象,如果这样操作,则在预览时会出现提示,效果如图2.9所示。 1.6 二、控件的对齐 在iReport中还可以使用\"窗口\"菜单中的Formating Tools面板来对控件进行对齐。 对齐的选项如图2.10所示。 1. Align Top/Align Bottom/Align Left/Align Right的使用 此种对齐方式是指:如果有多个控件被选中时这些控件的对齐方式。但在这里需要注意的是,有一个参考控件的概念,第1个被选中的控件就是参考控件,如图2.11所示。 在图2.11中执行的操作是利用鼠标选择B,然后按下Ctrl键再选中A和C,这时B第1个被选中,所以B是这3个控件的对齐参考控件,如果按下Align Left,这时的效果如图2.12所示。 其他的3个对齐方式这里不再赘述。 2. Align Horizontal Axes和Align Vertical Axes的使用 单词Axes是轴心、中轴线的意思,那么这种效果就是指将控件的高度除以2即为中轴,也可以将宽度除以2,布局控件的位置如图2.13所示。 单击Align Vertical Axes控件,意思是将这3个控件的垂直对齐方式设置为中轴线对齐,单击后的效果如图2.14所示。 3. Align To Top/Bottom/Left/Right Margin的使用 Align To Top/Bottom/Left/Right Margin的功能是:定义控件以报表边距为对齐方式。设置的报表模板内容如图2.15所示。 单击Align To Left Margin按钮,以报表的左边界为参考进行对齐,单击后的效果如图2.16所示。 4. Organize As Table的使用 Organize As Table按钮的功能是:可以使多个被选中的控件在当前的Band上方进行Top对齐,它经常用在将当前要打印的数据列进行自动停靠并且间距相同的情况下。布局报表模板的界面效果如图2.17所示。 单击Organize As Table按钮后布局将更改成如图2.18所示效果,即自动停靠在当前Band的上方,并且间距相同。 5. Join Left/Right的使用 Join Left/Right按钮的功能是:设置多个控件首尾垂直相接的效果,报表模板的设计如图2.19所示。 单击Join Left按钮,A、B和C就首尾垂直相接了,效果如图2.20所示。 6. Equal/Increase/Decrease/Remove Horiz/Vert. Space的使用 8个间距设置按钮(如图2.21所示)的功能是:设置多个控件之间的间距。 单词Horiz表示水平方向,而Vert表示垂直方向。Equal用于使控件之间的距离相同,Increase用于增加控件的间距,Decrease用于减小控件之间的间距,而Remove用于删除控件之间的距离。 初步设计的报表模板界面如图2.22所示。 单击Equal Horiz. Space按钮使这些控件之间的距离相同,效果如图2.23所示。 继续单击Increase Horiz. Space按钮增加各个控件的间距,它们的间距永远保持相同,效果如图2.24所示。 单击Decrease Horiz. Space按钮减小间距,效果如图2.25所示。 还可以删除间距,即单击Remove Horiz. Space按钮,效果如图2.26所示。 上面的示例是在水平方向上进行演示,垂直的效果相似,这里不再赘述。 7. Same Width/Height(Min/Max)和Same Size的使用 Same Width/Heigth(Min/Max)按钮的功能是:设置控件相同的高度/宽度(取决于最大/小控件的高度/宽度),这4个按钮不涉及参考控件,只获取最大宽度或最小宽度的值。 而Same Width和Same Height按钮的设置高度/宽度值要从参考控件中获得。当然还可以使用Same Size一起设置所有控件的高度和宽度,这些控件取得的值也要来自于参考控件。 7个设置宽度和高度的按钮如图2.27所示。 8. Adapt to parent和Adapt to parent width/Height的使用 这3个按钮的主要功能是:设置按钮的高度和宽度与父控件相同,使用起来非常简单,有些类似于填充的效果。 9. Center和Center Horizontally/Vertically的使用 这3个按钮的主要功能是:设置子控件在父控件中的位置,前面的章节已使用过,这里不再赘述。 1.7 三、 控件的常用属性 3.1 Forecolor、Backcolor、Opaque属性 在这里可以设置控件的外观颜色,主要使用3个属性:Forecolor用于设置文字颜色;Backcolor用于设置背景颜色;Opaque用于设置是否透明。例如,设置控件文字颜色为粉色、背景为绿色,如图2.28所示。 其中比较重要的是Opaque(不透明属性),勾选该选项表示控件的背景不透明,这时即可将背景颜色显示出来了。 3.2 Blank When Null属性(1) Text Field控件还有一个比较重要的属性,即Blank When Null,它的功能是:设置当Parameters参数值为Null时的处理方式。 3.3 Position Type属性 属性Position Type的功能很重要,因为连接数据源后在Band中显示数据时,数据量的多少不固定,也就是Band的高度一直在变化,但又想在报表中显示一些附加的元素,这时这个元素的位置就可以使用此属性进行定义。 向MySQL数据表中添加数据,共两条记录,其中第2条记录中的password字段内容文本较多,字段类型为longtext。 设计报表模板,内容如图2.35所示。 由于第2条记录的password字段较多,所以勾选password控件的属性 ,即Text Field控件 的高度随着文本的多少而自动伸展。 Position Type的值为Fix Relative to Top 从图中可以看到,有一条水平线,这条水平线与username和password控件在垂直和水平方向上并没有交错,现在想实现的效果是:这条水平 线一直保持与Detail 1的Top距离,设置Position Type的值为Fix Relative to Top,它也是此属性的默认值,即在报表运行时,向username和password填充数据时,Band的高度随着文本的多少在不断变化,而此水平线 一直保持在设计报表时与Detail 1的Top距离,运行效果如图2.36所示。 Fix Relative to Bottom 现在如果想把此水平线放在每一数据行的最后作为分割线,此时可以设置属性值为Fix Relative to Bottom,运行效果如图2.37所示。 再来查看如图2.38所示的效果。 从图2.38中可以看到,属性设置为Fix Relative to Bottom值的效果是在打印当前行的Band最后进行打印,如果线的宽度加宽,完全可以实现行分割的效果。 经过上面的两个实验已经知道如何在Band高度变化时设置此水平线控件的绝对定位问题。 继续设计报表模板,内容如图2.39所示。 在如图2.39所示的效果中可以看到$F{password}和水平线的垂直距离没超过5px,这时水平线是打印在当前页的底部。 Position Type属性值设置为Float 将水平线控件的Position Type属性值设置为Float(浮动),模板运行效果的第1页如图2.40所示。 从图2.40中可以看到,水平线真的是\"Float(浮动)\"了,被放在了第1页的最后,由于password字段显示出来的数据过多,而又设置水 平线的属性值为Float,所以password值把水平线\"压\"到第1页的结尾,水平线移动了,也就实现了Float(浮动)的效果。 模板运行效果的第2页如图2.41所示。 从以上两幅图中可以看到,设置为Float属性后,当Band的高度在一页中放不下时,水平线被放置在Band打印的第1页的最后位置进行显示(前 提是password控件和水平线的垂直距离要超过5px),所以Float使用的情况比较少,而Fix Relative to Bottom属性值经常用在此Band打印完毕后添加一个水平分割线时使用。 上面的示例是在报表中连接MySQL数据源,其实iReport还可以连接SQL Server数据源,在SQL Server中创建的数据表结构如图2.42所示。 3.4 Stretch Type属性(重要) 此属性的功能是:定义当Band高度变化时,其中的控件高度是如何计算的,初始报表界面的设计如图2.50所示。 1. No stretch 在初始报表界面中垂直线的Stretch Type值为默认的No stretch,在这里需要留意的是,垂直线并不是与Detail 1的Band同高,之间还有1px的距离,垂直线与1px比较的放大效果如图2.51所示。 运行效果如图2.52所示。 2. Relative to Band Height 从图2.52中可以看到,垂直线的高度不随着Band高度的加大而加大,更改垂直线的属性为 ,此属性值的含义是:控件的高度随着Band的高度而按比例变化,但其与底线的距离始终保持不变,在后面的示例中将利用1px像素来演示这个距离保持不变 的效果,但测试的运行效果如图2.53所示。 从图2.53中可以看到Band高度变化后垂直线的高度也随着发生了变化,并且距离底线永远有距离,这点可以从PDF文件的放大效果中查看到,如图2.54所示。 但垂直线仅仅出现在当前页中,因为第2页并没有垂直线了,想要实现第2页继续出现垂直线的效果,将在后面的章节中介绍,此处不再赘述。 属性值为Relative to Band Height时第2页不打印垂直线,如图2.55所示。 至此已经将属性值Relative to Band Height进行了效果演示,此值的主要功能是设置控件的高度按比例与Band的高度进行变化。 3、Relative to Tallest Object 属性值的功能非常重要,例如有如下的报表模板,设置4条垂直线的属性如图2.56所示。 设置两个Text Field控件的属性,如图2.57所示。 第1次的运行效果如图2.58所示。 如果想要实现垂直线和内容一样高呢?继续设置4条垂直线Stretch Type的值为Relative to Band Height,如图2.59所示。 运行效果如图2.60所示,可以看到左部分实现了设想效果,右部分的效果是错误的。 在图2.60中可以看到右边的两条垂直线不应该和左边的垂直线一样高,这是Relative to Band Height值的实现效果,将4条线和Band的高度设置为按比例自增,如果不想右边的垂直线根据Band的高度来进行自增,而是根据右边Text Field控件的高度而自增,应该怎么实现呢? 在左侧操作栏位中对两个竖线进行分组。。使用的是新标签 在上面的代码中使用了新的标签 设置垂直线的属性值为Relative to Tallest Object的作用是使垂直线的高度随着本组内最高的控件高度而进行变化。 程序运行效果如图2.63所示。 3.5、Stretch With Overflow 这个属性表明当组件内内容超过时候,换行显示,如texxt field里面的内容如果这个属性不设置为true的话,那么超过的部分是不会显示出来的。 3.6 Print Repeated Values属性 在MySQL中创建数据表结构及数据内容,userinfo表中的数据如图2.64所示。 报表模板的默认设置如图2.65所示。 默认模板的运行效果如图2.66所示。 可以发现password有aa值重复的问题,如果有重复值可以设置为不打印,即改变password控件的属性设置,取消勾选Print Repeated Values,如图2.67所示。 取消勾选的属性值运行效果如图2.68所示。 3.7 Remove line when blank属性 在图2.72中可以看到打印了一个空行,并且第2行和第3行之间有间距,如果想把空行删除并且去掉行距怎么办?很简单,使用Remove line when blank属性即可实现。 3.8 Print When Detail Overflows属性 在前面报表模板的基础上,在Band内部的右边添加一条垂直的线,并且设置此垂直线的属性Stretch Type为Relative to Band Heigth,也就是Band多高,此垂直线就为多高,设置垂直线的属性如图2.82所示。 此报表运行后,在字段较多的页面的打印效果如图2.83所示。 通过图2.83可以看到垂直线正确打印出来了,但在第4页却没有输出垂直线,效果如图2.84所示。 那么,如果想在这种情况下在第4页依然能够看到垂直线,该如何设置呢?重新对垂直线进行属性设置,勾选Print When Detail Overflows,如图2.85所示。 再次运行报表,在第4页终于又出现垂直线了,效果如图2.86所示。 1.8 四、控件的使用方法 iReport工具中有很多常用的控件,下面将为大家进行详细介绍。 4.1 形状控件 图形控件用于显示一些图形数据,如直线、矩形、椭圆形等,这些控件有一个比较重要的特点就是不能显示数据源中的数据,它们仅仅是用于设计报表的附属工具,从而使设计的报表更加美观、大方、得体。 图形控件包含Lines线、Rectangles矩形和Ellipses椭圆形,它们都可以设置边框的样式,以及填充的内容。 1. Lines 针对Lines控件,可以设置线的形状,如虚线还是实线,通过Pen属性来设置外观,设置Lines为虚线的界面如图2.87所示。 单击Pen属性右边的 按钮还可以定义线的颜色,设置线的颜色及样式的对话框如图2.88所示。 还可以在图2.88中设置线的宽度。 2. Rectangles Rectangles(矩形)控件的边框线外观同样也可以这样设置,设置界面如图2.89所示。 还可以通过设置Backcolor属性来改变矩形内部的填充颜色。 3. Ellipses Ellipses(椭圆形)控件也可以这样设置,效果如图2.90所示。 4.2 Image控件(1) 利用鼠标选中Image控件,如图2.91所示。 然后拖曳到报表模板的Detail 1中,这时弹出Image控件要关联一个真正的图片文件选择对话框,选中PNG图片,如图2.92所示。 选中要显示的图片后,如图2.93所示,可以看到在Image控件中显示出了PNG图片。 选中Image控件后需要留意右边的Image Expression属性,此时的值为:\"C:\\\\Documents and Settings\\\\ghy\\\\桌面\\\\mypng\\\\ghy.png\",说明此Image控件使用的是绝对路径,注意文件夹的\"\\\"要转义变成\"\\\\\"。 需要说明的是Image Expression属性共支持6种值类型,详细说明如表2.1所示。 表2.1 6种值类型 类型 具体值的写法 (1)c:\\\\abc\\\\ghy.jpg,此种写法不建议使用, 因为使用绝对路径不便于项目的移植,在大 多数的情况下不同计算机的图片存储路径都不 同,如果使用绝对路径将会造成非常大的麻烦, 即找不到图片的情况,那如何解决呢? java.lang.String 建议使用如下参数式的写法:$P {MY_IMAGES_DIRECTORY} + \"myImage.png\", 也就是将路径写成一个参数,或者完全可以将路 径和图片名作为一个参数从Servlet传递过来, 写法为$P{ ImagePath} (2)com/gaohongyan/www/ghy.png (3)http://localhost:8080/reportShow/ghy.png java.io.File java.net.URL 可以使用Java代码来加载图片: “new java.io.File(\"c:\\\\ghy.jpg\")” 可以使用代码访问远程URL中的图 片资源:“new java.net.URL(\"http:// 127.0.0.1/test.jpg\")” 报表的数据来源可以是InputStream,写法如 java.io.InputStream 下:“$P{imageParameter}”,表示来源是名称 为imageParameter的参数,但该参数的数据类型 是InputStream中得到图片的资源 java.awt.Image 图片来自于java.awt.Image对象 图片来自于net.sf.jasperreports.engine.JRRenderable JRRenderable 接口,使用此接口的目的是程序员自己实现绘 制图形的代码,但由于在使用率上较少,所以 具体使用方法请参考官方文档 4.2.1 分别介绍前5种写法的具体使用。 1. java.lang.String 在报表模板中设计Image控件的Image Expression属性值为如下XML代码: 上面的两种写法很明显是要报表运行在Web项目中,并且其中一个Image控件要从src资源路径的包中取得PNG图片资源,java.lang.String示例的项目结构如图2.94所示。 名称为test的Servlet核心代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ServletOutputStream servletOutputStream = response.getOutputStream(); InputStream reportStream = getServletConfig().getServletContext() .getResourceAsStream(\"report1.jasper\"); JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream,new HashMap(), new JREmptyDataSource()); response.setContentType(\"application/pdf\"); servletOutputStream.flush(); servletOutputStream.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } java.lang.String的运行效果如图2.95所示。 2. java.io.File 在报表模板中设计Image属性的XML代码如下: java.io.File的运行效果如图2.96所示。 3. java.net.URL 在报表模板中设计Image属性的XML代码如下: 报表运行后的效果如图2.97所示。 4. java.io.InputStream 在报表中添加一个名称为 的参数,它的数据类型设置如图2.98所示。 从图2.98中可以看到,参数的Parameter Class数据类型被设置为java.io.InputStream类。继续设置Image控件的属性,如图2.99所示。 属性Image Expression的值为$P{imageParameter},意思是从参数imageParameter取得InputStream图片输入流,然后以图片方式显示出来。 核心的Servlet代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ServletOutputStream servletOutputStream = response.getOutputStream(); InputStream reportStream = getServletConfig().getServletContext() .getResourceAsStream(\"report1.jasper\"); InputStream isRef = request.getSession().getServletContext() .getResourceAsStream(\"/ghy.png\"); HashMap paramHashMap = new HashMap(); paramHashMap.put(\"imageParameter\ JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, paramHashMap, new JREmptyDataSource()); response.setContentType(\"application/pdf\"); servletOutputStream.flush(); servletOutputStream.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } InputStream输入流显示成图片后的效果如图2.100所示。 5. java.awt.Image 通过使用java.awt.Image对象可以自定义打印的内容,但在本示例中还是使用PNG图片资源转成Image对象的方法来打印图形。 在报表中添加参数 ,并且设置该参数的属性,如图2.101所示。 设置Image控件的属性,如图2.102所示。 服务器端的Servlet核心代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ServletOutputStream servletOutputStream = response.getOutputStream(); InputStream reportStream = getServletConfig().getServletContext() .getResourceAsStream(\"report1.jasper\"); InputStream isRef = request.getSession().getServletContext() .getResourceAsStream(\"/ghyxyz.png\"); Image imageRef = ImageIO.read(isRef); HashMap paramHashMap = new HashMap(); paramHashMap.put(\"imageObjectParameter\ JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, paramHashMap, new JREmptyDataSource()); response.setContentType(\"application/pdf\"); servletOutputStream.flush(); servletOutputStream.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 打印图片来源为Image对象的效果如图2.103所示。 4.3 Image控件的属性及应用效果 控件有很多自己独有的属性,Image控件的属性列表如图2.104所示。 下面将为大家详细介绍主要属性的功能。 1. Scale Image属性 Scale Image属性的作用主要是设置图片的缩放方式,具有如下选项可供选择,如图2.105所示。 本示例为控件Image提供的图片资源如图2.106所示。 图2.106中的图片资源尺寸很大,图片尺寸如图2.107所示。 (1)Clip Clip的作用是图片的尺寸不可更改,属性值Clip的预览效果如图2.108所示。 (2)Fill Frame Fill Frame的作用是图片显示的大小随着Image控件而改变,容易使图片产生变形,属性值Fill Frame的预览效果如图2.109所示。 (3)Retain Shape Retain Shape的作用是图片显示的大小随着Image控件而改变,但一直是保持图片的等比属性,属性值Retain Shape的预览效果如图2.110所示。 (4)Real size Real size的作用是打印图片真正的尺寸,如果Image控件的宽和高小于图片的宽和高,则Image控件的宽和高将被自动拉伸,拉伸后Image控件的宽和高与图片的宽和高相同。 (5)Real height Real height的作用是保持Image控件的宽度,并在Image控件中打印图片真正的高度。 例如,素材图片如图2.111所示。 在报表模板中分别添加两个Image控件,并且设置左边Image控件的属性值为Real size,右边Image控件的属性值为Real height,布局效果如图2.112所示。 运行效果如图2.113所示。 从图2.113中可以看到使用Real size的Image背景并没有打印出来,实现了Image控件的高和宽与图片素材的高和宽相同。 而设置为Real height属性值的Image控件打印出了背景,即保持了Image控件的宽度,打印了图片真正的高度,Image控件的高度被自动扩展了。 2. Expression Class属性 属性Expression Class定义了Image Expression属性值使用的数据类型,取值类型如图2.114所示。 3. On Error Type属性 属性On Error Type的功能是当图片加载失败时的解决策略,可选择的值如图2.115所示。 其中Error是指图片加载失败时报出Java的异常,Blank代表出现空的打印空间,Icon代表将默认的图标显示出来。 4. Vertical Alignment和Horizontal Alignment属性 这两个属性用于定义图片在Image控件中的对齐位置。 5. 设置Image的边框及超链接 可以选中Image控件单击鼠标右键,在弹出的快捷菜单中选择Padding And Borders命令,如 图2.116所示,可以用于设置内填充、边框样式、超链接等。 设置边框和内填充的对话框如图2.117所示。 设置图片的超链接也很简单,如图2.118所示。 程序运行后的效果(运行效果)如图2.119所示。 在图2.118中属性Hyperlink type比较重要,它的取值范围如图2.120所示。 4.4、Image控件超链接设置 (1)Reference 通常情况下它是URL的唯一标识,前面的示例就是使用此属性值定义了一个链接,并且关联到http://www.baidu.com,而且还定义了一个名称为\"高洪岩去百度\"的Anchor。 (2)LocalAnchor 定位到本地的一个Anchor对象,前面已经有了一个名称为\"高洪岩去百度\"的Anchor,本示例要设置一个文本链接,单击链接后定位到\"高洪岩去百度\"这个Anchor,添加一个Text Field控件,并设置两个本地Anchor彼此切换,如图2.121所示。 (3)LocalPage 该属性值可以在单击链接后定位到指定的页数,设计界面如图2.122所示。 (4)RemoteAnchor 可以设置在导出的HTML文件中有一个链接,单击链接后到达C盘中的某一个HTML,并且定义到指定的Anchor,导出HTML定位findme的报表模板如图2.123所示。 继续设置目标Anchor的名称为endend,如图2.124所示。 文件c.html中有如下Anchor代码: asdf 在IE中运行程序,单击链接转到C盘的c.html,然后定位到名称为endend的Anchor上。 需要说明的是,不是所有的文件格式都支持超链接的形式。 还可以用HTTP协议来访问远程HTML中的Anchor,设计界面(使用HTTP协议访问远程HTML中的Anchor)如图2.125所示。 (5)RemotePage 此属性值主要用于在两个PDF文件之间链接到指定的页数,需要注意的是这两个PDF文件 必须放在同一个位置,如两个PDF文件放到Web项目中可以彼此调用,或者这两个PDF文件放到硬盘中可以互相调用。 (6)ReportExecution 该选项用于设置当鼠标悬停到链接上方时显示的提示文本。 4.4 文本控件(1) 在iReport中有两种控件可以显示文本,分别是Static Text和Text Field,它们的区别是Static Text只显示静态的文本,且不可以更改,而Text Field控件中显示的文本可以来自于变量、数据表字段中的值、Java的表达式,或者直接来自于一个字符串常量,如图2.126所示为使用常量字符串。 Text Field控件支持alignment(对齐)、position(位置)、line breaks(行回车)等功能,还支持随着内容的增加而在垂直方向上自动扩展的效果,以及支持超链接的效果。 控件Static Text和Text Field的共同属性如图2.127所示。 控件Text Field还具有自己独特的属性 它属性大多是如何利用动态的方式来提供Text Field显示的值。 1. 常用属性 这两个控件的常用属性有Font name(字体)、Size(字号)、Bold(是否为粗体)、Italic(是否为斜体)、Underline(是否有下划线)、Strike Through(是否有删除线)、Horizontal Alignment(水平对齐方式)、Vertical Alignment(垂直对齐方式)。 2. Rotation属性 属性Rotation的功能是定义文字如何打印,4种取值如图2.129所示。 其中None的运行效果如图2.130所示。 3. Line Spacing和Line spacing size属性 属性Line Spacing用于设置行间距的种类,而属性Line spacing size用于精确行间距的取值,行间距的取值列表如图2.134所示。 其中: Single是默认值。 1.5表示1.5倍的间距。 Double表示双倍的间距。 第5章 子报表Subreport 导言 子报表可以实现二级联动的效果,对创建复杂报表起着非常重要的作用。子报表是JasperReports框架中比较重要的知识点,读者应该着重掌握如下内容: 使用子报表控件 在程序代码中指定子报表文件 对子报表进行参数传递 从子报表中返回值 5.1 子报表Subreport的基础知识 其实子报表的解释很简单,就是报表中有报表。 如果想在iReport中使用子报表Subreport必须要考虑3件事情: 子报表如何取得对应的.jasper实例。 如何将数据传递给子报表。 如何给子报表参数设置传递数据值。 在解决这3个问题之前可以尝试着先把Subreport控件放到报表模板中,然后查看一下该控件独有的属性,Subreport控件的属性及控件的外观如图5.1所示。 想要解决上面这3个问题,也就是正确地使用Subreport子报表,其实答案就在图5.1中的属性里,在后面的章节中将主要介绍属性的作用及功能演示,这里不再赘述。 1.9 5.1 子报表Subreport的示例--静态文本(1) 本示例将演示主、子报表的使用,并且主、子报表中的数据都是静态文本,学习这个实验的主要目的是熟悉Subreport在iReport软件中的使用,需要注意的是:如果使用主、子报表时,子报表的DataSource中没有数据,则在预览主报表时子报表默认是不显示的。 1. 创建主报表及子报表 新建名称为main.jrxml主报表模板文件,把除了Detail 1栏之外的所有Band删除,并且添加一个Subreport控件,报表模板布局与添加的Subreport控件如图5.5所示。 弹出询问是否新建一个.jrxml文件还是使用存在的.jrxml,在这里选择新建一个.jrxml,如图5.6所示。 设置后单击\"下一步\"按钮继续配置,弹出选择报表模板对话框,如图5.7所示,为子报表选择一个模板,在这里只选择A4空白报表模板。 单击\"下一步\"按钮继续配置,在如图5.8所示的对话框中选择Empty datasource,即不需要数据库连接。 单击\"下一步\"按钮继续配置,不选择任何Field对象,如图5.9所示。 单击\"下一步\"按钮继续配置,不需要对子报表中的数据进行分组,如图5.10所示。 单击\"下一步\"按钮继续配置,弹出如图5.11所示的对话框,选中Store the directory name in a parameter单选按钮,也就是报表的路径可以来自于一个Parameters参数对象,这样可便于.jasper路径改变后对Java代码的维护。 单击\"下一步\"按钮继续配置,弹出如图5.12所示的对话框,询问主、子报表是使用同一个Connection还是其他的数据源,在这里选中Don't use any connection or date source单选按钮,即不使用任何的数据源。 配置完成后单击\"完成\"按钮出现两个.jrxml文件,如图5.13所示。 2. 两个.jrxml文件中的代码及编译 创建的main.jrxml文件中的核心代码如下: 从以上代码中可以看到 子报表文件并没有生成什么特别的代码,外观和普通的报表模板相同,如图5.14所示。 在main_subreport1.jrxml文件中添加一个Static Text对象,设计报表模板样式如图5.15所示。 设计main.jrxml文件模板样式,如图5.16所示。 继续配置Subreport控件的Subreport Expression属性,如图5.17所示。 通过图5.17可以说明,项目的src中有一个名称为jasperreports的包名,要把.jrxml编译后的.jasper文件放入这个包后再运行。 3. 在Web项目中使用两个.jrxml文件 创建Web项目,将这两个.jrxml文件放在WebRoot中的report文件夹下,项目结构如图5.18所示。 创建Servlet,核心代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String jrxmlSourcePathMain = this.getServletContext().getRealPath(\"/\") + \"report\\\\main.jrxml\"; String jrxmlSourcePathSub = this.getServletContext().getRealPath(\"/\") + \"report\\\\main_subreport1.jrxml\"; String jrxmlDestSourcePathMain = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+ \"jasperreports/main.jasper\"; String jrxmlDestSourcePathSub = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+ \"jasperreports/main_subreport1.jasper\"; JasperCompileManager.compileReportToFile(jrxmlSourcePathMain, jrxmlDestSourcePathMain); JasperCompileManager.compileReportToFile(jrxmlSourcePathSub, jrxmlDestSourcePathSub); InputStream isRef = new FileInputStream(new File( jrxmlDestSourcePathMain)); ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef, sosRef, new HashMap(), new JREmptyDataSource()); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 运行后子报表并没有输出,效果如图5.19所示。 因为子报表从未使用DataSource,所以子报表的Detail 1栏不显示,这种情况该怎么处理呢?这时可以使用No Data Section。 重新设计子报表模板,添加\"no data show!\",如图5.20所示。 还需要设置子报表模板的When No Data属性,如图5.21所示。 再次将这两个.jrxml放入Web项目,重新运行项目,主、子报表都显示出来了,效果如图5.22所示。 1.10 5.2 子报表Subreport的示例--动态数据JDBC(1) 本小节将演示子报表的使用方法,数据源来自于JDBC的Connection,重点是Parameters的使用,也就是Subreport控件 Parameters属性中的key/value中的key要对应sub.jrxml中的同名Parameters对象,即把main.jrxml中的值 通过Subreport控件的Parameters属性传递给sub.jrxml中的Parameters参数对象,因此main.jrxml和 sub.jrxml就可以通信了。 1. 创建userinfo数据表及内容 设计数据表userinfo的内容,如图5.23所示。 2. 创建主报表模板 在主报表模板中使用如图5.24所示的语句查询usertype的种类。 向主报表中添加usertype的Fields对象,如图5.25所示。 预览效果如图5.26所示,即出现3条记录。 3. 创建子报表模板 单独创建一个.jrxml文件作为子报表,删除除了Detai l之外的所有Band,并且设置Margins属性为0,设置内容如图5.27所示。 返回主报表,添加Subreport控件,使用如图5.28所示的设置在main.jrxml中关联sub.jrxml文件。 【责任编辑 单击\"下一步\"按钮,配置主、子报表使用相同的数据源,即同一个Connection连接,如图5.29所示。 单击\"下一步\"按钮,出现设置Parameters参数映射(如图5.30所示)和设置寻找.jasper路径类型的对话框(如图5.31所示),保持默认值即可,无须配置。 单击\"完成\"按钮完成Subreport控件关联sub.jrxml的操作,还要配置Subreport控件的Connection type属性,如图5.32所示。 由于主报表要对子报表传递usertype字段值,所以要添加一个Parameters属性,为Subreport控件添加Parameters属性如图5.33所示。 添加了Parameters属性后还要在sub.jrxml中添加参数来接收Subreport传递过来的参数usertypeParam对应的参数值,在sub.jrxml中添加Parameters参数对象,如图5.34所示。 需要注意的是Subreport中的Parameters属性名usertypeParam一定要和sub.jrxml中定义的Parameters参数名usertypeParam相同,这样才可以正确传递数据。 在sub.jrxml中配置查询的SQL语句,如图5.35所示。 并且在sub.jrxml报表模板上添加3个Fields对象,如图5.36所示。 最后需要更改Subreport的Subreport Expression属性值为sub.jasper,也就是在iReport中进行报表的预览,这两个.jrxml位于同一个文件夹下,如图5.37所示。 利用iReport预览的效果如图5.38所示。 4. 在Web项目中预览 由于Web项目是以PDF进行预览的,所以需要在iReport中解决PDF文件中显示中文的问题,设置中文编码如图5.39所示。 另外,在Web项目中运行的.jasper文件位于jasperreports包中,所以还要设置Subreport Expression的属性值为jasperreports/sub.jasper,如图5.40所示。 把iTextAsian.jar和iTextAsianCmaps.jar复制到Web项目的WEB-INF/lib文件夹下。 创建Servlet,核心代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String username = \"sa\"; String password = \"\"; String url = \"jdbc:sqlserver://localhost:1079;databaseName=ghydb\"; String driverName = \"com.microsoft.sqlserver.jdbc.SQLServerDriver\"; Class.forName(driverName); Connection connection=DriverManager.getConnection(url,username,password); String jrxmlSourcePathMain = this.getServletContext().getRealPath(\"/\") + \"report\\\\main.jrxml\"; String jrxmlSourcePathSub = this.getServletContext().getRealPath(\"/\") + \"report\\\\sub.jrxml\"; String jrxmlDestSourcePathMain = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1) + \"jasperreports/main.jasper\"; String jrxmlDestSourcePathSub = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1) + \"jasperreports/sub.jasper\"; JasperCompileManager.compileReportToFile(jrxmlSourcePathMain, jrxmlDestSourcePathMain); JasperCompileManager.compileReportToFile(jrxmlSourcePathSub, jrxmlDestSourcePathSub); InputStream isRef=new FileInputStream(new File(jrxmlDestSourcePathMain)); ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef,sosRef,new HashMap(),connection); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 运行效果如图5.41所示。 1.11 5.3 子报表Subreport的示例--打印实体类中的List 在第1章中曾经介绍过将List 1. 实体类的结构 创建要打印的实体Userinfo.java,代码如下: package entity; import java.util.ArrayList; import java.util.List; public class Userinfo { private String username; private String password; private List public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public List public void setListSchool(List public List public void setListAddress(List 类Address.java的结构如图5.42所示。 类School.java的结构如图5.43所示。 2. 创建3个.jrxml报表模板文件 新建report1.jrxml报表模板,设计内容如图5.44所示。 显示username值的Text Field控件的属性设计如图5.45所示。 显示password值的Text Field控件的属性设置与图5.45基本相同,这里不再赘述。 从图5.45中可以看到,一共有两个Detai l band栏,在每一个Detai l band栏中有一个Subreport控件,而且还添加了一个param_userinfo的Parameters参数对象,数据类型设置为 entity.Userinfo,该对象的属性设置如图5.46所示。 图5.46中的参数一定是在Servlet中通过HashMap对象传入到报表中,在报表中取得参数中的数据进而打印出来。 添加的第1个Subreport控件的属性设置如图5.47所示,即显示地址列表的Subreport属性设置。 其中比较重要的是属性Connection type,设置为Use a datasource expression,也就是子报表的数据来自于一个数据源,而不是Connection JDBC连接,取得数据源Data Source Expression属性值的表达式的内容如下: new net.sf.jasperreports.engine.data. JRBeanCollectionDataSource($P{param_userinfo}.getListAddress()) 即Subreport子报表的数据来自于$P{param_userinfo}参数的getListAddress()方法,该方法返回一个List 第2个Subreport控件和第1个基本相同,仅仅是取得数据源的代码不一样,第2个Subreport控件的属性设置如图5.48所示。 报表模板文件subListAddress.jrxml的设计界面如图5.49所示。 报表模板文件subListSchool.jrxml的设计界面如图5.50所示。 3. 设计Servlet核心代码 运行报表的Servlet核心代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Userinfo userinfo = new Userinfo(); userinfo.setUsername(\"高洪岩账号\"); userinfo.setPassword(\"高洪岩密码\"); ArrayList { schoolList.add(new School(\"id\" + (i + 1), \"school\" + (i + 1))); } ArrayList { addressList.add(new Address(\"id\" + (i + 1), \"address\" + (i + 1))); } userinfo.setListAddress(addressList); userinfo.setListSchool(schoolList); try { HashMap paramMap = new HashMap(); paramMap.put(\"param_userinfo\ String jrxmlSourcePathReport1=this.getServletContext().getRealPath(\"/\") + \"jrxml\\\\report1.jrxml\"; String jrxmlDestSourcePathReport1 = this.getClass() .getClassLoader().getResource(\"\").getPath().substring(1) + \"jasperreports/report1.jasper\"; String jrxmlSourcePathSubListAddress = this.getServletContext() .getRealPath(\"/\") + \"jrxml\\\\subListAddress.jrxml\"; String jrxmlDestSourcePathSubListAddress = this.getClass() .getClassLoader().getResource(\"\").getPath().substring(1) + \"jasperreports/subListAddress.jasper\"; String jrxmlSourcePathSubListSchool = this.getServletContext() .getRealPath(\"/\")+ \"jrxml\\\\subListSchool.jrxml\"; String jrxmlDestSourcePathSubListSchool = this.getClass() .getClassLoader().getResource(\"\").getPath().substring(1) + \"jasperreports/subListSchool.jasper\"; JasperCompileManager.compileReportToFile( jrxmlSourcePathSubListAddress, jrxmlDestSourcePathSubListAddress); JasperCompileManager.compileReportToFile( jrxmlSourcePathSubListSchool,jrxmlDestSourcePathSubListSchool); JasperCompileManager.compileReportToFile(jrxmlSourcePathReport1, jrxmlDestSourcePathReport1); InputStream isRef = new FileInputStream(new File( jrxmlDestSourcePathReport1)); ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef, sosRef, paramMap, new JREmptyDataSource()); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 4. 运行效果 程序运行的效果如图5.51所示。 1.12 5.4 从Servlet传递一个Map类型的参数到子报表 使用Parameters Map Expression属性的情况是在Sevlet中将固定的值作为参数传入到子报表中。 1. 创建Servlet代码 创建一个主报表main.jrxml,再创建一个子报表sub.jrxml,Servlet核心代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { HashMap subReportMap = new HashMap(); subReportMap.put(\"mapKey1\ String jrxmlSourcePathSub = this.getServletContext().getRealPath(\"/\") + \"jrxml\\\\sub.jrxml\"; String jrxmlDestPathSub = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+ \"jasperreports/sub.jasper\"; String jrxmlSourcePathMain = this.getServletContext().getRealPath(\"/\") + \"jrxml\\\\main.jrxml\"; String jrxmlDestPathMain = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+ \"jasperreports/main.jasper\"; JasperCompileManager.compileReportToFile(jrxmlSourcePathSub,jrxmlDestPathSub); JasperCompileManager.compileReportToFile (jrxmlSourcePathMain,jrxmlDestPathMain); InputStream isRef = new FileInputStream(new File(jrxmlDestPathMain)); HashMap paramMap = new HashMap(); paramMap.put(\"zzzzzzzzzz\ paramMap.put(\"showMainUsername\ ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef, sosRef, paramMap, new JREmptyDataSource()); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 从上面的代码可以看到如下的代码片段: HashMap subReportMap = new HashMap(); subReportMap.put(\"mapKey1\我是mapKey1我是高洪岩\"); HashMap paramMap = new HashMap(); paramMap.put(\"zzzzzzzzzz\ paramMap.put(\"showMainUsername\ JasperRunManager.runReportToPdfStream(isRef,sosRef,paramMap,new JREmptyDataSource()); 对象paramMap是真正传给main.jrxml的Parameters参数的Map对象,其中有两个key,一个是zzzzzzzzzz,另外一个是showMainUsername,所以要在main.jrxml中创建对应的两个Parameters参数对象。 2. 在main.jrxml中添加两个Parameters参数对象 参数名称为zzzzzzzzzz的属性设置如图5.52所示。 参数showMainUsername的属性设置如图5.53所示。 3. 在main.jrxml中显示showMainUsername参数值并添加Subreport控件 设计在main.jrxml中显示showMainUsername参数值,如图5.54所示。 添加Subreport控件,并且设置其属性如图5.55所示。 Parameters Map Expression的属性值为$P{zzzzzzzzzz},也就是将$P{zzzzzzzzzz}参数再传给子报表,所以在子报表中可以根据Map的key获取到zzzzzzzzzz对应Map中的值。 4. 设计sub.jrxml子报表模板 在子报表中添加No Data Band,添加Parameters参数mapKey1,效果如图5.56所示。 5. 运行效果 程序运行效果如图5.57所示。 1.13 5.5 对表达式进行计算后再传入子报表 前面的小节使用Parameters Map Expression属性对子报表传递Map类型的Parameters参数,然后在子报表中根据Map的key值就可以获取到对应的值,在这个过程中 Map的值仅仅是从Servlet中就已经确定了,不能更改,有些时候需要传递到子报表中的参数值可以进行计算,那么Parameters Map Expression属性就无法实现了,这时可以使用Parameters属性来实现这种动态值的效果。 Parameters属性在前面的章节已经介绍过,这里不再赘述。 在上一小节的基础上对Subreport控件设置Parameters属性,如图5.58所示。 设置完成后的Subreport控件属性如图5.59所示。 程序运行后的效果如图5.60所示。 从图5.60中可以看到,通过使用Parameters属性可以对参数的值进行计算,然后再传入到Subreport中。 1.14 5.6 对子报表传递List 有时候子报表中的数据源是被嵌套的,示例代码如下: public class test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // 在主报表中打印的普通String类型的Parameters参数 HashMap paramMap = new HashMap(); paramMap.put(\"param_username_main\ paramMap.put(\"param_password_main\ // 在主报表Detail打印的实体Userinfo列表 List mainListUsername = new ArrayList(); mainListUsername.add(new Userinfo(\"id11\ mainListUsername.add(new Userinfo(\"id12\ mainListUsername.add(new Userinfo(\"id13\ // ///////////////////////////////// // 在子报表中的Detail打印的列表,也就是Subreport的数据源 List subListUsername = new ArrayList(); subListUsername.add(new Userinfo(\"id111\ subListUsername.add(new Userinfo(\"id112\ subListUsername.add(new Userinfo(\"id113\ // 此subParamMap是在子报表Subreport中打印的普通字符串 HashMap subParamMap = new HashMap(); subParamMap.put(\"param_username_sub\ subParamMap.put(\"param_password_sub\ // 将subListUsername放入subParamMap对象中 subParamMap.put(\"subListUsername\ // 再将subParamMap对象放入paramMap对象中 paramMap.put(\"subParamMap\ String reportsDir = request.getSession().getServletContext() .getRealPath(\"/reports\"); String mainJRXMLPath = reportsDir + \"\\\\main.jrxml\"; String subJRXMLPath = reportsDir + \"\\\\sub.jrxml\"; String jasperreportsPath = this.getClass().getClassLoader() .getResource(\"\").getPath().toString().substring(1)+ \"/jasperreports/\"; String mainJASPERPath = jasperreportsPath + \"main.jasper\"; String subJASPERPath = jasperreportsPath + \"sub.jasper\"; JasperCompileManager.compileReportToFile(subJRXMLPath,subJASPERPath); JasperCompileManager.compileReportToFile(mainJRXMLPath,mainJASPERPath); InputStream isRef = new FileInputStream(new File(mainJASPERPath)); ServletOutputStream sosRef = response.getOutputStream(); response.setCharacterEncoding(\"utf-8\"); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef, sosRef, paramMap, new JRBeanCollectionDataSource(mainListUsername)); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 从上面可以看到如下代码: paramMap.put(\"subParamMap\ 也就是将子报表的Map放入paramMap中了,那也就意味着子报表Subreport的数据源的嵌套关系是:paramMap.get(\"subParamMap\").get(\"subListUsername\"),只有这样才可以传递给子报表数据源并打印出来。 主报表main.jrxml的设计如图5.61所示。 从图5.61中可以看到有3个自定义的Parameters参数,属性设置如图5.62所示。 主报表main.jrxml中的Summary栏的内容如图5.63所示。 子报表Subreport控件的属性设置如图5.64所示。 属性Parameters Map Expression值为$P{subParamMap}的作用是把名称为subParamMap的Map对象中的值批量传入子报表,而对象 subParamMap中有一个List对象,它是子报表的数据源,如何传给子报表呢?取出后将其转换成 JRBeanCollectionDataSource对象即可,此功能由Data Source Expression属性完成,该属性值设置为: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource ($P{subParamMap}.get(\"subListUsername\")) 子报表sub.jrxml的界面设计如图5.65所示。 程序运行效果如图5.66所示。 1.15 5.7 示例:从主报表中取得子报表返回的参数值(1) 本小节将使用省市二级联动的效果实现,并且在省名的右边显示该省一共有多少个市。 1. 在Servlet对象中封装省市二级联动关系 核心代码如下: public class test extends HttpServlet { @SuppressWarnings(\"unchecked\") public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Sheng sheng1 = new Sheng(\"1\辽宁省\"); Shi sheng1_shi1 = new Shi(\"101\沈阳市1\"); Shi sheng1_shi2 = new Shi(\"102\沈阳市2\"); Shi sheng1_shi3 = new Shi(\"103\沈阳市3\"); sheng1.getShiList().add(sheng1_shi1); sheng1.getShiList().add(sheng1_shi2); sheng1.getShiList().add(sheng1_shi3); Sheng sheng2 = new Sheng(\"2\山东省\"); Shi sheng2_shi1 = new Shi(\"101\青岛市1\"); Shi sheng2_shi2 = new Shi(\"101\青岛市2\"); sheng2.getShiList().add(sheng2_shi1); sheng2.getShiList().add(sheng2_shi2); List shengList = new ArrayList(); shengList.add(sheng1); shengList.add(sheng2); Userinfo userinfo = new Userinfo(); userinfo.setUsername(\"高洪岩的报表-用子报表模仿分组Group的效果\"); String jrxmlSourcePathSub = this.getServletContext().getRealPath(\"/\") + \"jrxml\\\\sub.jrxml\"; String jrxmlDestPathSub = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+ \"jasperreports/sub.jasper\"; String jrxmlSourcePathMain = this.getServletContext().getRealPath(\"/\") + \"jrxml\\\\main.jrxml\"; String jrxmlDestPathMain = this.getClass().getClassLoader() .getResource(\"\").getPath().substring(1)+ \"jasperreports/main.jasper\"; JasperCompileManager.compileReportToFile(jrxmlSourcePathSub,jrxmlDestPathSub); JasperCompileManager.compileReportToFile(jrxmlSourcePathMain, jrxmlDestPathMain); InputStream isRef = new FileInputStream(new File(jrxmlDestPathMain)); HashMap paramMap = new HashMap(); paramMap.put(\"userinfo\ ServletOutputStream sosRef = response.getOutputStream(); response.setContentType(\"application/pdf\"); JasperRunManager.runReportToPdfStream(isRef, sosRef, paramMap, new JRBeanCollectionDataSource(shengList)); sosRef.flush(); sosRef.close(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 2. 添加Sheng.class、Shi.class及中文.jar文件路径 配置Sheng.class、Shi.class及中文.jar的文件路径如图5.67所示。 3. 逆向Sheng.java的属性 逆向Sheng.java中的两个属性名如图5.68所示。 一定要将shiList属性逆向,因为需要对Shi.java进行列表打印。 4. 设计main.jrxml的报表模板 main.jrxml报表模板的外观如图5.69所示。 5. 显示省列表的运行效果 程序运行后显示出省列表,如图5.70所示。 6. 在main.jrxml中添加Subreport控件 设置Subreport控件的属性,如图5.71所示。 关键是要设置Data Source Expression属性值,如图5.72所示。 7. 设计sub.jrxml报表模板 为sub.jrxml报表模板中显示的Shi.java类中的数据进行逆向,如图5.73所示。 添加3个Fields对象,并将Margin属性清0,sub.jrxml报表模板设计如图5.74所示。 别忘了设置Text Field控件的中文属性。 8. 省市一起显示的运行效果 省市一起显示的运行效果如图5.75所示。 9. 统计每个省中市的数量 在sub.jrxml模板中添加一个Variables变量对象,专门用来统计每个省中的市数量,变量shiCount的属性设置如图5.76所示。 分别显示出市的数量,程序运行效果如图5.77所示。 10. 在main.jrxml中添加Variables变量并与子报表中的变量做关联映射 变量的属性设置如图5.78所示。 将子报表中的shiCount映射到main.jrxml中的getShiCount变量上,选中Subreport控件,Return Values属性设置如图5.79所示。 添加一个变量映射,主、子报表的变量映射设置如图5.80所示。 将变量添加到main.jrxml界面,并且设置Evaluation Time属性为Band,如图5.81所示。 因篇幅问题不能全部显示,请点此查看更多更全内容