`
tianyulif
  • 浏览: 19107 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Excel动态导出

阅读更多
#此文章是转载-----

今天在写四位一体系统的过程中,根据需求需要实现工单的导出功能。我上网查找了一些资料,然后根据自己的实际,比较顺利地实现了这个功能。

下面简单分享一下:

首先需要去找一个pio包,我使用的是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;
}

}
分享到:
评论

相关推荐

    Excel动态导出.md

    Excel动态导出.md

    自定义动态导出excel封装类

    在IT行业中,Excel导出是常见的数据处理任务,特别是在数据分析、报表生成以及数据交换等领域。本文将详细讲解如何实现一个自定义的动态导出Excel封装类,以满足各种不同的需求。 首先,我们要理解为什么要自定义...

    Excel报表导出,复杂Excel模板导出(带单元格合并),jxls2

    这种工作方式极大地简化了Excel导出的编程过程,提高了开发效率。 项目提供的Maven配置使得开发者可以直接下载并运行`JxlsTest` demo,快速了解和上手。Maven是Java领域广泛应用的构建工具,通过依赖管理和项目生命...

    kettle 使用excel模板导出数据

    5. **处理动态数据**:如果数据量大或需要动态生成多个Excel文件,可以使用"Filter Rows"或"Variable"步骤来控制导出逻辑。例如,可以按日期范围或分组导出不同的Excel文件。 6. **注意要点**: - 保持模板的兼容...

    excel 自定义列导出, excel导出

    标题说的很清楚,利用asm-3.1.jar,cglib-2.2.jar,commons-io-1.3.2.jar,poi-3.9-20121203.jar 开发的一个工具包。 其中用到字节码编码,反射,excel操作。...主要功能1、自定义列导出excel Main()类为测试用例

    Excel导入导出项目 简单的

    Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出Excel导入导出

    thinkhphp3.2 excel导入导出demo

    thinkhphp3.2 excel导入导出demothinkhphp3.2 excel导入导出demothinkhphp3.2 excel导入导出demothinkhphp3.2 excel导入导出demothinkhphp3.2 excel导入导出demothinkhphp3.2 excel导入导出demothinkhphp3.2 excel...

    Thinkphp5整合excel导入导出

    Thinkphp5整合excel导入导出Thinkphp5整合excel导入导出Thinkphp5整合excel导入导出Thinkphp5整合excel导入导出Thinkphp5整合excel导入导出Thinkphp5整合excel导入导出Thinkphp5整合excel导入导出Thinkphp5整合excel...

    Java POI EXCEL导入导出

    Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出Java POI EXCEL导入导出...

    java_poi实现excel导入导出

    Java POI 实现 Excel 导入导出 Java POI 是一个流行的 Java 库,用于处理 Microsoft Office 文件格式,包括 Excel 文件。在本文中,我们将详细介绍如何使用 Java POI 实现 Excel 导入导出功能。 1. 什么是 Java ...

    Freemarker实现excel导出功能

    本篇文章将详细探讨如何使用Freemarker来实现Excel导出功能,并通过实际例子加深理解。 一、Freemarker基础 1. 模板语言:Freemarker是一种基于模板的语言,它允许开发者通过简单的语法(如 `${}` 和 `#if`)来...

    Excel导出数据(根据Excel模板定义)

    "Excel导出数据(根据Excel模板定义)"这个主题涉及到的核心技术是如何根据预设的Excel模板生成和导出数据,通常用于批量生成报表或者进行复杂的数据呈现。下面将详细解释这一过程及其相关知识点。 1. **Excel模板...

    POI实现的基于动态模板的EXCEL数据导出

    “EXCEL导出”是我们的主要目标,即生成可下载的Excel文件;“大量数据导出”则强调了该方法适用于处理批量数据,比如用于报表生成、数据分析等场景。 从压缩包子文件的文件名称“excelExport”来看,这可能是包含...

    java导出复杂Excel内容数据动态循环

    java导出复杂Excel内容数据动态循环

    asp将EXCEL导入导出数据库原程序

    这个"asp将EXCEL导入导出数据库原程序"提供了一个解决方案,能够方便地将Excel中的数据存入MSSQL数据库,同时也能将数据库中的数据导出到Excel文件。 首先,我们需要了解如何使用ASP连接MSSQL数据库。通常,这涉及...

    excel导出实现代码

    在IT行业中,Excel导出是一项常见的需求,尤其是在数据处理、报表生成和数据分析等领域。Apache POI是一个开源项目,专门用于读取和写入Microsoft Office格式的文件,包括Excel(.xlsx和.xls)。以下是对"Excel导出...

    easypoi的使用demo,包含Excel模板导出,html导出Excel,Excel导出pdf等

    3. Excel导出为PDF: 虽然Apache POI本身并不直接支持Excel到PDF的转换,但Easy POI通过引入第三方库如 Flying Saucer 或 Apache FOP 实现了这一功能。首先,你需要将Excel文件读取为一个工作簿对象,然后利用PDF...

    导出EXCEL文件导出EXCEL

    用于考核的系统,导出EXCEL导出EXCEL

    导出Excel功能,导出Excel功能,导出Excel功能

    5. **模板设计**:为了提供一致的视觉效果,可以预先设计Excel模板,包括固定头部、冻结行列、图表、公式等,然后将动态数据填充到模板中。 6. **并发处理**:在多用户环境下,需要处理并发导出请求,避免文件冲突...

Global site tag (gtag.js) - Google Analytics