java根据xml配置文件导出excel通用方法
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通用方法的更多相关文章
- java导出excel通用方法
首先需要引入的jar包: 正式代码了. import java.io.FileOutputStream; import java.io.OutputStream; import java.net.UR ...
- NOPI 导出excel 通用方法
public static byte[] ExportExcel<T>(Dictionary<string, string> columnsHeader, List<T& ...
- NPOI 导出excel 通用方法
public static byte[] ExportExcel<T>(Dictionary<string, string> columnsHeader, List<T& ...
- NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中
以下是NPOI导入导出EXCEL通用类,是在别人的代码上进行优化的,兼容xls与xlsx文件格式,供参考,可直接使用在WinForm项目中,由于XSSFWorkbook类型的Write方法限制,Wri ...
- ASP.NET导出excel表方法汇总
asp.net里导出excel表方法汇总 1.由dataset生成 public void CreateExcel(DataSet ds,string typeid,string FileName) ...
- XML格式导出Excel
下面介绍一种导出Excel的方法: 此方法不需要在服务器上安装Excel,采用生成xml以excel方式输出到客户端,可能需要客户机安装excel,所以也不会有乱七八糟的权限设定,和莫名其妙的版本问题 ...
- Java中导入、导出Excel
原文:Java中导入.导出Excel 一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已 ...
- 懒人小工具:T4自动生成Model,Insert,Select,Delete以及导出Excel的方法
之前写了篇文章,懒人小工具:[自动生成Model,Insert,Select,Delete以及导出Excel的方法](http://www.jianshu.com/p/d5b11589174a),但是 ...
- java使用poi生成导出Excel(新)
导出样式: java代码: import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStre ...
随机推荐
- 几个不错的开源的.net界面控件
转自原文 几个不错的开源的.net界面控件 (转) 几个不错的开源的.net界面控件 - zt 介绍几个自己觉得不错的几个开源的.net界面控件,不知道是否有人介绍过. DockPanel Suite ...
- HDFS简单介绍及用C语言訪问HDFS接口操作实践
一.概述 近年来,大数据技术如火如荼,怎样存储海量数据也成了当今的热点和难点问题,而HDFS分布式文件系统作为Hadoop项目的分布式存储基础,也为HBASE提供数据持久化功能,它在大数据项目中有很广 ...
- 修改android的wifi客户端名称的两种方法
修改android的wifi客户端名称的两种方法 手机连接到无线路由时,在dhcp的客户端列表里面是这样的名称"android-89425253e5de3a2",这就是安卓 ...
- Broadcast-广播的接收
至于广播的意思,不再赘述,直接看它的使用 先看代码 package com.example.test1123; import android.annotation.SuppressLint; impo ...
- golang中new和make区别
golang 中有两个内存分配机制 :new和make,二者有明显区别. new:用来初始化一个对象,并且返回该对象的首地址.其自身是一个指针.可用于初始化任何类型 make:返回一个初始化的实例,返 ...
- 一个奇怪的Java集合问题
int size = list.size(); Integer existIndex = -1; for (int index = 0; index < size; index++) { Pho ...
- ArcGIS 点要素新增点
IFeatureLayer layer = FrmMain.m_mapControl.get_Layer(0) as IFeatureLayer; IFeatureClass featureClass ...
- 利用jquery.fullPage.js 和 scrolloverflow.min.js 实现滚屏效果
参考链接:https://blog.csdn.net/c11073138/article/details/79631036 /* 按着思路去search. */
- PHP从数组中删除元素的四种方法实例
PHP从数组中删除元素的四种方法实例 一.总结 一句话总结:unset(),array_splice(),array_diff(),array_diff_key() 二.PHP从数组中删除元素的四种方 ...
- (转)Could not execute auto check for display colors using command /usr/bin/xdpyinfo. Check if the DISPL
转自:http://blog.csdn.net/huashnag/article/details/9357517 Starting Oracle Universal Installer... Chec ...