Jasperreport+ireport 实践操作及 web 应用
转自:http://blog.csdn.net/jiaoxiaguoke/article/details/5089266
学习完jasperreports+ireport,给我感觉深刻,不仅掌握了报表开发技术,还掌握了如何在web中生成pdf,xls,rtf文件,以下是jasperreports+ireport开发知识点: 1.字段,变量,参数,传参2.矢量图,位图3.超链接,锚4.数据源,自定义数据源5.国际化(I18N)6.脚本 7.子报表 8.图表(饼图,柱图,线图) 9.导出pdf,xls,html...操作版本: jasperreports2.0.2+ireport2.0.2说明: 本文并非入门级教程,所以阅读本文需要有一定基础.以下针对每个知识点,讲解在ireport中是如何操作,以及在真实项目中如何部署.1. 字段 , 变量 , 参数 , 传参这个知识点很简单,在ireport的 view 菜单下有 Fields,Variables,Parameters三个菜单,如要定义一个参数,可进行如下操作.点 击 Parameters 菜单,此时弹出一个操作参数的窗口,单击 New 按钮,输入参数名(Parameter Name),选择参数类型(Parameter Class Type),如要赋一个默认值则填写默认值表达式(Default Value Expression)(默认值如为字符串则以"string"形式填写,如为整形则以 new Integer(1) 形式填写,以此类推.),填好后,点 OK 就新建了一个参数了.定义字段与定义参数是一样的操作,至于定义变量操作差不多,也相对少用一些,在此就不讲述.在ireport 中如何引用字段, 变量, 参数? 引用字段使用 $F{field_name}引用变量使用 $V{variable_name}引用参数使用 $P{param_name} 或 $P!{param_name}$P!{param_name}一般用于拼接sql语句,它的值可以与sql语句拼接后,再去执行查询.例:定义一个参数名为 where 类型为String 默认值为 "where id=100"有一查询语句:select * from user $P!{where}则执行查询时会替换成:select * from user where id=100$P{param_name}在sql语句中使用时,也有一特殊情况.例:有一参数名为 id,类型为Integer,默认值为 new Integer(100)有一查询语句:select * from user where id=$P{id}执行查询可正常查询,但如果有一参数名为 name,类型为String,默认值为"zhanngle"有一查询语句:select * from user where name=$P{name}执行查询时出错,不知道为什么(即使数据库中有该条记录),不知是不是bug,还是自已哪里弄错了.解决办法是,将查询语句改为:select * from user where name='$P!{name}'可以证明$P!{}语法,只做替换操作,如上只将$P!{name}替换成zhanngle.也可以证明$P{}语法,在sql语句中使用时,值为数字类型还可以正常执行,如为字符串类型则会出错.在程序中如何传参? 如上例定义了一个name参数,那么在程序中如何动态传参查询出不同的记录呢,也很简单.程序代码如下: Map params = new HashMap(); params.put( " name " , " zhanngle " ); JasperPrint print = JasperFillManager.fillReport(jasper, params,conn);就是将参数名和值put进入一map,然后再填充报表时将map传过去就行了.2. 矢量图 , 位图Jasperreports支持矢量图与位图功能,是因为他封装了jfreechart(jfreechart是一个开源的图形解决方案库), 使用ireport绘制矢量图或插入位图,可以不用我们写一行代码,这些jasperreports已经为我们全部封装好了,ireport只提供了三种 矢量图,分别是矩形,圆形,线条,下面先介绍如何绘制矢量图,再介绍如何插入位图. 初始工作:先新建一个空报表绘制矩形: 点击工具栏的 Rectangle 按钮,在Detail区域,绘制一个矩形,绘制方法与windows自带的画图工具一样,绘制好后,在该矩形上点右键,选属性,即可设置该矩形的属性,大家可以根据自己需要进行设置,如设置前景色,背景色...绘制圆形与绘制线条方法一样,只需要在工具栏点相应的圆形工具或线条工具就行了.很简单吧. 问题出现1. 图与图之间(更具体的说法,应该是元素与元素之间)不能有任何重叠,如重叠则只能显示最上层的图.2. 使用线条工具可以绘制斜线,当导出为pdf文件,没有任何问题,当导出html,xls文件时,发现斜线变成了矩形,解决方案是:使用外部图形编辑软件,绘制一条斜线,并保存为图片文件,再将这个图片文件插入到报表相应位置中.在ireport 中如何测试预览pdf,html,xls… 文件?1.首先要设置一下pdf文件有什么预览,html文件用什么预览…点Options -> Settings -> External Programs,在弹出的窗口中填写正确的外部程序。如我的设置如下:External Editor: C:/Program Files/EditPlus 2/editplus.exe (jrxml文件编辑器)PDF Viewer: D:/Program Files/Adobe/Acrobat 7.0/Reader/AcroRd32.exeHTML Viewer: C:/Program Files/Internet Explorer/IEXPLORE.EXEXLS Viewer: "D:/Program Files/Microsoft Office/OFFICE11/EXCEL.EXE"RTF Viewer: C:/Program Files/Windows NT/Accessories/wordpad.exe该步操作只要设置一次,以后就不需要再设置了。2.设置你要预览的是什么文件,ireport默认预览的是pdf文件,但不是使用我们配制的外部程序预览的,而是使用 jasperreports的JRViewer预览的。你也可以设置使用我们配制的外部程序来预览,点Build -> PDF Preview,再点Execute (empty data source)按钮,即可预览PDF文件。点Build -> HTML Preview,再点Execute (empty data source)按钮,即可预览HTML文件。注意: 任何一个报表都必须要有一个数据源来为报表提供数据。Execute (empty data source)的意思就是构造一个只有一条记录的数据源传给报表,并且这条记录的值都是null,这个按钮在测试报表不需要数据时,非常有用。Execute (whit active connection)的意思就是将当前激活的连接或数据源传给报表,并生成报表。 位图插入位图也很简单,在工具栏上点击 Image 按钮,然后在 Detail 区域绘制一个”矩形”(与绘制矩形操作相同),此时可以在你绘制的区域看到一个图片,在这个图片上点右键,选属性,选 Image 选项卡,点 “Find …”按钮,选择你要插入的图片,OK后,就可以看到你要插入的图片了. 在真实项目中如何插入图片, 动态改变图片?在真实项目中可不能使用上面介绍的方法来插入图片,上面的方法只是启到 hello world 的作用,要想在真实项目中插入图片,可以按照以下方法来配制.1. 定义一个参数名为 imageName 类型:String 没有默认值 2. 在报表设计界面中绘制一个Image,打开该Image的属性框,选Image选项卡,在Image Expression文本框中输入:$P{imageName},代表该图片的路径是由imageName的参数值来决定的,我们可以在程序中传入该参数的值.如何在程序中传入该参数值呢?示例代码如下: ServletContext context = request.getSession().getServletContext(); Map params = new HashMap(); Params.put(“imageName”,context.getRealPath(“ / reports / test.jpg”)); JasperPrint print = JasperFillManager.fillReport(jasper, params,conn); 传入不同的路径值即可动态改变图片 在html 中如何显示图片?当导出带有图片的报表到pdf,xls文件时,没有任何问题,但导出到html文件时,发现图片不能正常显示,不要急,jasperreports已经为我们提供了解决方案.解决步骤如下:1.将以下代码添加到web.xml文件中 < servlet > < servlet-name > JasperreportsImageServlet </ servlet-name > < servlet-class > net.sf.jasperreports.j2ee.servlets.ImageServlet </ servlet-class > </ servlet > < servlet-mapping > < servlet-name > JasperreportsImageServlet </ servlet-name > < url-pattern > /servlets/image </ url-pattern > </ servlet-mapping >2.程序代码按以下方式编写 ServletContext context = request.getSession().getServletContext(); Map params = new HashMap(); Params.put(“imageName”,context.getRealPath(“ / reports / test.jpg”)); Map imageMap = new HashMap(); request.getSession().setAttribute( " IMAGES_MAP " , imageMap); JasperPrint print = JasperFillManager.fillReport(jasper,params,conn);request.getSession().setAttribute(net.sf.jasperreports.j2ee.servlets.ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,print); JRHtmlExporter exporter = new JRHtmlExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, print); exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter()); exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP,imageMap); exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + " /servlets/image?image= " );exporter.setParameter(JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.TRUE); 3. 超链接 , 锚有时我们想在报表中为某个关键字添加超链接或锚,使鼠标点击该关键字时跳转页面.针对这一小功能,jasperreports 也提供了支持,在ireport中操作很简单.不是所有的元素都支持超链接,目前我所知道支持超链接的常用元素有,动态文本框元素(Text Field),位图元素(Image),图表元素(Chart tool).这三种元素设置超链接的方法都是一样,所以只介绍动态文本框如何设置超链接. 如何在 ireport 中插入超链接 ?由于静态文本框不支持超链接,所以只能通过动态文本框为静态文字设置超链接,操作方法如下所述:1.在工具栏中选中 Text Field 按钮,回到 Detail 区域,绘制一个Text Field (与绘制矩形方法一样),然后在该Text Field 上点右键,选 Edit Expresion,在弹出的窗口中输入表达式 "CSDN",然后再点 apply 按钮.(注意: "CSDN"要包含双引号)2.打开该 Text Field 的属性框,选 Hyperlink 选项卡,将 Hyperlink target 改为 blank,Hyperlink Type 改为 Reference,在Hyperlink Reference Expression框中输入"http://www.csdn.net ",再点关闭.(注意: "http://www.csdn.net " 要包含双引号)此时一个超链接已设置好,导出pdf,html文件看看,点击CSDN即可弹出CSDN的网页. 如何在ireport 中插入锚?其实锚是超链接的一种特殊形式,因此支持超链接的元素都支持锚,不支持超链接的元素都不支持锚,锚的设置也很简单,只要你知道使用html的<a>设置锚,那么ireport也是差不多的.设置锚,也需要两步操作1.设置锚对象在 Title 区域绘制一个动态文本框,输入表达式 “2007年终财务报表”,再打开它的Hyperlink 选项卡,在 Anchor Name Expression 框中输入 “title”,点关闭.此时已定义了一个锚对象.它的锚名字是 title.2.链接锚对象在 Detail区域绘制一个动态文本框,输入表达式 “返回顶部”,再打开它的 Hyperlink 选项卡,将Hyperlink target改为 self,Hyperlink Type 改为 LocalAnchor,在Hyperlink Anchor Expression框中输入 “title”,点关闭.一个锚链接已设置完毕,导出pdf,html看看,当然,如果你的报表内容不多,那么锚起不到任何作用. 4. 数据源 , 自定义数据源数据源顾名思义数据来源,即报表数据从何而来。jasperreports可以从数据库、XML文件、CSV文件、 java.util.Collection对象以及自定义数据源得到数据。在真实项目中,报表数据一般从数据库得到,下面介绍在ireport中如何配制 连接制数据库的数据源。操作步骤如下: 说明: 本例以MySql数据库来配制数据源新建一个Document(报表文档),点 Data -> Connections/Data Sources -> New -> Database JDBC Connection -> Next。在弹出的窗口中按照提示填写属性,例:Name:mysql,JDBC Driver:com.mysql.jdbc.DriverJDBC URL:jdbc:mysql://localhost:3306/db_nameUser Name:rootPassword:your_password 填好后,单击Test按钮,如弹出 Connection test successful!,则代表数据源配制正确,并再点Save 按钮,保存配制。否则配制错误,请检查哪里出错。配制好后,即可连接数据库。那么如何用数据源查询数据库,并将查询结果显示在报表上呢?说明: 本例操作必须配制好数据库数据源才能正常操作。而且连接的数据库里要有表。点 Data -> Report Query,在弹出的窗口中输入SQL查询语句:select * from t_users 。如果sql语句正确将在窗口底部显示该表的所有字段,点击OK,即完成了报表查询工作。大家可以查看一下Fields面板,ireport已经自动将查询出的所有字段,定义成字段对象了(也就是最前面所说的定义字段)。说完了如何将数据查询出来,接下来的工作就是如何将数据显示在报表界面上。点View -> Fields打开Fields面板,在面板上任意选一个字段,将它拖到Detail区域的左上角对齐,再选一个字段拖到Detail区域的中上角,好了就 用两字段做试验吧,只要Detail区域够宽,大家可以多拖两个字段到Detail区域,拖到Detail区域的字段将在报表中显示。调整好Detail 区域的高度,运行(Build -> Execute (whit active connection))一下看看吧,如果你看到有正确数据,那恭喜你,你试验成功了! 自定义数据源有时,你可能需要自定义一个数据源来满足你的需求,jasperreports对此也提供了良好支持。只要你实现JRDataSource接口,就行了,很简单吧!JRDataSource接口声明如下: public interface JRDataSource { public boolean next() throws JRException; public Object getFieldValue(JRField jrField) throws JRException; } 以下我是我自定义的一个数据源代码:1.先创建一个Bean类,该bean类属性全是大写,这是因为ireport自动定义字段时,字段名全是大写,你也可以手动改为小写,那么该bean类属性就可以为小写,你要确保bean类的属性名与字段名一致(包括大小写)。 package test; import java.sql.Timestamp; publicclass Bean { privateintID; private String NAME; private String NICKNAME; privateintSCORE; privatefloatBALANCE; private Timestamp LASTLOGINDATE; publicfloat getBALANCE() { returnBALANCE; } publicvoid setBALANCE( float balance) { this .BALANCE = balance; } publicint getID() { returnID; } publicvoid setID( int id) { this .ID = id; } public Timestamp getLASTLOGINDATE() { returnLASTLOGINDATE; } publicvoid setLASTLOGINDATE(Timestamp lastLoginDate) { this .LASTLOGINDATE = lastLoginDate; } public String getNAME() { returnNAME; } publicvoid setNAME(String name) { this .NAME = name; } public String getNICKNAME() { returnNICKNAME; } publicvoid setNICKNAME(String nickname) { this .NICKNAME = nickname; } publicint getSCORE() { returnSCORE; } publicvoid setSCORE( int score) { this .SCORE = score; } } 2.创建实现数据源类 package test; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.PropertyUtils; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRField; publicclass TestBeanDataSource implements JRDataSource { private List list; privateintindex =- 1 ; public TestBeanDataSource() { list = new ArrayList(); Bean bean = null ; for ( int i = 0 ;i < 100 ;i ++ ) { bean = new Bean(); bean.setID(i); bean.setNAME( " name " + i); bean.setNICKNAME( " nickname " + i); bean.setBALANCE(( float )(Math.random() * 100 * i)); bean.setSCORE(i * 2 ); bean.setLASTLOGINDATE( new Timestamp(System.currentTimeMillis())); list.add(bean); } } publicboolean next() throws JRException { return ++ index < list.size(); // return false; } public Object getFieldValue(JRField field) throws JRException { Bean bean = (Bean)list.get(index); String fieldName = field.getName(); try { return PropertyUtils.getProperty(bean,fieldName); } catch (Exception e) { thrownew JRException(e); } } public List getList() { returnlist; } publicvoid setList(List list) { this .list = list; } } 3.在填充报表时将该DataSource传进去就行了。 JasperPrint print = JasperFillManager.fillReport(jasper,map, new TestBeanDataSource()); JRHtmlExporter exporter = new JRHtmlExporter(); … exporter.setParameter(JRExporterParameter.JASPER_PRINT, print); … exporter.exportReport();此时报表数据的来源,就是从自定义数据源中得到的100条记录。 如何配制 ireport 支持自定义的数据源 ?1.把以上两个类创建好后,还要创建一个工厂类,用于生产自定义数据源,该工厂类代码如下: package test; import net.sf.jasperreports.engine.JRDataSource; publicclass TestCustomJRDataSourceFactory { publicstatic JRDataSource test() { returnnew TestBeanDataSource(); } } 2.由于是自定义数据源,因此要将数据源引用的相关类,全部引入ireport的classpath,以供ireport调用,否则ireport会抛 java.lang.ClassNotFoundException,例如我以上三个类都是放在d:/workspace/jasperreports /classes目录下,那么点 Options -> Classpath -> Add Folder 选择d:/workspace/jasperreports/classes,选择好后,点Save Classpath。3.在ireport中创建一个自定义数据源点Data -> Connections/Data Sources -> New -> Custom JRDataSource将弹出一窗口,根据提示填写内容,例:Name:testCustomFactory Class:test.TestCustomJRDataSourceFactoryThe static method to call…:test点击Test,弹出Connection test successful!,则代表自定义数据源配制成功,否则请检查错误。完成了这三步,就可以在ireport中使用该自定义数据源了。 如何激活数据源?创建好数据源后,ireport会自动激活它,由于同一时刻只能有一个数据源处于激活状态,所以当你想激活其它数据源时可如下操作:点Data -> Set Active Connection,在弹出的窗口中选择你要激活的数据源,再点OK就激活了。只有激活的数据源才会传给报表。5. 国际化 (I18N)国际化,又称I18N,因为国际化的英文是Internationalization,它以I开头,以N结尾,中间共18个字母。Jasprereports通过ResourceBundle类支持I18N。在ireport 中如何配制支持I18N ?我们新建一个报表,报表名为I18NTest,然后点Edit -> Internationalization -> Locale Files -> Create New Locale,输入_zh_CN,按OK,此时创建了一个支持中文的.properties文件,它的文件名全写是 I18NTest_zh_CN.properties,存放在与报表文件在同一目录下,我们再建一个支持英文的.properties文件,单击 Create New Locale,输入_en,按OK。如果你对ResourceBundle类有些了解,那么你就会知道输入的是什么意思。创建属性文件后,下一步就是编辑它们,在Locale resource bundle窗口中,双击I18NTest_zh_CN.properties,此时即可对编辑属性文件,我们在属性文件中增加一条i18n=嗨!国际 化,然后保存。再编辑I18NTest_en.properties,在属性文件中增加一条i18n=hello I18n,保存。以上操作即配制好了ireport支持i18n。如何调用显示属性文件内容?在报表的任何一个区域都可以调用属性文件显示内容。调用语法:$R{key} 或 str(key)例:如要调用上面所配制的属性,使用 $R{i18n} 或 str(“i18n”)格式化消息使用msg(pattern, arg1 )例:msg(”my name is {0}.”,”zhannggle”) 则输出:my name is zhanngle.msg()有三个重载方式,msg(pattern,arg1), msg(pattern,arg1,arg1), msg(pattern,arg1,arg1,arg1)区别就是参数不同而已,底层是通过MessageFormat.format(pattern,arguments)实现的。使用属性文件格式化消息。例有一属性文件定义如下:a=jasperreportsb=ireporthi=hello {0},hello {1}! 我们可以使用以下表达式显示消息msg(str(“hi”),str(“a”),str(“b”)) 输出:hello jasperreports,hello ireport!在web 开发中如何存放属性文件?将属性文件存放到WEB-INF/classes目录下,jasprereports会去这个目录搜索它。提示:只要配制好ireport支持I18N,就可以到报表文件存放目录找到自动生成好的属性文件,将它们拷到WEB-INF/classes目录下就可以了。[ 讨论]: jasperreports是通过 ResourceBundle.getBundle()获取属性文件,而getBundle()有三种重载方式 getBundle(baseName),getBundle(baseName,locale),getBundle(baseName,locale,loader)不知jasperreports是采用哪种方式,如果采用第一种,则根据服务器系统默认语言获取属性文件,而不管客户端请求哪种语言,如采用第 二、三种,则会根据客户端请求语言去获取属性文件。而我在做测试时,不管将客户端设置成何种语言,都返回服务器系统默认语言,郁闷的,不知是我哪里错 了,还是jasperreports采用了第一种方式去获取属性文件,没测出来,遗憾的,要查看源码才知道。 6. 脚本脚本是一个java类,它用来执行指定的细节在打印期间。脚本中的一些方法被报表引擎的调用,当一些特殊的事件,像创建一个新页或者处理detail 行。实现一个脚本得继承net.sf.jasperreports.engine.JRAbstractScriptlet类。net.sf.jasperreports.engine.JRAbstractScriptlet的声明如下: package net.sf.jasperreports.engine; /** * @author Teodor Danciu (teodord@users.sourceforge.net) * @version $Id: JRDefaultScriptlet.java,v 1.3 2004/06/01 20:28:22 teodord Exp $ */ public class JRDefaultScriptlet extends JRAbstractScriptlet { public JRDefaultScriptlet() { } public void beforeReportInit() throws JRScriptletException { } public void afterReportInit() throws JRScriptletException { } public void beforePageInit() throws JRScriptletException { } public void afterPageInit() throws JRScriptletException { } public void beforeColumnInit() throws JRScriptletException { } public void afterColumnInit() throws JRScriptletException { } public void beforeGroupInit(String groupName) throws JRScriptletException { } public void afterGroupInit(String groupName) throws JRScriptletException { } public void beforeDetailEval() throws JRScriptletException { } public void afterDetailEval() throws JRScriptletException { } } 在ireport 中如何配制脚本?Ireport默认不使用脚本,我们可以如下操作,使它使用脚本。首先新建一个报表文档,报表名TestScriptlet然后点Edit -> Report Properties -> Scriptlet Class -> Use ireport internal scriptlet support此时ireport已经使用了一个内部定义好的脚本,该脚本是个空壳子,没有实现任何功能。我们也可以编辑该脚本类,如下操作:点Edit -> Scriptlet Editor,此时会弹出一个编辑脚本类的窗口,找到该脚本构造方法,在构造方法中添加一条语句:System.out.println(“create scriptlet…”);在构造方法下面添加一个max方法,整个代码如下所示: import net.sf.jasperreports.engine. * ; public class < ScriptletClassName > extends it.businesslogic.ireport.IReportScriptlet { /** Creates a new instance of JRIreportDefaultScriptlet */ public < ScriptletClassName > () { System.out.println( " create scriptlet... " ); } public int max( int a, int b) { if (a >= b) return a; return b; } } 然后点Save保存,即创建了一个脚本,并再保存报表文件,此时你可以到报表文件目录找到一个TestScriptleScriptlet的java文件,这就是ireport自动生成的脚本类文件(脚本类名= 报表名+Scriptlet)。在ireport 中如何调用脚本?在报表创建时jasperreports会自动创建脚本对象,并在生成脚本时,jasperreports会自动调用相应的脚本方法,自定义的方法需要我们手动调用才会执行。例调用上面的max方法,可使用表达式:((TestScriptletScriptlet)$P{REPORT_SCRIPTLET}).max ( 23,64)$P{REPORT_SCRIPTLET}返回当前报表的脚本类大家可以根据以上表达式举一反三调用脚本。在web 项目中如何配制脚本?当在web项目中使用脚本时,就不能按照上面的方式配制了,那样会找不到脚本类的。解决办法如下4步:1.在ireport的lib目录下找到ireport.jar,将它引入到项目中。2.将ireport自动生成的java文件复制到项目src目录下(打包也行)。3.编译项目后,将该项目的classes目录添加到ireport的classpath中。4.点Edit -> Report Properties -> Scriptlet Class -> Use this scriptlet class…,在下面的文本框输入脚本类名,如打了包,要输入包名,点OK,编译ireport。 7. 子报表未完待续...8. 图表 ( 饼图 , 柱图 , 线图 )未完待续...9. 导出 pdf,xls,html...以下是我导出各种报表Servlet源代码,供大家参考! package servlet; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import oracle.jdbc.driver.OracleDriver; import test.TestBeanDataSource; import net.sf.jasperreports.engine.JRAbstractExporter; import net.sf.jasperreports.engine.JREmptyDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.JasperRunManager; import net.sf.jasperreports.engine.base.JRBaseReport; import net.sf.jasperreports.engine.export.JExcelApiExporter; import net.sf.jasperreports.engine.export.JRHtmlExporter; import net.sf.jasperreports.engine.export.JRHtmlExporterParameter; import net.sf.jasperreports.engine.export.JRXlsExporterParameter; import net.sf.jasperreports.engine.export.JRXmlExporter; import net.sf.jasperreports.engine.util.JRLoader; import net.sf.jasperreports.j2ee.servlets.ImageServlet; publicclass ExportReportServlet extends HttpServlet { /** *Destructionoftheservlet.<br> */ publicvoid destroy() { super .destroy(); // Just puts "destroy" string in log // Put your code here } publicvoid doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String view = request.getParameter( " view " ); if (view == null || view.trim().length() == 0 ) return ; if (view.equalsIgnoreCase( " html " )) doHtml(request,response); if (view.equalsIgnoreCase( " pdf " )) doPdf(request,response); if (view.equalsIgnoreCase( " xls " )) doExcel(request,response); if (view.equalsIgnoreCase( " xml " )) doXml(request,response); } privatevoid doHtml(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); // String jrxml=context.getRealPath("/WEB-INF/reports/Test1.jrxml"); /* try { String jasper=context.getRealPath("/WEB-INF/reports/Test1.jasper"); String html="/reports/"+System.currentTimeMillis()+".html"; JasperRunManager.runReportToHtmlFile(jasper,context.getRealPath(html),new HashMap(),getConn()); response.sendRedirect(request.getContextPath()+html); } catch (JRException e) { e.printStackTrace(); } */ String reportDir = context.getRealPath( " /WEB-INF/reports " ); String jasper = reportDir + " /Test1.jasper " ; response.setContentType( " text/html " ); response.setCharacterEncoding( " utf-8 " ); Map map = new HashMap(); Map imageMap = new HashMap(); map.put( " exportType " , " html " ); map.put( " imageTest " ,context.getRealPath( " /reports/star.gif " )); map.put( " SUBREPORT_DIR " ,reportDir + " / " ); request.getSession().setAttribute( " IMAGES_MAP " , imageMap); Connection conn = getConn(); try { // JasperPrint print=JasperFillManager.fillReport(jasper,map,new TestBeanDataSource()); JasperPrint print = JasperFillManager.fillReport(jasper,map,conn); // JasperPrint print=JasperFillManager.fillReport(jasper,map,new JREmptyDataSource()); JRHtmlExporter exporter = new JRHtmlExporter(); request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,print); exporter.setParameter(JRExporterParameter.JASPER_PRINT, print); exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter()); exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP,imageMap); exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + " /servlets/image?image= " ); exporter.setParameter(JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.TRUE); exporter.exportReport(); } catch (JRException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); response.setContentType( " text/plain " ); response.getOutputStream().print(sw.toString()); } finally { if (conn != null ) try { if ( ! conn.isClosed()) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } privatevoid doPdf(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); // String jrxml=context.getRealPath("/WEB-INF/reports/Test1.jrxml"); String reportDir = context.getRealPath( " /WEB-INF/reports " ); String jasper = reportDir + " /Test1.jasper " ; response.setContentType( " application/pdf " ); Map map = new HashMap(); map.put( " exportType " , " pdf " ); map.put( " imageTest " ,context.getRealPath( " /reports/star.gif " )); map.put( " SUBREPORT_DIR " ,reportDir + " / " ); Connection conn = getConn(); try { OutputStream os = response.getOutputStream(); InputStream is = new FileInputStream(jasper); JasperRunManager.runReportToPdfStream(is,os,map,conn); // JasperRunManager.runReportToPdfStream(is,os,map,new TestBeanDataSource()); os.flush(); os.close(); } catch (JRException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); response.setContentType( " text/plain " ); response.getOutputStream().print(sw.toString()); } finally { if (conn != null ) try { if ( ! conn.isClosed()) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } privatevoid doExcel(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); String reportDir = context.getRealPath( " /WEB-INF/reports " ); String jasper = reportDir + " /Test1.jasper " ; response.setContentType( " application/vnd.ms-excel " ); response.setHeader( " Content-Disposition " , " attachment;filename=Test1.xls " ); Map map = new HashMap(); map.put( " exportType " , " xls " ); // 设置参数,导出类型为xls map.put( " imageTest " ,context.getRealPath( " /reports/star.gif " )); // 设置参数,图片路径 map.put( " SUBREPORT_DIR " ,reportDir + " / " ); Connection conn = getConn(); try { JasperReport report = (JasperReport)JRLoader.loadObject(jasper); try { // 设置上边距,左边距,右边距,下边距为0 java.lang.reflect.Field margin = JRBaseReport. class .getDeclaredField( " leftMargin " ); margin.setAccessible( true ); margin.setInt(report, 0 ); margin = JRBaseReport. class .getDeclaredField( " topMargin " ); margin.setAccessible( true ); margin.setInt(report, 0 ); margin = JRBaseReport. class .getDeclaredField( " rightMargin " ); margin.setAccessible( true ); margin.setInt(report, 0 ); margin = JRBaseReport. class .getDeclaredField( " bottomMargin " ); margin.setAccessible( true ); margin.setInt(report, 0 ); // 去掉Excel中隐藏的行,技巧 java.lang.reflect.Field pageHeight = JRBaseReport. class .getDeclaredField( " pageHeight " ); pageHeight.setAccessible( true ); pageHeight.setInt(report, Integer.MAX_VALUE); // Don't print group header on each page if ( null != report.getGroups()) { for ( int i = 0 ; i < report.getGroups().length; i ++ ) { report.getGroups()[i].setReprintHeaderOnEachPage( false ); } } } catch (Exception e) { e.printStackTrace(); } JasperPrint print = JasperFillManager.fillReport(report,map,conn); // 填充数据 // JasperPrint print=JasperFillManager.fillReport(report,map,new TestBeanDataSource()); // 填充数据 JRAbstractExporter exporter = new JExcelApiExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT,print); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM,response.getOutputStream()); 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(); response.getOutputStream().flush(); response.getOutputStream().close(); } catch (JRException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); response.setContentType( " text/plain " ); response.getOutputStream().print(sw.toString()); } finally { if (conn != null ) try { if ( ! conn.isClosed()) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } privatevoid doXml(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); // String jrxml=context.getRealPath("/WEB-INF/reports/Test1.jrxml"); String reportDir = context.getRealPath( " /WEB-INF/reports " ); String jasper = reportDir + " /Test1.jasper " ; response.setContentType( " text/xml " ); Map map = new HashMap(); map.put( " exportType " , " xml " ); map.put( " imageTest " ,context.getRealPath( " /reports/star.gif " )); map.put( " SUBREPORT_DIR " ,reportDir + " / " ); Connection conn = getConn(); try { JasperPrint print = JasperFillManager.fillReport(jasper,map,conn); OutputStream os = response.getOutputStream(); JasperExportManager.exportReportToXmlStream(print,os); os.flush(); os.close(); } catch (JRException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); response.setContentType( " text/plain " ); response.getOutputStream().print(sw.toString()); } finally { if (conn != null ) try { if ( ! conn.isClosed()) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } privatestatic Connection getConn() { try { Class.forName(OracleDriver. class .getName()); return DriverManager.getConnection( " jdbc:oracle:thin:@202.192.xxx.xxx:1521:orc92 " , " name " , " password " ); } catch (Exception e) { e.printStackTrace(); } returnnull; } /** *Initializationoftheservlet.<br> * *@throwsServletExceptionifanerroroccure */ publicvoid init() throws ServletException { // Put your code here } } ?