当前位置: 代码迷 >> ASP >> JasperReport 在Spring中的使用 有关问题
  详细解决方案

JasperReport 在Spring中的使用 有关问题

热度:1081   发布时间:2012-11-07 09:56:10.0
JasperReport 在Spring中的使用 问题
最近看了《JasperReports for Java Developers》,里面讲了怎么在Spring里使用JasperReport
照着里面的例子做了一下,例子是没有问题的,但是我把展现方式改为由JasperReportsHtmlView 展现就出问题了,所有的图片都出不来,是不是使用JasperReportsHtmlView还要配置其它的拦截器或是什么?我在Google里找了一通,也没能解决主要是E文不太好国外的论坛也找了,看得头大,所以把代码贴出来,那位用过的能指点一下,谢过了

web配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>ReportWebApp</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>jasperSpring</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet 
        </servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>jasperSpring</servlet-name>
		<url-pattern>/jasperSpring/*</url-pattern>
	</servlet-mapping>
</web-app>


前台Jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Generate Report</title>
	</head>
<body>
			Click on the button to generate the report.
<form name="reportForm" action="jasperSpring/report" method="get"><input
	type="submit" name="submitButton" value="Submit" /></form>
</body>
</html>


jasperSpring-servlet.xml的内容:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
		</property>
		<property name="url">
			<value>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=Northwind</value>
		</property>
		<property name="username">
			<value>sa</value>
		</property>
		<property name="password">
			<value>sa</value>
		</property>
	</bean>
	<bean id="publicUrlMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="report">jasperController</prop>
			</props>
		</property>
	</bean>
	<bean id="jasperController"
		class="net.aachina.jasperreport.JasperSpringController">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
	</bean>
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
		<property name="basename" value="views" />
	</bean>
	<bean id="ImageServlet" class="net.sf.jasperreports.j2ee.servlets.ImageServlet">
	</bean>
</beans>


引用
views.properties中的内容

report.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
#report.class=org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView
#report.class=net.aachina.jasperreport.render.JasperReportsHtmlView
report.url=reports/ChartReportDemo.jasper


控制器JasperSpringController的源码:
package net.aachina.jasperreport;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import net.sf.jasperreports.engine.JRResultSetDataSource;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class JasperSpringController implements Controller {

	private DataSource dataSource;

	public ModelAndView handleRequest(HttpServletRequest request,	HttpServletResponse response) throws ServletException,	IOException, ClassNotFoundException, SQLException
	{
		
		return new ModelAndView("report", getModel());
	}

	@SuppressWarnings("unchecked")
	private Map getModel() throws ClassNotFoundException, SQLException
	{
		Connection connection;
		Statement statement;
		ResultSet resultSet;
		HashMap model = new HashMap();
		String query = "SELECT"+
			     " Employees.[LastName] AS Employees_LastName,"+
		              " Employees.[FirstName] AS Employees_FirstName,"+
		              " Employees.[EmployeeID] AS Employees_EmployeeID,"+
		              " Orders.[OrderID] AS Orders_OrderID,"+
		              " Orders.[OrderDate] AS Orders_OrderDate "+
		                "  FROM "+
" Employees INNER JOIN  Orders ON Employees.[EmployeeID] = Orders.[EmployeeID]";
		connection = dataSource.getConnection();
		statement = connection.createStatement();
		resultSet = statement.executeQuery(query);
		JRResultSetDataSource resultSetDataSource =new JRResultSetDataSource(resultSet);
		model.put("datasource", resultSetDataSource);
		return model;
		}
	
	public void setDataSource(DataSource dataSource) 
	{
		this.dataSource = dataSource;
	}
}


JasperReport页面在IReport中的效果:


页面输出PDF效果:


但把输出改为JasperReportsHtmlView页面上的所有图片都显示不出来,应该是还有什么属性值设置的不对,哪位知道的请指点一下,项目里面的Jar包太大了不然把整个项目都上传上来
1 楼 hejianhuacn 2007-11-07  
直接使用Servlet 可以正确的输出为HTML,代码为:
package net.aachina.jasperreport;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;

public class HtmlReportServlet extends HttpServlet {
	public static final String REPORT_DIRECTORY = "/reports";

	protected void doGet(HttpServletRequest request,
	HttpServletResponse response) throws ServletException, IOException {
		Connection connection;
		ServletContext context = this.getServletConfig().getServletContext();
		String reportName = "ChartReportDemo";
		PrintWriter printWriter = response.getWriter();
		InputStream reportStream = getServletConfig().getServletContext()
				.getResourceAsStream(
						"/" + REPORT_DIRECTORY + "/" + reportName + ".jasper");
		JasperPrint jasperPrint;
		try {
			Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
			connection = DriverManager
					.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=Northwind","sa","sa");
			
			
			jasperPrint = JasperFillManager.fillReport(reportStream,
					new HashMap(), connection);
			JRHtmlExporter htmlExporter = new JRHtmlExporter();
			response.setContentType("text/html");
			request.getSession().setAttribute(
					ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
					jasperPrint);
			
			htmlExporter.setParameter(JRExporterParameter.JASPER_PRINT,
					jasperPrint);
			htmlExporter.setParameter(JRExporterParameter.OUTPUT_WRITER,
					printWriter);
			htmlExporter.setParameter(JRHtmlExporterParameter.CHARACTER_ENCODING, "gb2312");
			htmlExporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
					"image?image=");
			htmlExporter.exportReport();
			connection.close();
			System.out.println("done!");
		} catch (Throwable t) {
			// display stack trace in the browser
			t.printStackTrace(printWriter);
		}
	}
}



web.xml修改为:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>
	ReportWebApp</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>jasperSpring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet>
		<servlet-name>ImageServlet</servlet-name>
		<servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>HtmlReportServlet</servlet-name>
		<servlet-class>
			net.aachina.jasperreport.HtmlReportServlet
		</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>jasperSpring</servlet-name>
		<url-pattern>/jasperSpring/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>HtmlReportServlet</servlet-name>
		<url-pattern>/htmlReport</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>ImageServlet</servlet-name>
		<url-pattern>/image</url-pattern>
	</servlet-mapping>
</web-app>


index.jsp的form action修改为:htmlReport

输出效果:图片上传不知道怎么编辑^_^
2 楼 hejianhuacn 2007-11-07  
终于解决了!
方法来源于:http://forum.springframework.org/showthread.php?t=25030 其实自己也应该想到的BS一下自己。为了不让后来人受累,我把代码再Copy过来使帖子完整^_^

package net.aachina.jasperreport.render;

import java.io.ByteArrayOutputStream;
import java.util.Map;

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

import org.springframework.ui.jasperreports.JasperReportsUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsSingleFormatView;
import org.springframework.web.util.WebUtils;

import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;

public class JasperReportsHtmlViewExtend extends
		AbstractJasperReportsSingleFormatView {

	private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 4096;

	public JasperReportsHtmlViewExtend() {
		setContentType("text/html; charset=UTF-8");
	}

	protected JRExporter createExporter() {
		JRHtmlExporter jrHtmlExporter = new JRHtmlExporter();
		jrHtmlExporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
				"image?image=");
		return jrHtmlExporter;
	}

	protected boolean useWriter() {
		return true;
	}

	@Override
	protected void renderReport(JasperPrint populatedReport, Map model,
			HttpServletResponse response) throws Exception {
		// TODO 自动生成方法存根
		if (model.containsKey("requestObject")) {
			HttpServletRequest request = (HttpServletRequest) model
					.get("requestObject");
			request.getSession().setAttribute(
					ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
					populatedReport);

		}
		// Prepare report for rendering.
		JRExporter exporter = createExporter();

		// Set exporter parameters - overriding with values from the Model.
		Map mergedExporterParameters = mergeExporterParameters(model);
		if (!CollectionUtils.isEmpty(mergedExporterParameters)) {
			exporter.setParameters(mergedExporterParameters);
		}

		if (useWriter()) {
			// We need to write text to the response Writer.

			// Copy the encoding configured for the report into the response.
			String contentType = getContentType();
			String encoding = (String) exporter
					.getParameter(JRExporterParameter.CHARACTER_ENCODING);
			if (encoding != null) {
				// Only apply encoding if content type is specified but does not
				// contain charset clause already.
				if (contentType != null
						&& contentType.toLowerCase().indexOf(
								WebUtils.CONTENT_TYPE_CHARSET_PREFIX) == -1) {
					contentType = contentType
							+ WebUtils.CONTENT_TYPE_CHARSET_PREFIX + encoding;
				}
			}
			response.setContentType(contentType);

			// Render report into HttpServletResponse's Writer.
			JasperReportsUtils.render(exporter, populatedReport, response
					.getWriter());
		}

		else {
			// We need to write binary output to the response OutputStream.

			// Apply the content type as specified - we don't need an encoding
			// here.
			response.setContentType(getContentType());

			// Render report into local OutputStream.
			// IE workaround: write into byte array first.
			ByteArrayOutputStream baos = new ByteArrayOutputStream(
					OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
			JasperReportsUtils.render(exporter, populatedReport, baos);

			// Write content length (determined via byte array).
			response.setContentLength(baos.size());

			// Flush byte array to servlet output stream.
			ServletOutputStream out = response.getOutputStream();
			baos.writeTo(out);
			out.flush();
		}
	}

}

看代码就应该能明白了,哎 为什么我就没想到这么写呢

对了控制器里面也要修改一下:
package net.aachina.jasperreport;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import net.sf.jasperreports.engine.JRResultSetDataSource;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class JasperSpringController implements Controller {

	private DataSource dataSource;

	public ModelAndView handleRequest(HttpServletRequest request,	HttpServletResponse response) throws ServletException,	IOException, ClassNotFoundException, SQLException
	{
		
		return new ModelAndView("report", getModel(request));
	}

	@SuppressWarnings("unchecked")
	private Map getModel(HttpServletRequest request) throws ClassNotFoundException, SQLException
	{
		Connection connection;
		Statement statement;
		ResultSet resultSet;
		HashMap model = new HashMap();
		String query = "SELECT"+
						    " Employees.[LastName] AS Employees_LastName,"+
						    " Employees.[FirstName] AS Employees_FirstName,"+
						    " Employees.[EmployeeID] AS Employees_EmployeeID,"+
						    " Orders.[OrderID] AS Orders_OrderID,"+
						    " Orders.[OrderDate] AS Orders_OrderDate "+
					   "  FROM "+
					     	" Employees INNER JOIN  Orders ON Employees.[EmployeeID] = Orders.[EmployeeID]";
		connection = dataSource.getConnection();
		statement = connection.createStatement();
		resultSet = statement.executeQuery(query);
		JRResultSetDataSource resultSetDataSource =new JRResultSetDataSource(resultSet);
		model.put("datasource", resultSetDataSource);
		model.put("requestObject",request);
		System.out.println("well done!");
		return model;
		}
	
	public void setDataSource(DataSource dataSource) 
	{
		this.dataSource = dataSource;
	}
}
3 楼 hejianhuacn 2007-11-12  
在上面的Controller中传入的是JRResultSetDataSource 如何传入Connection?因为报表文件里已经存在SQL语句了,如何直接传入Connection呢?这样最少页面看上去要整齐一点
4 楼 htp2002 2007-12-12  
这样做,connection何时关闭?

以下做法供参考:将datasource(jdbc)作为一个value放入model,这样spring的jasper相关view就会取到这个datasource,进而获取connection,fillreport后由spring关闭connection。

请参考代码AbstractJasperReportsView.fillReport
		JRDataSource jrDataSource = getReportData(model);

		if (jrDataSource != null) {
			// Use the JasperReports JRDataSource.
			if (logger.isDebugEnabled()) {
				logger.debug("Filling report with JRDataSource [" + jrDataSource + "].");
			}
			return JasperFillManager.fillReport(this.report, model, jrDataSource);
		}

		else {
			if (this.jdbcDataSource == null) {
				this.jdbcDataSource = (DataSource) CollectionUtils.findValueOfType(model.values(), DataSource.class);
			}

			if (this.jdbcDataSource != null) {
				// Use the JDBC DataSource.
				if (logger.isDebugEnabled()) {
					logger.debug("Filling report with JDBC DataSource [" + this.jdbcDataSource + "].");
				}
				Connection con = this.jdbcDataSource.getConnection();
				try {
					return JasperFillManager.fillReport(this.report, model, con);
				}
				finally {
					try {
						con.close();
					}
					catch (SQLException ex) {
						logger.debug("Could not close JDBC Connection", ex);
					}
				}
			}

			else {
				// Assume that the model contains parameters that identify
				// the source for report data (e.g. Hibernate or JPA queries).
				return JasperFillManager.fillReport(this.report, model);
			}
		}
5 楼 揣神再现 2008-08-05  
没有上传这个文件吗???ChartReportDemo.jasper
  相关解决方案