JasperReport+Servlet Web应用之:打印

关于JasperReport的简介大家可以去google上去查,在这里就不作介绍了。

 

我的开发环境:MyEclipse 5.5 GA+iReport-nb-3.5.2。所用的JasperReport版本也是:jasperreports-3.5.2

所需要的jar可以从下面的lib1,lib2中获得,所有jar包除了iTextAsian.jar外都可以从jasperreports-3.5.2中找到!

 

JasperReport要和iReport一起使用开发起来才比较方便,要注意的是中文显示问题,设计模板的时候要注意以下三点:

Font   name:    宋体 (中文字体)
PDF    font name:   STSong-Light
PDF    Encoding:  UniGB-UCS2-H(Chinese Siplified)
PDF    Embeded: √

在应用程序中添加iTextAsian.jar

 

第一步:用iReport设计JasperReport模板并编译。结果有两个文件:preson.jrxml(模板文件),preson.jasper(编译文件)。在WebRoot下面新建文件夹jasper,将这两个文件放到该文件夹中。

 

第二步:构造我们的实体Bean

public class Person {
	private String person_Id;

	private String person_name;

	private String person_age;

	private String person_address;

	public Person() {

	}
	public Person(String id, String name, String age, String address) {
		this.person_Id = id;
		this.person_name = name;
		this.person_age = age;
		this.person_address = address;
	}
	//get,set方法就省掉了
}

   

 第三步:构造我们的service

 

public class PersonService {
	public List<Person> getAllPerson() {
		List<Person> perList = new ArrayList<Person>();
		perList.add(new Person("101", "小博", "22", "湖北"));
		perList.add(new Person("102", "张三", "21", "湖南"));
		perList.add(new Person("103", "李四", "23", "江苏"));
		perList.add(new Person("104", "王五", "22", "上海"));
		return perList;
	}
} 

 

第四步:构造我们的JRDataSource

package com.mengya.JRDataSource;

import java.util.List;
import com.mengya.bean.Person;
import com.mengya.service.PersonService;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

/**
 * 填充JaserperReort数据
 * 
 * @author 张明学
 * 
 */
public class PersonDataSource implements JRDataSource {
	private int index = -1;

	private List<Person> personList = new PersonService().getAllPerson();

	public Object getFieldValue(JRField field) throws JRException {
		Object value = null;
		String fieldName = field.getName();
		if ("person_Id".equals(fieldName)) {
			value = personList.get(index).getPerson_Id();
		} else if ("person_name".equals(fieldName)) {
			value = personList.get(index).getPerson_name();
		} else if ("person_age".equals(fieldName)) {
			value = personList.get(index).getPerson_age();
		} else if ("person_address".equals(fieldName)) {
			value = personList.get(index).getPerson_address();
		}
		return value;
	}
	public boolean next() throws JRException {
		index++;
		return index < personList.size();
	}
}

  

第五步:构造我们的Servlet

public class JRPrintServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ServletContext context = this.getServletConfig().getServletContext();
		File reportFile = new File(context.getRealPath("/jasper/preson.jasper"));
		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("year", "2009");
		parameters.put("unit_mc", "武汉XX科技有限公司");
		JasperPrint jasperPrint = null;
		try {
			JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());
			jasperPrint = JasperFillManager.fillReport(jasperReport,parameters, new PersonDataSource());
		} catch (JRException e) {
			e.printStackTrace();
		}
		if (jasperPrint != null) {
			response.setContentType("application/octet-stream");
			ServletOutputStream ouputStream = response.getOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(ouputStream);
			oos.writeObject(jasperPrint);
			oos.flush();
			oos.close();
			ouputStream.flush();
			ouputStream.close();
		}
	}

}

  

web.xml中配置我们的servlet如下:

<servlet>
		<servlet-name>JRPrintServlet</servlet-name>
		<servlet-class>com.mengya.servlet.JRPrintServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>JRPrintServlet</servlet-name>
		<url-pattern>/JRPrintServlet</url-pattern>
	</servlet-mapping>

   

第六步:由于我们web打印是基于applet形式,故需要创建我们打印的applet如下:

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;

import javax.swing.JOptionPane;

import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.util.JRLoader;

public class JRPrinterApplet extends javax.swing.JApplet {
	private URL url = null;
	public void init() {
		String strUrl = getParameter("REPORT_URL");
		if (strUrl != null) {
			try {
				url = new URL(getCodeBase(), strUrl);// 从获得html参数中获得报表URL
				// System.out.println("url=" + url.toURI());//要是servlet的路径
			} catch (Exception e) {
				StringWriter swriter = new StringWriter();
				PrintWriter pwriter = new PrintWriter(swriter);
				e.printStackTrace(pwriter);
				JOptionPane.showMessageDialog(this, swriter.toString());
			}
		} else {
			JOptionPane.showMessageDialog(this, "Source URL not specified");
		}
	}
	
	public void start() {
		if (url != null) {
			try {
				Object obj = JRLoader.loadObject(url);// 发送对象请求,获得JasperPrint对象
				JasperPrintManager.printReport((JasperPrint) obj, true);// 调用方法打印所获得的JasperPrint对象
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

 

 

重点提示:需要在WebRoot下面新一个applet文件夹,将jasperreports-3.5.2-applet.jar,commons-logging-1.0.2.jar,commons-collections-2.1.jar三个包加进去,还要将上面的JRPrinterApplet编译后的文件放进去。

(applet最好不要加包名,如果加了包名要建一个如包名一样的文件夹路径再将applet编译后的文件放进去再把它放到与applet同一目录中去,否则老报找一到这个类)

 public final void setStub(AppletStub stub)
//设置Appletstub.stubJavaC之间转换参数并返回值的代码位,它是由系统自动设定的。
public boolean isActive();// 判断一个Applet是否处于活动状态。
public URL getDocumentBase();// 检索表示该Applet运行的文件目录的对象。
public URL getCodeBase();// 获取该Applet 代码的URL地址。
public String getParameter(String name)// 获取该Applet name指定参数的值。
public AppletContext getAppletContext()// 返回浏览器或小应用程序观察器。
public void resize(int width,int height)// 调整Applet运行的窗口尺寸。
public void resize(Dimension d)// 调整Applet运行的窗口尺寸。
public void showStatus(String msg)// 在浏览器的状态条中显示指定的信息。
public Image getImage(URL url) // url指定的地址装入图象。
public Image getImage(URL url,String name)// url指定的地址和文件名加载图像。
public AudioClip getAudioClip(URL url)// url指定的地址获取声音文件。
public AudioClip getAudioClip(URL url, String name)// url指定的地址和文件名获取声音。
public String getAppletInfo()// 返回Applet应用有关的作者、版本和版权方面的信息;
public String[][] getParameterInfo()
// 返回描述Applet参数的字符串数组,该数组通常包含三个字符串: 参数名、该参数所需值的类型和该参数的说明。
public void play(URL url)// 加载并播放一个url指定的音频剪辑。
public void destroy()//撤消Applet及其所占用的资源。若该Applet是活动的,则先终止该Applet的运行。

* CODE标志
  CODE标志指定Applet的类名;WIDTHHEIGHT标志指定Applet窗口的像素尺寸。在APPLET语句里还可使用其他一些标志。
  * CODEBASE 标志
  CODEBASE标志指定AppletURL地址。Applet的通用资源定位地址URL,它可以是绝对地址 ,如www.sun.com。也可以是相对于当前HTML所在目录的相对地址,如/AppletPath/Name。如果HTML文件不指定CODEBASE 标志,浏览器将使用和HTML文件相同的URL
  * ALT 标志
  虽然JavaWWW上很受欢迎,但并非所有浏览器都对其提供支持。如果某浏览器无法运行Java Applet,那么它在遇到APPLET语句时将显示ALT标志指定的文本信息。
  * ALIGN 标志
  ALIGN标志可用来控制把Applet窗口显示在HTML文档窗口的什么位置。与HTMLLMG>语句一样,ALIGN标志指定的值可以是TOPMIDDLEBOTTOM
  * VSPACEHSPACE 标志
  VSPACEHSPACE标志指定浏览器显示在Applet窗口周围的水平和竖直空白条的尺寸,单位为像素。如下例使用该标志在Applet窗口之上和之下各留出50像素的空白,在其左和其右各留出25像素的空白:
  * NAME 标志
  NAME标志把指定的名字赋予Applet的当前实例。当浏览器同时运行两个或多个Applet时,各Applet可通过名字相互引用或交换信息。如果忽略NAME标志,Applet的名字将对应于其类名。
  * PARAM 标志
  通用性是程序设计所追求的目标之一。使用户或者程序员能很方便地使用同一个Applet完成不同的任务是通用性的具体表现。从HTML文件获取信息是提高Applet通用性的一条有效途径。
  假设编制了一个把某公司的名字在屏幕上卷动的Applet。为了使该Applet更加通用,则可以使该AppletHTML文件获取需要卷动的文本信息。这样,若想显示另一个公司的名字,用不着修改Java Applet本身,只需修改HTML文件即可。
  PARAM 标志可用来在HTML文件里指定参数,格式如下所示:
PARAM Name="name" Value="Liter"
  Java Applet可调用getParameter方法获取HTML文件里设置的参数值。

第七步:构造我们的打印页面:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>打印窗口</title>
	</head>
	<script language="javascript"> 
	<!-- 
		function openApp() 
		{ 
			var url = "../JRPrintServlet"; 
			document.write('<APPLET ID="JrPrt" CODE = "JRPrinterApplet.class" CODEBASE = "applets" ARCHIVE = "jasperreports-3.5.2-applet.jar,commons-logging-1.0.2.jar,commons-collections-2.1.jar" WIDTH = "0" HEIGHT = "0">'); 
			document.write('<PARAM NAME = "type" VALUE="application/x-java-applet;version=1.2.2">'); 
			document.write('<PARAM NAME = "scriptable" VALUE="false">'); 
			document.write('<PARAM NAME = "REPORT_URL" VALUE ="'+url+'">'); 
			document.write('</APPLET>'); 
		}
		--> 
	</script>
	<body bgcolor="#FFFFFF">
		<input type="button" value="测试打印" onclick="openApp();">
		<!-- 不用上面的js只用下的标签也可以 -->
		<!-- 
		<APPLET CODE="JRPrinterApplet.class" CODEBASE = "applets"
			ARCHIVE = "jasperreports-3.5.2-applet.jar,commons-logging-1.0.2.jar,commons-collections-2.1.jar"
			WIDTH="300" HEIGHT="40">
			</XMP>
			<PARAM NAME=CODE VALUE="JRPrinterApplet.class">
			<PARAM NAME = ARCHIVE VALUE = "jasperreports-3.5.2-applet.jar,commons-logging-1.0.2.jar,commons-collections-2.1.jar" >
			<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2">
			<PARAM NAME="scriptable" VALUE="false">
			<PARAM NAME="REPORT_URL" VALUE="../JRPrintServlet">
		</APPLET>
		 -->
	</body>
</html>

  

 

 需要指出的是:该页面上的URL必须是servlet的路径。

 

其实上面的所有的东西都可以从jasperReprot自己带的demo中找到

在jasperreports-3.5.2-project\jasperreports-3.5.2\demo\samples\webapp中有web应用的例子。

 

打印需要在机器上按装jre-1_5_0_18-windows-i586-p.exe

 

你可能感兴趣的:(Web,.net,servlet,浏览器,swing)