概述:
现在简要的介绍Jasperreport 是
如何工作的,这样你可以更好的理解iReport 是如何帮助Jasperreport 实现前端的
工作,其实这些工作在我们看来就是“脏活”,为什么呢?看看下面的资料就知
道了:
首先是要有一个XML
文件(一般是以jrxml后缀),那么这个XML文件从那里来呢?做什么用呢? 这
个XML 文件就是报表的定义文件,整个报表的每一个细节都在这个XML 文件
之中定义,一个简单报表的xml文件就有几百行,你可以手工编辑这个XML文
件(一行一行,一段一段的编辑吧――这就是所谓的“脏活”),然后可以在jsp后台使用JasperCompileManager将xml文件编译为jasper文件
ireport工具就是简化编写xml文件和编译的这个流程,而且提供可视化编辑窗口,非常方便
我使用的是ireport3.0和现在最新的4.0界面上有很大的不同:
3.0界面:
这里,我假设ireport的环境已经配置完毕,点击左上角的档案,选择开启新档,设置报表初始化参数:
注意一下里边的字段数的按钮,字段数设置默认为1,如果设置为2的话,就相当于每一列会有2个字段排列,这样讲有点抽象,请看下边
的例子:
假设我们的数据表是这样:
name | sex | realname | remark |
a_1 | b_1 | c_1 | d_1 |
a_2 | b_2 | c_2 | d_2 |
a_3 | b_3 | c_3 | d_3 |
a_4 | b_4 | c_4 | d_4 |
如果ireport的字段数设为2,结果会变成:
name | sex | realname | remark |
a_1 a_2 | b_1 b_2 | c_1 c_2 | d_1 d_2 |
a_3 a_4 | b_3 b_4 | c_3 c_4 | d_3 d_4 |
所以,一般设置字段数为1即可。
新建后,可以看到中间的控制面板:
这里,假设您只需要报表显示表格和统计数据,所以title和lastpagefooter可以不要,在左上角的预览里,选择栏,把title和lastpagefooter高度设为0.
下面开始设计报表:
然后可以拖拉到控制面板对应字段对齐
这里假设各位都会对其,效果图如下:
使用报表变量,计算统计值:
document下右键添加variable,出现这个界面,然后按照这样设置:
这里我是统计列a的个行相加值,因为前面 已经设置了sum,所以,报表会自动计算列a的相加值。
这里设计报表要注意几点:
1.字段间要对齐,方框为红色的,表明是超出报表边界
2.写表达式的时候,与java类型兼容,但是写法有点不同,类型转换要用new 类型 不然会报错
1.每个Web应用都会有WEB-INF目录,但是lib 是不一定有的,如果没有就创
建它,本文需要的jar库文件有3个:
jasperreports-0.5.3.jar :jasperreports执行时需要的API
iTextAsian.jar :亚洲字符集支持
itext-1.02b.jar :其他字符集支持
2.在Web应用中根目录下创建repotrs目录,其实这是一种建议,没有必要完
全按照这样做,你可以根据你的业务需要创建N个目录或是层次目录。
把.jasper文件拷贝到repotrs目录下,比如例子中的BusinessRpt.jasper
文件。
1.直接使用jsp处理报表
2.使用servlet处理报表
1.使用jsp处理报表:
jsp文件:
<%@ page session="false" %> <%@ page import="dori.jasper.engine.*" %> <%@ page import="javax.naming.*"%> <%@ page import="java.sql.*"%> <%@ page import="javax.sql.*"%> <%@ page import="java.util.*" %> <%@ page import="java.io.*" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title></title> <% DataSource ds = null; try{ InitialContext ctx=new InitialContext(); ds=(DataSource)ctx.lookup("java:comp/env/jdbc/mysql"); Connection conn = ds.getConnection(); //装载jasper 文件 File business_rpt = new File(application.getRealPath("/reports/BusinessRpt.jasper")); // http://blog.csdn.net/jemlee2002/archive/2004/10/08/JJem3.aspx //ProjectName 就是iReport 的变量$P{ProjectName}的名称, //proname 就是从界面上获取的值。 Map parameters = new HashMap(); parameters.put("ProjectName ", proname); // JasperRunManager是一个输出控制管理类,下文会提及部分内容 JasperRunManager.runReportToHtmlFile(business_rpt.getPath(),parameters,conn); //如果创建报表成功,则转向该报表,其实可以把报表套在框架内,这样实现比较有意 义的报表格式。 response.sendRedirect("/reports/BusinessRpt.html"); }catch(Exception ex){ out.print("出现例外,信息是:"+ex.getMessage()); ex.printStackTrace(); } %> </head> <body> </body> </html>
2.使用servlet处理报表:
主要区别就是,servlet是直接输出report报表流:
先写一个CustomDataSource类实现report的JRDataSource接口,转化vector向量为数据源:
public class CustomDataSource implements JRDataSource { private Vector dataVector = new Vector(); private int index = -1; public CustomDataSource(Vector DataVector) { dataVector=DataVector; } public boolean next() throws JRException { index++; return (index < dataVector.size()); } public Object getFieldValue(JRField field) throws JRException { Object value = null; String fieldName = field.getName(); value=((Map)dataVector.get(index)).get(fieldName); return value; } }
输出html:
ServletContext context = this.getServletConfig().getServletContext(); File reportFile = new File(context .getRealPath("/reports/test.jasper"));//加载报表路径 if (!reportFile.exists()) { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.print("<script language='javascript'>"); out.print("alert('找不到报表!');"); out.print("</script>"); return; } Map parameters = new HashMap(); response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); try { JasperReport jasperReport = (JasperReport) JRLoader .loadObject(reportFile.getPath());//加载报表 /* java.lang.reflect.Field pageHeight = JRBaseReport.class.getDeclaredField("pageHeight"); pageHeight.setAccessible(true); pageHeight.setInt(jasperReport, 500); */ JasperPrint jasperPrint = JasperFillManager .fillReport(jasperReport, parameters, new CustomDataSource((Vector) re .get(1)));//加载数据源和parameters,这里的数据源用到的是JRDataSource,所以要实现JRDataSource接口 JRHtmlExporter exporter = new JRHtmlExporter(); Map imagesMap = new HashMap(); request.getSession().setAttribute("IMAGES_MAP", imagesMap); String header = ""; header = "<script language='javascript'>\n"; header += "window.history.forward(1);\n"; header += "document.onkeydown=function(){if(event.keyCode==8){if((document.activeElement.type!='text')&&(document.activeElement.type!='textarea')){event.keyCode=0}};}\n"; header += "document.oncontextmenu=function() {return false;};\n"; header += "</script>\n"; header += "<html>\n"; header += "<head>\n"; header += " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=GBK\">\n"; header += "<style type=\"text/css\">\n"; header += " a {text-decoration: none}\n"; header += " </style>\n"; header += "</head>\n"; header += "<body text=\"#000000\" link=\"#000000\" alink=\"#000000\" vlink=\"#000000\">\n"; header += "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n"; header += "<tr><td width=\"50%\"> </td><td align=\"center\">\n"; header += "\n"; exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter( JRExporterParameter.OUTPUT_WRITER, out); exporter.setParameter( JRHtmlExporterParameter.IMAGES_MAP, imagesMap); exporter.setParameter( JRHtmlExporterParameter.IMAGES_URI, "/Images/"); exporter .setParameter( JRHtmlExporterParameter.HTML_HEADER, header); exporter.exportReport();
pdf输出:
byte[] bytes = null; try { bytes = JasperRunManager.runReportToPdf(reportFile .getPath(), parameters, new CustomDataSource((Vector) re.get(1))); if (bytes != null && bytes.length > 0) { response.setContentType("application/pdf"); response.setContentLength(bytes.length); ServletOutputStream ouputStream = response .getOutputStream(); ouputStream.write(bytes, 0, bytes.length); ouputStream.flush(); ouputStream.close(); } } catch (Exception e) { e.printStackTrace(); System.out.println("ErrorTime:" + new Date()); response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.print("<script language='javascript'>"); out.print("alert('" + e.toString().replace("'", " ") + "');"); out.print("</script>"); }
excel输出:
try { JasperReport jasperReport = (JasperReport) JRLoader .loadObject(reportFile.getPath()); ServletOutputStream ouputStream = response .getOutputStream(); JasperPrint jasperPrint = JasperFillManager .fillReport(jasperReport, parameters, new CustomDataSource((Vector) re .get(1))); response.setContentType("application/ms-excel"); response.setHeader("Content-Disposition", "inline;filename=\"" + jasperPrint.getName() + ".XLS\""); JRXlsExporter exporter = new JRXlsExporter(); exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter( JRExporterParameter.OUTPUT_STREAM, ouputStream); exporter .setParameter( JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); exporter .setParameter( JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE); exporter .setParameter( JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE); exporter.exportReport(); } catch (Exception e) { e.printStackTrace(); System.out.println("ErrorTime:" + new Date()); response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.print("<script language='javascript'>"); out.print("alert('" + e.toString().replace("'", " ") + "');"); out.print("</script>"); }