注意:本文針對(duì)對(duì)
Struts,Value?List有一定使用經(jīng)驗(yàn)的開發(fā)人員,如果你不是在web環(huán)境下使用
POI,建議你直接去看
POI的教程。
1.問(wèn)題由來(lái)
?????在此之前,我一直用valuelist來(lái)完成查詢并顯示結(jié)果,效果不錯(cuò)。valuelist可以導(dǎo)出excel,csv,但是一用之下,并沒(méi)有相象的那么好,它導(dǎo)出的excel并不是真正的excel文件,是一個(gè)html的文本文件,這樣由于某些處理上的不完善,在我這里出現(xiàn)了導(dǎo)出的文件在打開時(shí),表頭和下面的內(nèi)容錯(cuò)開,并且有多余的空列。如果對(duì)它的有關(guān)源代碼進(jìn)行修改,做到正常顯示是沒(méi)問(wèn)題的,但是如果客戶的需求再變一點(diǎn)點(diǎn),比如要設(shè)置一定的格式,用它來(lái)做就不太方便了。所以我只好尋求另一種方案,最后終于找到
POI,看它的介紹很不錯(cuò),按照它的指南一試之下,也很簡(jiǎn)單,于是決定就用它了。現(xiàn)在的問(wèn)題就是怎樣取得valuelist的查詢結(jié)果,并且用
POI導(dǎo)出到Excel中。
2.從web頁(yè)面動(dòng)作時(shí)調(diào)用的Action
在我們真正用到的查詢action里只要設(shè)置好三個(gè)屬性值就可以了.
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;
/**
?*?導(dǎo)出查詢的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中對(duì)應(yīng)的sql的列名一致。
???//?順序不必一致
??
??String?colNames[]={"stu_no","stu_name"};
??//Excel表的表頭,列名對(duì)應(yīng)的中文,必須和列名的順序?qū)?yīng)
??String?titleNames[]={"學(xué)號(hào)","姓名"};
??//applicataionContext.xml中sql對(duì)應(yīng)的id
??String?valueListName="testList";
//??這三項(xiàng)必須設(shè)置
???setColNames(colNames);
???setTitleNames(titleNames);
???set
ValueListName(valueListName);
???
???return?super.export(mapping,form,request,response);
?}
}
3.在ExportBaseAction?中取得valuelist的查詢結(jié)果
valuelist可以不用
Struts單獨(dú)使用,我這里是在
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?{
?
?/*
??*可導(dǎo)出的最大記錄數(shù)
??*/
?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]);//關(guān)鍵點(diǎn)
?????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的屬性值時(shí)發(fā)生錯(cuò)誤");
?????break;
???}
??}
??
??ExcelExporter.export(ls,response,colWidths);
??
??return?null;
?}
?
?/**
??*?@param?colNames返回的記錄集的列名.
??*/
?public?void?setColNames(String[]?colNames)?{
??this.colNames?=?colNames;
?}
?/**
??*?@param?titleNames?表頭漢字的字符串?dāng)?shù)組.
??*/
?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.真正導(dǎo)出excel的類
這里只是簡(jiǎn)單的將傳入的字符串?dāng)?shù)組的List導(dǎo)出
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
?*?
?*?導(dǎo)出數(shù)據(jù)到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?{
???//僅僅為了防止系統(tǒng)拋出空指針異常,這應(yīng)該算
POI的一個(gè)bug吧,這個(gè)問(wèn)題花了我半天時(shí)間,現(xiàn)在還沒(méi)搞明白
???//總之設(shè)置之后就可以用了:)
???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.小結(jié)
這不能算是文章,只能算是一個(gè)拋磚引玉的筆記,本人學(xué)習(xí)
POI也才一天半,貼出來(lái)的目的是為了感謝同樣貼出文章的同仁們,他們的無(wú)私奉獻(xiàn)給了我不少啟示,節(jié)省了我的時(shí)間,因此我覺得花一點(diǎn)時(shí)間將我的經(jīng)驗(yàn)和大家分享是值得的。