java web项目中时常会用到导出功能,而导出excel几乎是每个项目必备的功能之一。针对形形色色的导出方法及个人平时的工作经验,特将导出excel方法整理成通用的方法,根据xml配置来实现特定的导出。

  此方法基于struts2框架实现,先看struts.xml配置文件中的配置方法:

 <action name="exportExcel" class="exportExcelAction">
<result name="download" type="stream">
<param name="contentType">application/vnd.ms-excel</param>
<param name="contentDisposition">attachment;filename="${excelName}"</param>
<param name="inputName">excelStream</param>
</result>
</action>

  1、excelName对应bean中的excelName属性,为导出文件名称;

  2、excelStream对应bean中导出数据流,即导出方法返回的数据流。

  接着是导出配置文件:excel.xml,需要导出的列表按照规则配置在此xml文件中即可:

 <?xml version="1.0" encoding="utf-8"?>
<excel>
<element title="检测库信息表" class="com.model.CheckRecord">
<property name="xmmc" display_name="项目名称"></property>
<property name="sampleNo" display_name="样品编号"></property>
<property name="detectTime" display_name="检测日期"></property>
<property name="jcbh" display_name="检测板号"></property>
<property name="ypmc" display_name="样品名称"></property>
<property name="yplx" display_name="样品类型"></property>
<property name="ypcd" display_name="样品产地"></property>
<property name="resultType" display_name="检测类型"></property>
<property name="resultValue" display_name="检测结果"></property>
<property name="resultDetect" display_name="检测读数值"></property>
<property name="resultTip" display_name="检测提示"></property>
<property name="submitStaff" display_name="送检人员"></property>
<property name="submitTime" display_name="送检时间"></property>
</element>
</excel>

  excel节点为根节点,element节点即为需要导出的列表节点,class属性用来唯一区别不同的导出列表,即根据class属性查找需要导出的列表属性集合,title属性当然是导出excel表格的标题咯。

  property节点是需要导出的字段,name属性和javabean中属性一一对应,display_name是excel表格所对应的显示名称。

  不同的导出列表只需要按照上面的实例配置多个element即可,切记class属性要唯一哦。

  接下来就是导出excel工具类啦,先看代码:

 package excel.util;

 /**
* 导出excel工具类
* @author BaiFL
*/
public class ExportExcelUtil { /**标题**/
private String title; private InputStream inputStream = null; private ByteArrayOutputStream outputStream = null; private HSSFWorkbook workbook; private HSSFSheet sheet; /**表格行**/
private HSSFRow row; /**单元格**/
private HSSFCell cell; /**字体**/
private HSSFFont font; /**单元格样式**/
private HSSFCellStyle cellStyle; /**
* 字段及字段注释
* key:字段名
* value:字段注释
*/
private Map<String, String> propertyMap = new HashMap<String, String>(); /**
* 导出excel
* @param className 完整类名
* @param list 导出结果集
*/
public InputStream export(String className, List<?> list){ //初始化
this.instance(className); //设置字体
font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12); //设置单元格类型
cellStyle = workbook.createCellStyle();
cellStyle.setFont(font);
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //创建第一行title
row = sheet.createRow(0);
this.setCellValue(0, title);
//合并单元格:0行~0行,0列~propertyMap.size() - 1列
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, propertyMap.size() - 1)); //创建第二行标题行
row = sheet.createRow(1);
int i = 0;
//遍历propertyMap
for(String key : propertyMap.keySet()){
//创建单元格
this.setCellValue(i, propertyMap.get(key));
i++;
} //遍历数据集合
for(int j = 0; j < list.size(); j++) {
Object object = list.get(j);
//创建数据行,从第三行开始
row = sheet.createRow(j + 2);
int k = 0;
for(String key : propertyMap.keySet()){
Field f;
String value;
try {
f = object.getClass().getDeclaredField(key);
//设置私有字段的可访问性
f.setAccessible(true);
//获取字段get方法
value = String.valueOf(f.get(object));
//设置单元格
this.setCellValue(k, value);
k++;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
try {
outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] content = outputStream.toByteArray();
inputStream = new ByteArrayInputStream(content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(outputStream != null){
outputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return inputStream;
} /**
* 初始化
* @param className 完整类名
* 根据className获取excel.xml文件对应element属性集合
*/
@SuppressWarnings("unchecked")
private void instance(String className){
//加载配置文件
inputStream = ExportExcelUtil.class.
getResourceAsStream("/resources/exportExcel/excel.xml"); this.workbook = new HSSFWorkbook();
this.sheet = workbook.createSheet(); SAXReader reader = new SAXReader(); Document document = null;
try {
document = reader.read(inputStream);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //获取根节点
Element excel = document.getRootElement(); //获取element集合
List<Element> elementList = excel.elements("element");
//根据class属性获取对应导出字段属性集合
for(Element element : elementList){
if(className.equals(element.attributeValue("class"))){
title = element.attributeValue("title");
//element下所有property集合
List<Element> childList = element.elements();
for(Element child : childList){
propertyMap.put(child.attributeValue("name"),
child.attributeValue("display_name"));
}
}
}
} /**
* 设置单元格
* @param index
* @param value
*/
private void setCellValue(int index, String value){
//创建单元格,设置单元格属性为文本类型
cell = row.createCell(index, HSSFCell.CELL_TYPE_STRING);
cell.setCellStyle(cellStyle);
cell.setCellValue(value);
//设置第index列宽为自动
sheet.autoSizeColumn(index);
} }
   方法export(String className, List<?> list)即导出excel通用方法,参数1:className对应导出配置文件excel.xml文件中element节点的class属 性,为完整类名;参数2:list即需要导出的数据,该list为对象集合,非数组集合。

  下面就是action中如何用啦,前面所有工作做好以后action中只需要很少的代码调用就可以啦,先看代码:
     /**
* exportExcel
* @return
*/
public String exportExcel() {
//获取数据条数
int count = recordService.count(checkRecord);
//分页
Page page = listForm.getPageObj(count);
if(StringUtils.blank(page.getOrderBy())){
//默认按检测时间倒序排序
page.setOrderBy("detectTime");
page.setOrder("desc");
}
//导出excel
if(Constant.EXPORT.equals(export)){
page.setPage(0);
page.setPageSize(exportSize !=0 && exportSize < count ? exportSize : (count < 65535 ? count : 65535));
List<CheckRecord> list = recordService.find(checkRecord, page);
excelStream = excel.export(CheckRecord.class.getName(), list);
return "download";  
}else{
List<CheckRecord> list = recordService.find(checkRecord, page);
httpServletRequest.setAttribute("List", list);
httpServletRequest.setAttribute("Page", page);
return "list";
}
}

  这是普通的页面列表数据展示代码,当属性export值为Constant.EXPORT("export")时,执行导出excel操作,导出数据范围为exportSize~65535;

  action中还必须有excelStream、excelName两个属性,分别和struts中的属性一一对应。

  /**导出excel数据流对应struts中的stream**/
  protected InputStream excelStream;

  /**excel文件名**/
  protected String excelName;

  getter/setter方法这里就不写了,action中可一定要写哦。

  至此,整个导出功能全部实现,赶紧试试吧

  下面的代码无需配置struts,直接导出并下载:

 package com.jeecms.common.util;

 import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /**
* 导出excel工具类
* @author BaiFL
*/
public class ExportExcelUtil { /**标题**/
private String title; private InputStream inputStream = null; private OutputStream os = null; private HSSFWorkbook workbook; private HSSFSheet sheet; /**表格行**/
private HSSFRow row; /**单元格**/
private HSSFCell cell; /**字体**/
private HSSFFont font; /**单元格样式**/
private HSSFCellStyle cellStyle; /**
* 字段及字段注释
* key:字段名
* value:字段注释
*/
private Map<String, String> propertyMap = new LinkedHashMap<String, String>(); /**
* 导出excel
* @param className 完整类名
* @param list 导出结果集
* @param response
*/
public void export(String className, List<?> list, HttpServletResponse response){ //初始化
this.instance(className); response.reset(); response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.ms-excel");
String fileName = null;
try {
fileName = new String(title.getBytes("GBK"), "ISO-8859-1");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
response.setHeader("Content-Disposition", "filename=" + fileName + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")+ ".xls"); //设置字体
font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12); //设置单元格类型
cellStyle = workbook.createCellStyle();
cellStyle.setFont(font);
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //创建第一行title
row = sheet.createRow(0);
this.setCellValue(0, title);
//合并单元格:0行~0行,0列~propertyMap.size() - 1列
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, propertyMap.size() - 1)); //创建第二行标题行
row = sheet.createRow(1);
int i = 0;
//遍历propertyMap
for(String key : propertyMap.keySet()){
//创建单元格
this.setCellValue(i, propertyMap.get(key));
i++;
}
//遍历数据集合
for(int j = 0; j < list.size(); j++) {
Object object = list.get(j);
//创建数据行,从第三行开始
row = sheet.createRow(j + 2);
int k = 0;
for(String key : propertyMap.keySet()){
if(key.indexOf(".") > 0){ //关联对象中的私有属性
String[] keyArr = key.split("\\.");
Field field;
Object obj = object;
for(int t = 0; t < keyArr.length; t++){
if(t + 1 == keyArr.length){ //获取私有字段值
try {
field = obj.getClass().getDeclaredField(keyArr[t]);
//设置私有字段的可访问性
field.setAccessible(true);
//获取字段get方法
Object value = field.get(obj);
//设置单元格
this.setCellValue(k, (value == null ? "" : String.valueOf(value)));
k++;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}else{ //获取关联对象
try {
field = obj.getClass().getDeclaredField(keyArr[t]);
//设置私有字段的可访问性
field.setAccessible(true);
//获取字段get方法
obj = field.get(obj);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}else{ //不包含关联对象的私有属性
try {
Field f = object.getClass().getDeclaredField(key);
//设置私有字段的可访问性
f.setAccessible(true);
//获取字段get方法
Object value = f.get(object);
//设置单元格
this.setCellValue(k, (value == null ? "" : String.valueOf(value)));
k++;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
try {
os = response.getOutputStream();
workbook.write(os);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(os != null){
os.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
} /**
* 初始化
* @param className 完整类名
* 根据className获取excel.xml文件对应element属性集合
*/
@SuppressWarnings("unchecked")
private void instance(String className){
//加载配置文件
inputStream = ExportExcelUtil.class.getResourceAsStream("/resources/exportExcel/excel.xml"); SAXReader reader = new SAXReader(); Document document = null;
try {
document = reader.read(inputStream);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //获取根节点
Element excel = document.getRootElement(); //获取element集合
List<Element> elementList = excel.elements("element");
//根据class属性获取对应导出字段属性集合
for(Element element : elementList){
if(className.equals(element.attributeValue("class"))){
title = element.attributeValue("title");
//element下所有property集合
List<Element> childList = element.elements();
for(Element child : childList){
propertyMap.put(child.attributeValue("name"), child.attributeValue("display_name"));
}
}
} this.workbook = new HSSFWorkbook();
this.sheet = workbook.createSheet(title);
} /**
* 设置单元格
* @param index
* @param value
*/
private void setCellValue(int index, String value){
//创建单元格,设置单元格属性为文本类型
cell = row.createCell(index, HSSFCell.CELL_TYPE_STRING);
cell.setCellStyle(cellStyle);
cell.setCellValue(value);
//设置第index列宽为自动
sheet.autoSizeColumn(index);
} }

action中使用方法:

     /**
* 导出
* @param queryValue
* @param pageNo
* @param request
* @param response
* @param model
*/
@RequestMapping(value = "/addresslist/export.do")
public void export(String queryValue, Integer pageNo,
HttpServletRequest request, HttpServletResponse response, ModelMap model) {
List<CmsUser> list = manager.getExcelList(CmsUtils.getSiteId(request), queryValue);
ExportExcelUtil excel = new ExportExcelUtil();
excel.export(CmsUser.class.getName(), list, response);
log.info("通讯录导出成功!");
}
 
												

java根据xml配置文件导出excel通用方法的更多相关文章

  1. java导出excel通用方法

    首先需要引入的jar包: 正式代码了. import java.io.FileOutputStream; import java.io.OutputStream; import java.net.UR ...

  2. NOPI 导出excel 通用方法

    public static byte[] ExportExcel<T>(Dictionary<string, string> columnsHeader, List<T& ...

  3. NPOI 导出excel 通用方法

    public static byte[] ExportExcel<T>(Dictionary<string, string> columnsHeader, List<T& ...

  4. NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中

    以下是NPOI导入导出EXCEL通用类,是在别人的代码上进行优化的,兼容xls与xlsx文件格式,供参考,可直接使用在WinForm项目中,由于XSSFWorkbook类型的Write方法限制,Wri ...

  5. ASP.NET导出excel表方法汇总

    asp.net里导出excel表方法汇总  1.由dataset生成 public void CreateExcel(DataSet ds,string typeid,string FileName) ...

  6. XML格式导出Excel

    下面介绍一种导出Excel的方法: 此方法不需要在服务器上安装Excel,采用生成xml以excel方式输出到客户端,可能需要客户机安装excel,所以也不会有乱七八糟的权限设定,和莫名其妙的版本问题 ...

  7. Java中导入、导出Excel

    原文:Java中导入.导出Excel 一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已 ...

  8. 懒人小工具:T4自动生成Model,Insert,Select,Delete以及导出Excel的方法

    之前写了篇文章,懒人小工具:[自动生成Model,Insert,Select,Delete以及导出Excel的方法](http://www.jianshu.com/p/d5b11589174a),但是 ...

  9. java使用poi生成导出Excel(新)

    导出样式: java代码: import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStre ...

随机推荐

  1. android缩放动画的两种实现方法

    在android开发.我们会常常使用到缩放动画,普通情况下缩放动画有两种实现方式.一种是直接通过java代码去实现,第二种是通过配置文件实现动画,以下是两种动画的基本是用法: Java代码实现: // ...

  2. 10小时之内,暴力破解SSH账号的IP

    10小时之内,暴力破解SSH账号的IP,IP 地址数据来源于  ip138.com 182.18.76.246 北京市昌平区 北京亿安天下网络科技有限公司 联通 221.223.200.143 北京市 ...

  3. python 新模块或者包的安装方法

    主要介绍通过pip自动工具来安装需要的包. 1,先安装pip 下载pip的包(包括setup.py文件) cmd载入到pip本地文件所在路径,使用命令进行安装. python setup.py ins ...

  4. codeforces 204E. Little Elephant and Strings(广义后缀自动机,Parent树)

    传送门在这里. 大意: 给一堆字符串,询问每个字符串有多少子串在所有字符串中出现K次以上. 解题思路: 这种子串问题一定要见后缀自动机Parent树Dfs序统计出现次数都是套路了吧. 这道题统计子串个 ...

  5. 一起talk C栗子吧(第九回:C语言实例--最大公约数)

    各位看官们,大家好.从今天開始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们.上一回中咱们说的是素数的样例.这一回咱们说的样例是: ...

  6. 好记性不如烂笔头——datagridview相关

    DataGridViewTextBoxColumn dgv_IDY = new DataGridViewTextBoxColumn(); dgv_IDY.Visible = false; dgv_ID ...

  7. javascript中的事件问题的总结

    一.什么是事件? 事件就是DOM和浏览器之间的交互行为(只要触发了这个行为,也就相当于触发了事件),我们可以通过事件监听来绑定事件,例如:box.onclick=function(){},如果我们点击 ...

  8. GO语言学习(七)Go 语言变量

    Go 语言变量 变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念.变量可以通过变量名访问. Go 语言变量名由字母.数字.下划线组成,其中首个字母不能为数字. 声明变量的一般形式是使用 ...

  9. Playing with coroutines and Qt

    你好!我最近想知道C ++中的协程的状态,我发现了几个实现.我决定选择一个用于我的实验.它简单易用,适用于Linux和Windows. 我的目标是试图找到一种方法来让代码异步运行,而不必等待信号触发插 ...

  10. MongoDb 查询时常用方法

    Query.All("name", "a", "b");//通过多个元素来匹配数组Query.And(Query.EQ("name ...