首页 > 代码库 > javaweb+jasperreports报表+struts2

javaweb+jasperreports报表+struts2

本文将详细介绍javaweb中采用struts2框架的jasperreports报表开发方法,数据源选取的是connection。模板选取的是编译后的模板(jasper格式文件)。

网上很多教程采用了jasperreports-3.x.x的api ,本文采用jarjasperreports-5.6.0.jar的api,两个版本的区别还是很大的,3.x.x版本的很多方法已经过时废弃了。

建议统一采用jarjasperreports-5.6.0.jar版本,因为生成报表的这些工具目前都有,jar包也齐全。3.x.x版的开发工具有,但是配套的jar包只能一个一个找了,另外很多方法已经过时了。

jasperreports的数据源可以有多种,list,JavaBean,connection等,为了不跟后台service层和dao层等关联起来,我们采用connection作为数据源。(因为后台如果用到了hibernate等框架,list,JavaBean等获取数据源就要做大量工作:写JavaBean,写映射文件等;采用connection数据源的话我们可以把sql语句写在模板中,在action中只是传map格式的参数和connection连接就可以了)

action中需要的HttpServletResponse对象和ServletContext对象可以通过实现ServletResponseAware和ServletContextAware接口来得到。更多方法可以参照此链接

jasperreports类里面的路径处理很纠结,为了方便期间统一使用servletContext的getRealPath方法来处理。

选择编译后的模版,可以减轻服务器负载,另外在action中编译的话,很容易因为编译器版本和产生报表工具版本不一致导致编译期间出错。jdt-compiler-3.1.1.jar和jasperreports-5.6.0.jar是匹配的。另外jaspersoft和ireport里面可以很方便的编译。(下面的实例代码pdf方法中中包含了编译)

相关代码、工具、参考文档、源码等下载链接


一、利用struts2,action中不配置result,当然action中对应方法就不用返回值了,利用JRExporter对象的exportReport()输出到浏览器端。

1.开发jrxml格式的报表文件,可以用jaspersoft-studio或者ireport开发。将其放入我们web项目的WebRoot目录下。

2.将jrxml格式的文件编译为jasper格式的文件。

3.给jasper格式的文件填充数据并生成jrprint格式文件或流(不可以生成别的文件格式,jrprint格式的文件可以序列化)。比如:使用JasperFillManager.fillReport生成jrprint格式的文件。

4.利用JRExporter接口的具体实现类HtmlExporter、JRPdfExporter、JRXlsExporter等导出类将jrprint格式的文件生成html、pdf、xls格式的文件,并且导出到response的OutputStream流,从而输出到浏览器页面上。(当然也可以用JasperExportManager来代替前面的JRExporter实现类,不过该类只能处理3中格式(pdf、html、xml)的文件,要处理其他格式就要用具体的JRExporter具体实现类)

以上流程可参考下图(图片来源于网络)


开发流程中涉及的JasperReports相关类



二、利用struts2,action中不配置result,action中对应方法无返回值,在action中直接调用HttpServletResponse类的OutputStream类对象进行输出,从而输出到浏览器端。

1.开发jrxml格式的报表文件,可以用jaspersoft-studio或者ireport开发。将其放入我们web项目的WebRoot目录下。

2.将jrxml格式的文件编译为jasper格式的文件。

3..给jasper格式的文件填充数据并输出到response的OutputStream流。可以利用JasperRunManager的相关方法搞定。另外JasperRunManager一些方法可以在硬盘上生成html、pdf、xsl等格式文件。

4.利用HttpServletResponse的setContentType方法设置返回数据类型,最后利用OutputStream类的flush()方法和close()方法输出到浏览器。


三、利用struts2,action中配置result,对应方法当然需要返回值了,result类型选择stream。需要配置响应内容的格式contentType,输出到浏览器的inputName(该参数的值是一个InputStream流,我们可以将生成的pdf、html、xsl文件通过new FileInputStream来产生输入流)等。

1.开发jrxml格式的报表文件,可以用jaspersoft-studio或者ireport开发。将其放入我们web项目的WebRoot目录下。

2.将jrxml格式的文件编译为jasper格式的文件。

3.利用JasperRunManager的相关方法生成具体格式的(pdf,html等)文件,利用new FileInputStream产生InputStream流对象。剩下的交给struts2配置文件。



上面的3种方法对应的实例代码如下:(分别对应pdf1、pdf2、pdf3方法,其中pdf方法包含将jrxml格式编译为jasper)

struts.xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <constant name="struts.devMode" value=http://www.mamicode.com/"true" />>
action代码

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimplePdfExporterConfiguration;

import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.util.ServletContextAware;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport implements ServletResponseAware, ServletContextAware{
	
	HttpServletResponse response;
	ServletContext servletContext;
	InputStream inputStream;
	


	public void pdf() {
		long start = System.currentTimeMillis();
		try {
			//数据库连接
			Class.forName("com.mysql.jdbc.Driver");
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=flf1989317");
			
			String reportSource = servletContext.getRealPath("/jasper/jasper_template.jrxml");
			System.out.println(reportSource);
			File parent = new File(reportSource).getParentFile();
			String reportDestination = new File(parent,"complied_jasper_template.jasper").getAbsolutePath();
			
			
			//将未编译.jrxml格式的报表文件编译并产生.jasper格式的报表文件
			JasperCompileManager.compileReportToFile(reportSource,reportDestination);
			//获得输出流
			ServletOutputStream servletOutputStream = response.getOutputStream();
			//获得jasper报表文件的输入流
			InputStream inputStream = new FileInputStream(reportDestination);
			//生成传数据的Map对象
			HashMap hm = new HashMap();
			hm.put("test", new Integer(20));
			
			//生成pdf文档格式的输出流
			JasperRunManager.runReportToPdfStream(inputStream,servletOutputStream,hm,conn);
			response.setContentType("application/pdf");
			servletOutputStream.flush();
			servletOutputStream.close();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.err.println("Filling time : " + (System.currentTimeMillis() - start));
	}
	
	
public void pdf1() {
		
		long start = System.currentTimeMillis();
		try {
			//生成传数据的Map对象
			HashMap hm = new HashMap();
			hm.put("test", new Integer(20));
			//数据库连接
			Class.forName("com.mysql.jdbc.Driver");
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=flf1989317");
			String jasperFile = servletContext.getRealPath("/jasper/complied_jasper_template.jasper");
			//JasperPrint jasperPrint = JasperFillManager.fillReport(jasperFile, hm, conn);
			String jrprintPath = servletContext.getRealPath("/jasper/template.jrprint");
			//File jrprintFile = new File(jrprintPath);
			JasperFillManager.fillReportToFile(jasperFile, jrprintPath, hm, conn);
			
			
			JRPdfExporter exporter = new JRPdfExporter();
			//exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
			exporter.setExporterInput(new SimpleExporterInput(jrprintPath));
			
			//String pdfFilePath = servletContext.getRealPath("/jasper/template.pdf");
			//输出到硬盘上
			//exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(pdfFilePath));
			//输出到响应流,展现在浏览器上
			exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream()));
			SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
			//可以通过configuration对象设置输出pdf文档的各种属性
			//configuration.setCreatingBatchModeBookmarks(true);
			exporter.setConfiguration(configuration);
			exporter.exportReport();
			
			
        } catch (Exception e) {
            e.printStackTrace();
        }
		
        System.err.println("Filling time : " + (System.currentTimeMillis() - start));
	}
	
	
	public void pdf2() {
		long start = System.currentTimeMillis();
		try {
			//数据库连接
			Class.forName("com.mysql.jdbc.Driver");
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=flf1989317");
			String reportDestination = servletContext.getRealPath("/jasper/complied_jasper_template.jasper");
			ServletOutputStream servletOutputStream = response.getOutputStream();
			//获得jasper报表文件的输入流
			InputStream inputStream = new FileInputStream(reportDestination);
			//生成传数据的Map对象
			HashMap hm = new HashMap();
			hm.put("test", new Integer(20));
			//生成pdf文档格式的输出流
			JasperRunManager.runReportToPdfStream(inputStream,servletOutputStream,hm,conn);
			response.setContentType("application/pdf");
			servletOutputStream.flush();
			servletOutputStream.close();
			
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.err.println("Filling time : " + (System.currentTimeMillis() - start));
	}
	
	public String pdf3() {
		long start = System.currentTimeMillis();
		try {
			//数据库连接
			Class.forName("com.mysql.jdbc.Driver");
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=flf1989317");
			String reportDestination = servletContext.getRealPath("/jasper/complied_jasper_template.jasper");
			String pdfFilePath = servletContext.getRealPath("/jasper/template.pdf");
			HashMap hm = new HashMap();
			hm.put("test", new Integer(20));
			
			JasperRunManager.runReportToPdfFile(reportDestination, pdfFilePath, hm, conn);
			inputStream = new FileInputStream(pdfFilePath);
			
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.err.println("Filling time : " + (System.currentTimeMillis() - start));
		return SUCCESS;
	}
	
	

	public void setServletResponse(HttpServletResponse response) {
		// TODO Auto-generated method stub
		this.response = response;
	}


	public void setServletContext(ServletContext servletContext) {
		// TODO Auto-generated method stub
		this.servletContext = servletContext;
		
	}


	public InputStream getInputStream() {
		return inputStream;
	}

	
}



四、利用struts2的jasperreports插件完成报表的输出到浏览器。此插件需要jasper格式的文件,填充jasper格式的文件的数据源dateSource(可以参考jasperReports的api生成),输出的类型格式(HTML、PDF等)。

因为struts2-jasperreports-plugin-2.3.14.jar插件对应的是jasperreports-3.1.2.jar版本,因此如果用高版本的jasperreports或者ireport工具生成jasper格式的文件,用到此处就会产生一些冲突。固不给出与此方法相关的例子代码。

struts.xml的配置可以参考如下:

<package name="default"extends="jasperreports-default">
	<action name="PDF" class="XXX">
            <result name="success" type="jasper">
                <param name="location">
                    /jasper/template.jasper
                </param>
                <param name="dataSource">YYY</param>
                <param name="format">PDF</param>
            </result>
        </action>
</package>



javaweb+jasperreports报表+struts2