风人园

弱水三千,只取一瓢,便能解渴;佛法无边,奉行一法,便能得益。
随笔 - 99, 文章 - 181, 评论 - 56, 引用 - 0
数据加载中……

POI

注意:本文针对对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);
   setValueListName(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 getValueListHandler() {
  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.buildValueListInfo(request);
  vli.setPagingNumberPer(MAX_NUM_PER_PAGE);
  
  ValueList valueList = getValueListHandler().getValueList(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 setValueListName(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也才一天半,贴出来的目的是为了感谢同样贴出文章的同仁们,他们的无私奉献给了我不少启示,节省了我的时间,因此我觉得花一点时间将我的经验和大家分享是值得的。

posted on 2007-02-12 08:42 风人园 阅读(717) 评论(0)  编辑  收藏 所属分类: Java