注意:本文针对对
Struts,Value List有一定使用经验的开发人员,如果你不是在web环境下使用
POI,建议你直接去看
POI的教程。
1.问题由来
在此之前,我一直用valuelist来完成查询并显示结果,效果不错。valuelist可以导出excel,csv,但是一用之下,并没有相象的那么好,它导出的excel并不是真正的excel文件,是一个html的文本文件,这样由于某些处理上的不完善,在我这里出现了导出的文件在打开时,表头和下面的内容错开,并且有多余的空列。如果对它的有关源代码进行修改,做到正常显示是没问题的,但是如果客户的需求再变一点点,比如要设置一定的格式,用它来做就不太方便了。所以我只好寻求另一种方案,最后终于找到
POI,看它的介绍很不错,按照它的指南一试之下,也很简单,于是决定就用它了。现在的问题就是怎样取得valuelist的查询结果,并且用
POI导出到Excel中。
2.从web页面动作时调用的Action
在我们真正用到的查询action里只要设置好三个属性值就可以了.
package com.sogoodsoft.test.export.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.*;
import com.sogoodsoft.framework.exporter.ExportBaseAction;
/**
* 导出查询的excel表
*
* @author Albert Song
* @version 1.0
*/
public class ExportQueryAction extends ExportBaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//列名,必须和applicationContext.xml中对应的sql的列名一致。
// 顺序不必一致
String colNames[]={"stu_no","stu_name"};
//Excel表的表头,列名对应的中文,必须和列名的顺序对应
String titleNames[]={"学号","姓名"};
//applicataionContext.xml中sql对应的id
String valueListName="testList";
// 这三项必须设置
setColNames(colNames);
setTitleNames(titleNames);
set
ValueListName(valueListName);
return super.export(mapping,form,request,response);
}
}
3.在ExportBaseAction 中取得valuelist的查询结果
valuelist可以不用
Struts单独使用,我这里是在
Struts中的用法,代码大概像这样
package com.sogoodsoft.framework.exporter;
import java.util.List;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.*;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import net.mlw.vlh.*;
import net.mlw.vlh.web.
ValueListRequestUtil;
import com.sogoodsoft.util.BaseAction;
/**
*
*
* @author Albert Song
* @version 1.0
*/
public class ExportBaseAction extends BaseAction {
/*
*可导出的最大记录数
*/
private final static int MAX_NUM_PER_PAGE=10000;
private
ValueListHandler get
ValueListHandler() {
WebApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(getServlet().getServletContext());
return (
ValueListHandler) context.getBean("valueListHandler",
ValueListHandler.class);
}
public ActionForward export(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
ValueListInfo vli=
ValueListRequestUtil.build
ValueListInfo(request);
vli.setPagingNumberPer(MAX_NUM_PER_PAGE);
ValueList valueList = get
ValueListHandler().get
ValueList(valueListName,
vli);
List ls=new ArrayList();
ls.add(titleNames);
int colWidths[]=new int[colNames.length];//列宽
for(int i=0;i<colNames.length;i++)
{
colWidths[i]=titleNames[i].length();
}
while(valueList.hasNext())
{
String cols[]=new String[colNames.length];
Object bean=valueList.next();
try {
for(int i=0;i<colNames.length;i++)
{
Object value=PropertyUtils.getProperty(bean,colNames[i]);//关键点
if(value==null)
value="-";
cols[i]=(String)value;
if(colWidths[i]<cols[i].length())
{
colWidths[i]=cols[i].length();
}
}
ls.add(cols);
} catch (Exception e) {
System.out.println("获取valueList的属性值时发生错误");
break;
}
}
ExcelExporter.export(ls,response,colWidths);
return null;
}
/**
* @param colNames返回的记录集的列名.
*/
public void setColNames(String[] colNames) {
this.colNames = colNames;
}
/**
* @param titleNames 表头汉字的字符串数组.
*/
public void setTitleNames(String[] titleNames) {
this.titleNames = titleNames;
}
/**
* @param valueListName 查询用的value list的sql的entry key .
*/
public void set
ValueListName(String valueListName) {
this.valueListName = valueListName;
}
}
4.真正导出excel的类
这里只是简单的将传入的字符串数组的List导出
package com.sogoodsoft.framework.exporter;
import java.util.List;
import java.io.*;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.*;
/**
* @author Albert Song
*
* 导出数据到Excel文件中
*
*/
public class ExcelExporter {
public static void export(List exportStringArrayList,
HttpServletResponse response) throws Exception {
export(exportStringArrayList,response,null);
}
public static void export(List exportStringArrayList,
HttpServletResponse response,int colWidths[]) throws Exception {
//仅仅为了防止系统抛出空指针异常,这应该算
POI的一个bug吧,这个问题花了我半天时间,现在还没搞明白
//总之设置之后就可以用了:)
System.setProperty("org.apache.poi.util.
POILogger","org.apache.poi.util.
POILogger");
List ls=exportStringArrayList;
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("sheet1");
if(colWidths!=null)
{
for(int i=0;i<colWidths.length;i++)
{
sheet.setColumnWidth((short)i,(short)(colWidths[i]*600));
}
}
for(int i=0;i<ls.size();i++)
{
HSSFRow row = sheet.createRow(i);
String[] strs=(String[])ls.get(i);
for(int j=0;j<strs.length;j++)
{
HSSFCell cell = row.createCell((short) j);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue(strs[j]);
}
}
// Get output stream
response.setContentType("application/x-msdownload");
response.setHeader("content-disposition",
"attachment; filename=dataexport.xls");
OutputStream os = response.getOutputStream();
wb.write(os);
os.close();
}
}
5.小结
这不能算是文章,只能算是一个抛砖引玉的笔记,本人学习
POI也才一天半,贴出来的目的是为了感谢同样贴出文章的同仁们,他们的无私奉献给了我不少启示,节省了我的时间,因此我觉得花一点时间将我的经验和大家分享是值得的。