struts2+poi实现excel文件的导出
来源:互联网 发布:javmoo.xyz最新域名 编辑:程序博客网 时间:2024/04/25 09:12
首先需要去找一个poi包,我使用的是poi-3.2.jar
这个功能只需要用到一个Action,并在struts.xml中将其配置好即可。
<action name="exportExcel" class="panyu.flow.web.action.ExcelAction">
<result name="success" type="stream">
<param name="contentType">application/vnd.ms-excel</param>
<param name="inputName">excelStream</param>
<param name="contentDisposition">attachment;filename="${fileName}.xls"</param>
<param name="bufferSize">1024</param>
</result>
<result name="error">/WEB-INF/jsp/msg_error.jsp</result>
</action>
上面的配置中需要注意红色字体标注的部分。
1.、result的类型需要配置为stream(流),这是因为我们的Excel文件是以字节流的形式输出的。
2、contentType指定了我们导出的数据流其实是一个Excel文档。
3、inputName配置的是输入流的名称,我们导出的Excel就是从这个输入流里面读取数据。
4、contentDisposition的作用主要是让IE浏览器将其作为一个附件形式返回而不是直接在网页中显示,其中我们用到一个参数fileName,这样可以在Struts中动态修改这个Excel文件的名称。
然后看Struts
package panyu.flow.web.action;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts2.StrutsStatics;
import panyu.flow.business.service.CzyService;
import panyu.flow.business.service.CzydwService;
import panyu.flow.business.service.GdService;
import panyu.flow.business.vo.Czy;
import panyu.flow.business.vo.Czydw;
import panyu.flow.business.vo.Gd;
import panyu.flow.business.vo.inf.Exportable;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
* @author Liang Zhibiao
*/
public class ExcelAction extends ActionSupport {
private GdService gdService;
private CzyService czyService;
private CzydwService czydwService;
InputStream excelStream; //这个输入流对应上面struts.xml中配置的那个excelStream,两者必须一致
String fileName; //这个名称就是用来传给上面struts.xml中的${fileName}的
@Override
public String execute() throws Exception {
/*第一步:获取查询参数
我这个应用要导出的其实是用户查询返回的结果列表(List),而“导出Excel”这个按钮我就是放到查询结果显示页面上的。在这个页面上,我用一个form来将用户上一步查询的参数保存下来,然后当用户点击“导出Excel”按钮的时候,其实是再执行了一次form表单提交来执行本Action。这两次查询其实是大同小异的,只是显示查询结果的时候还需要做一个分页的功能,而这里导出则不用进行分页。*/
HttpServletRequest request = (HttpServletRequest) ActionContext
.getContext().get(StrutsStatics.HTTP_REQUEST);
DateFormat dateFormat = DateFormat.getDateInstance();
String str_fqrid = request.getParameter("fqrid");
String str_fsqj1 = request.getParameter("fqsj1");
……略
/*第二步:得到List
这个List需要调用到数据服务层,传入相应参数后会返回一个List
另外,我这里用到了接口而不是实际的类,这是为了方便我们可以创建一个通用的“Excel表数据填充方法”,而不用为每个特定类都创建一个。
这个接口有两个方法:
public String[] getColumnNames() ; //返回需要导出的列名称,例如“工单标题”、“工单内容”等
public String[] getColumnMethods(); //这是一个方法名称数组,我们会用到“反射”中的invoke来调用这些方法来取得各行数据
*/
List<Exportable> list = gdService.exportGd(fqrid, fqsj1, fqsj2, gdbt, gdnr, lcszid, nsrsbh, nsrmc,wszt, zzwcsj1, zzwcsj2, dqjbrid, jbrid, jbrdwid, jbrgwid);
if(list==null){
request.setAttribute("message", "没有数据");
return ERROR;
}else{
/*第三步:创建Excel工作簿。
正如上面所说,由于我们使用了接口,所以下面这个getWorkbook方法接收的list中的元素并不针对特定的类,只要该类实现了Exportable接口即可 */
HSSFWorkbook workbook = getWorkbook(list);
if(workbook != null){
try{
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
String month_ = new String(""+month);
if(month<10){
month_ = "0"+month;
}
int day = c.get(Calendar.DAY_OF_MONTH);
String day_ = new String(""+day);
if(day<10){
day_ = "0"+day;
}
//第四步:将工作簿写入最上面定义的InputStream流——名称为excelStream,这个名字对应struts.xml中配置的inputName参数
this.workbook2InputStream(workbook,year+"-"+month_+"-"+day_+"");
return SUCCESS;
}catch(IOException e){
e.printStackTrace();
request.setAttribute("message", "创建Excel失败");
return ERROR;
}
}else{
request.setAttribute("message", "创建Excel失败");
return ERROR;
}
}
}
//创建Workbook
//将Workbook写入到InputStream
private void workbook2InputStream(HSSFWorkbook workbook,String fileName) throws Exception{
this.fileName = fileName; //设置fileName
ByteArrayOutputStream baos = new ByteArrayOutputStream();
workbook.write(baos);
baos.flush();
byte[] aa = baos.toByteArray();
excelStream= new ByteArrayInputStream(aa, 0, aa.length);
baos.close();
}
public void setGdService(GdService gdService) {
this.gdService = gdService;
}
public String getFileName() {
return fileName;
}
public InputStream getExcelStream()
{
return excelStream;
}
/*下面这个方法是将list转换为Excel工作表的*/
private HSSFWorkbook getWorkbook(List<Exportable> list) throws Exception{
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("sheet1");
String[] columnNames;
String[] columnMethods;
//首先,我们读取list中的第一个元素,根据它来确定工作表的列名,以及输出数据所对应的方法数组
Exportable exp = list.get(0);
columnNames = exp.getColumnNames();
columnMethods = exp.getColumnMethods();
HSSFRow row = sheet.createRow(0); //创建第1行,也就是输出表头
HSSFCell cell;
for(int i=0;i<columnNames.length;i++){
cell = row.createCell(i); //创建第i列
cell.setCellValue(new HSSFRichTextString(columnNames[i]));
}
//下面是输出各行的数据
for (int i = 0; i < list.size(); i++) {
exp=(Exportable)list.get(i);
row=sheet.createRow(i+1);//创建第i+1行
for(int j=0;j<columnMethods.length;j++){
cell=row.createCell(j);//创建第j列
Method method;
method = exp.getClass().getMethod(columnMethods[j]); //这里用到了反射机制,通过方法名来取得对应方法返回的结果对象
Object obj = method.invoke(exp);
cell.setCellValue(obj.toString());
}
}
return workbook;
}
public void setCzyService(CzyService czyService) {
this.czyService = czyService;
}
public void setCzydwService(CzydwService czydwService) {
this.czydwService = czydwService;
}
}
这种实现方式网上已经有很多描述,主要的区别是我这里用到了接口和反射机制,因为我需要导出的类型并不只是工单类(Gd),还会有操作员类(Czy)等等,如果每个类都要单独写一个创建Excel表的方法,那并不是明智的方法。由于我需要用到查询,所以获取list这一块暂时还没有用到接口,其实这一块也可以再继续虚拟化一些,也可以定义一个接口,这样,这个Excel导出类就可以更加通用了。
最后看一下Gd类
/**
* @author Liang Zhibiao
* 工单
*/
package panyu.flow.business.vo;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;
import panyu.flow.business.vo.inf.Exportable;
public class Gd implements Exportable{
private int id;
private String gdbt; //工单标题
private String gdnr; //工单内容
//略
private String[] columnNames
=new String[]{"ID","工单标题","工单内容","纳税人识别号","纳税人名称","发起人","发起时间","最终完成时间","工单状态"};
private String[] columnMethods
= new String[]{"getId","getGdbt","getGdnr","getNsrsbh","getNsrmc","getFqrmc","getFqsjStr","getZzwcsjStr","getWcztName"};
public String[] getColumnNames() {
return columnNames;
}
public String[] getColumnMethods() {
return columnMethods;
}
}
- struts2+poi实现excel文件的导出
- struts2+poi实现导出Excel文件
- Struts2+poi实现Excel文件导出
- struts2+poi 导出Excel文件
- 自己封装的POI + Struts2 实现Excel导出工具包
- struts2利用poi导出excel文件
- Struts2+Poi实现导出excel功能
- Struts2 POI实现导出Excel功能
- POI Excel文件的导出
- Struts2 poi导出excel
- POI实现Excel的导出
- poi报表实现,导出到excel文件
- Java利用POI实现导出excel文件
- Apache POI实现Excel文件导出
- POI导出Excel文件
- POI EXCEL 文件导出
- POI 导出excel文件
- POI导出Excel文件
- 硬盘主引导记录详解
- qt FTP客户端编程
- qt FTP客户端编程
- 什么是DataSnap
- SAP 中的读取及上传文件方法总结
- struts2+poi实现excel文件的导出
- Spy++的搜索窗口程序
- bjective-C边学边记-7:Foundation Kit快速教程之 范围
- 正则表达式
- 火车硬座车厢座位分布表
- Linux环境下的C/C++基础调试技术3——查看数据
- JavaScript Date Validation
- 我的第一个ant应用
- 框架设计简介(一)