POI与Struts2的使用 poi-2.5.1.jar

一.POI 简介

Jakarta POI 是apache的子项目,目标是处理ole2对象。它提供了一组操纵Windows文档的Java API

目前比较成熟的是HSSF接口,处理MS Excel(97-2002)对象。它不象我们仅仅是用csv生成的没有格式的可以由Excel转换的东西,而是真正的Excel对象,你可以控制一些属性如sheet,cell等等。

 

二.HSSF概况

HSSF 是Horrible SpreadSheet Format的缩写,也即“讨厌的电子表格格式”。 也许HSSF的名字有点滑稽,就本质而言它是一个非常严肃、正规的API。通过HSSF,你可以用纯Java代码来读取、写入、修改Excel文件。

HSSF 为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。前者很好理解,后者比较抽象,但操作效率要高得多。

 

三.开始编码

 

可以到 http://www.apache.org/dyn/closer.cgi/jakarta/poi / 最新的POI 工具包

 

HSSFWorkbook excell 文档对象介绍
HSSFSheet excell的表单
HSSFRow excell的行
HSSFCell excell的格子单元
HSSFFont excell字体
HSSFName 名称
HSSFDataFormat 日期格式
在poi1.7中才有以下2项:
HSSFHeader sheet头
HSSFFooter sheet尾
和这个样式
HSSFCellStyle cell样式
辅助操作包括
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 错误信息表

(以上部分转自http://ltc603.iteye.com/blog/30184)

 

在我们在Service编写操作如下:

package com.mengya.service.imple;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.mengya.dao.UsersDaoInter;
import com.mengya.entity.Users;
import com.mengya.service.UsersServiceInter;

public class UsersService implements UsersServiceInter {

	private UsersDaoInter usersdao = null;

	public void setUsersdao(UsersDaoInter usersdao) {
		this.usersdao = usersdao;
	}

	@SuppressWarnings("unchecked")
	public InputStream exportUsers() {
		// 创建一个HSSFWorkbook
		HSSFWorkbook wb = new HSSFWorkbook();
		// 由HSSFWorkbook创建一个HSSFSheet
		HSSFSheet sheet = wb.createSheet();
		// 由HSSFSheet创建HSSFRow
		HSSFRow row = sheet.createRow(0);

		HSSFCell cell = row.createCell((short) 0);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("序号");

		cell = row.createCell((short) 1);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("姓");

		cell = row.createCell((short) 2);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("名字");

		cell = row.createCell((short) 3);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("年龄");

		List<Users> userList = this.findAll();
		for (int i = 0; i < userList.size(); i++) {
			Users user = userList.get(i);
			row = sheet.createRow(i + 1);
			cell = row.createCell((short) 0);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(i+1);

			cell = row.createCell((short) 1);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getUfristName());

			cell = row.createCell((short) 2);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getUlastName());

			cell = row.createCell((short) 3);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getUage());
		}
		
		//方法一:生成xls文件到硬盘上,然后再删除该文件(启动一个线程或Servlet启动时删除)
		//自己的方法产生随机的字符串作为文件名
                //参见(http://zmx.iteye.com/admin/blogs/477460)
		//String fileName=RandomFileName2.getRandomString(10);
		//使用apache的commons-lang.jar产生随机的字符串作为文件名
		String fileName=RandomStringUtils.randomAlphanumeric(10);
		//生成xls文件名必须要是随机的,确保每个线程访问都产生不同的文件
		StringBuffer sb=new StringBuffer(fileName);
		final File file = new File(sb.append(".xls").toString());
		try {
			OutputStream os=new FileOutputStream(file);
			try {
				wb.write(os);
				os.close();
			} catch (IOException e) {
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		InputStream is=null;
		try {
			is=new FileInputStream(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		//生成一个线程,splee15秒删除该文件
		new Thread(new Runnable(){

			public void run() {
				try {
					Thread.sleep(15000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				file.delete();
			}
			
		}).start();
		
		return is;

	}
}

 

   对于上面的方法如果服务器停止可能导致有些文件没有删除可能会越来越多,对于tomcat该文件放在tomcat的bin目录中。故我们可以用一个Servlet在服务器启动时删除这些垃圾文件。Servlet如下:

/**
 * 服务器启动时清除服务器中的垃圾文件
 * 
 * @author 张明学
 * 
 */
@SuppressWarnings("serial")
public class DeleteExlFileServlet extends HttpServlet {

	public void destroy() {
		super.destroy();
	}

	public void init() throws ServletException {
		/**第一种方式删除
		 * File file = new File(".");对于tomcat得到的是bin目录
		File file = new File(".");
		File[] subFiles = file.listFiles();
		for (File f : subFiles) {
			if (f.getName().endsWith(".xls")) {
				f.delete();
			}
		}
		**/
		
		File file = new File(".");
		File[] subFiles = file.listFiles(new FileFilter() {
			public boolean accept(File pathname) {
				if (pathname.getName().endsWith(".xls")) {
					return true;
				}
				return false;
			}
		});
		for (File f : subFiles) {
			f.delete();
		}
	}

}

 该Servlet在web.xml中配置如下:

<!-- 该serlvet不需用户访问服务启时执行init就可以了-->
	<servlet>
		<description>服务器启动时删除服务器中的垃圾文件</description>
		<servlet-name>DeleteExlFileServlet</servlet-name>
		<servlet-class>
			com.mengya.servlet.DeleteExlFileServlet
		</servlet-class>
                <!-- 指定服务器启动时执行的次序 -->
		<load-on-startup>10</load-on-startup>
	</servlet>

action中调用该service:

@SuppressWarnings("serial")
public class ExportUsersAction extends ActionSupport {
	private UsersServiceInter userService;

	public void setUserService(UsersServiceInter userService) {
		this.userService = userService;
	}

	@Override
	public String execute() throws Exception {

		return SUCCESS;
	}

	public InputStream getDownloadFile

() {
		return userService.exportUsers();
	}
}

 

struts.xml中的配置如下:

<!-- 将用户信息用Excel导出 -->
		<action name="exportUsers" class="exportUsersAction">
			<result name="success" type="stream">
				<!-- 指定文件下载类型 -->
				<param name="contentType">application/vnd.ms-excel</param>
				<!-- 对于第一个参数默认值为inline这样的话若在线打开的话会生成两个xls文件 -->
				<param name="contentDisposition">attachment;filename="allUsers.xls"</param>
				<param name="inputName">downloadFile

</param>
			</result>
		</action>

 

 

到些第一种方法就写完了,还有一种方法可以不生成Excel文件而是返回一个该xls文件的InputStream

Service中的方法如下:

 

import java.util.List;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.mengya.dao.UsersDaoInter;
import com.mengya.entity.Users;
import com.mengya.service.UsersServiceInter;

public class UsersService implements UsersServiceInter {

	private UsersDaoInter usersdao = null;
        
        public void setUsersdao(UsersDaoInter usersdao) {
		this.usersdao = usersdao;
	}   
        
	@SuppressWarnings("unchecked")
	public InputStream exportUsers() {
		// 创建一个HSSFWorkbook
		HSSFWorkbook wb = new HSSFWorkbook();
		// 由HSSFWorkbook创建一个HSSFSheet
		HSSFSheet sheet = wb.createSheet();
		// 由HSSFSheet创建HSSFRow
		HSSFRow row = sheet.createRow(0);

		HSSFCell cell = row.createCell((short) 0);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("序号");

		cell = row.createCell((short) 1);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("姓");

		cell = row.createCell((short) 2);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("名字");

		cell = row.createCell((short) 3);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("年龄");

		List<Users> userList = this.findAll();
		for (int i = 0; i < userList.size(); i++) {
			Users user = userList.get(i);
			row = sheet.createRow(i + 1);
			cell = row.createCell((short) 0);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(i+1);

			cell = row.createCell((short) 1);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getUfristName());

			cell = row.createCell((short) 2);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getUlastName());

			cell = row.createCell((short) 3);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getUage());
		}
		
		/**
		 * 方法二:在内存中返回该InputStream,不生成文件到硬盘上 
		 */
		ByteArrayOutputStream os=new ByteArrayOutputStream();
		try {
			wb.write(os);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		byte[] bytes=os.toByteArray();
		InputStream is=new ByteArrayInputStream(bytes);
		return is;
	}
}

 action中的调用和struts.xml中配置同上面的一样。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值