Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类
==============================
©Copyright 蕃薯耀 2017年9月13日
http://www.cnblogs.com/fanshuyao/
直接上代码:
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletOutputStream;
import org.apache.commons.lang.StringUtils;
public class ExportUtil {
/**
* 只导出包含在includeFieldNames中的属性
* @param sheetName 表格左下角的名称
* @param firstRowTitle 第一行需要设置的title,为空则不设置
* @param list 需要显示的数据集合
* @param headers 表格属性列名数组
* @param includeFieldNames 包含的实体属性
* @param widths 列的宽度,不设置(为Null)则默认,设置则根据对应的列宽设置(可以是一个,可以是对应的数量,整形数字,如200)
* @param outputStream 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
* @param datetimePattern 时间形式,当为空(Null或空字符串)时默认为yyyy-MM-dd HH:mm:ss
* @throws Exception
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void exportExcel(String sheetName, String firstRowTitle, List list, String[] headers, String[] includeFieldNames, Integer[] widths,
ServletOutputStream outputStream, String datetimePattern) throws Exception {
// 默认输出格式
if (StringUtils.isBlank(datetimePattern)) {
datetimePattern = "yyyy-MM-dd HH:mm:ss";
}
// 创建一个excel应用文件
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\"?>");
sb.append("\n");
sb.append("<?mso-application progid=\"Excel.Sheet\"?>");
sb.append("\n");
sb.append("
sb.append("\n");
sb.append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"");
sb.append("\n");
sb.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"");
sb.append("\n");
sb.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">");
sb.append("\n");
sb.append("\n");
/*设置列头样式*/
sb.append("
sb.append("\n");// 设置背景颜色
sb.append("\n");//设置字体
sb.append("\n");
/*其它默认样式设置*/
sb.append("
//sb.append("\n");
sb.append("\n");// 左中右设置,一个是水平,一个是垂直
sb.append("\n");
sb.append("\n");//左边框设置
sb.append("\n");//右边框设置
sb.append("\n");//下边框设置
sb.append("\n");//上边框设置
sb.append("\n");
sb.append("\n");
sb.append("\n");
sb.append("\n");
sb.append("\n");
sb.append("\n");
sb.append("\n");
try {
// 生成表格
int headersLength = headers.length;
sb.append("");
sb.append("\n");
sb.append("
+ "\" ss:ExpandedRowCount=\"1000000\" x:FullColumns=\"1\" x:FullRows=\"1\">");
sb.append("\n");
if(!StrUtils.isEmptyArray(widths)){
if(widths.length > 1){
for (int i = 0; i < headersLength; i++) {
sb.append("");
}
}else{
for (int i = 0; i < headersLength; i++) {
sb.append("");
}
}
}
// 输出第一行的标题
if(!StrUtils.isBlank(firstRowTitle)){
//ss:StyleID可以加row或者Cell,加在Row,整行(包括空的Cell)都有,加上Cell,只有Cell才有。
sb.append("");
sb.append("" + firstRowTitle + "");
sb.append("");
}
// 输出列头
sb.append("");
for (int i = 0; i < headersLength; i++) {
sb.append("" + headers[i] + "");
}
sb.append("");
// 构建表体数据
for (int j = 0; j < list.size(); j++) {
sb.append("");
T t = (T) list.get(j);
for (int i = 0; i < includeFieldNames.length; i++) {
// 获取属性名称
String fieldName = includeFieldNames[i];
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
// 获取class对象
Class tCls = t.getClass();
// 获取属性值
Object value = null;
try {
// 获取class方法
Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
// 获取属性值
value = getMethod.invoke(t, new Object[] {});
} catch (NoSuchMethodException e) {
// 继续循环
continue;
}
// 判断值的类型后进行强制类型转换
String textValue = "";
if (value instanceof Integer) {
// int value = ((Integer) value).intValue();
textValue = value.toString();
} else if (value instanceof String) {
// String s = (String) value;
textValue = value.toString();
} else if (value instanceof Double) {
// double d = ((Double) value).doubleValue();
textValue = String.format("%.2f", value);
} else if (value instanceof Float) {
// float f = ((Float) value).floatValue();
textValue = value.toString();
} else if (value instanceof Long) {
// long l = ((Long) value).longValue();
textValue = value.toString();
} else if (value instanceof Boolean) {
// boolean b = ((Boolean) value).booleanValue();
textValue = value.toString();
} else if (value instanceof Date) {
Date date = (Date) value;
SimpleDateFormat sdf = new SimpleDateFormat(datetimePattern);
textValue = sdf.format(date);
} else if ((value instanceof BigDecimal)) {
textValue = value.toString();
} else {
if (value != null) {
continue;
}
}
sb.append("");
// 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
if (StringUtils.isNotBlank(textValue)) {
Pattern p = Pattern.compile("^//d+(//.//d+)?$");
Matcher matcher = p.matcher(textValue);
if (matcher.matches()) {
// 是数字当作double处理
sb.append(Double.parseDouble(textValue));
} else {
sb.append(textValue);
}
}
sb.append("");
}
sb.append("");
sb.append("\n");
}
sb.append("
");sb.append("");
sb.append("\n");
sb.append("False");
sb.append("\n");
sb.append("False");
sb.append("\n");
sb.append("");
sb.append("\n");
sb.append("");
sb.append("");
sb.append("\n");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
try {
outputStream.write(sb.toString().getBytes());
outputStream.flush();
outputStream.close();
sb = null;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用方式:
@RequestMapping("/exportMsCard")
public void exportMsCard(HttpServletRequest req, HttpServletResponse res,
Integer pageIndex, Integer pageSize,
String cardNo, String mobile, String cinemaBaseName, Date startDate, Date endDate) {
try {
if(endDate != null){
endDate = DateUtils.dateAdd(endDate, 1, false);
}
List msCards = msCardService.list(pageIndex, pageSize,
cardNo, mobile, cinemaBaseName, startDate, endDate);
String[] headers = { "会员卡号", "会员昵称", "手机号码", "影院名称", "创建时间"};
String[] includeFieldNames = { "cardNo", "nickname", "mobile", "cinemaBaseName", "createTime"};
// 设置文件后缀并编码
String fileName = new String("运营平台-会员卡包-会员卡列表.xls".getBytes("UTF-8"), "iso8859-1");
// 设置响应的编码方式;
res.setCharacterEncoding("gb2312");
res.setHeader("Content-disposition", "attachment; filename=" + fileName);
res.setContentType("application/msexcel;charset=UTF-8");
// 导出订单Excel
ExportUtil exportUtil = new ExportUtil();
exportUtil.exportExcel("sheet", "", msCards, headers, includeFieldNames, new Integer[]{200}, res.getOutputStream(), null);
} catch (Exception e) {
e.printStackTrace();
}
}
注意:不能直接通过Ajax请求,需要通过表单提交。
xml方式转Excel用到的属性:
补充一个:
ss:MergeAcross 表示跨列合并,如下:
// 输出第一行的标题
if(!StrUtils.isBlank(firstRowTitle)){
//ss:StyleID可以加row或者Cell,加在Row,整行(包括空的Cell)都有,加上Cell,只有Cell才有。
sb.append("");
sb.append("" + firstRowTitle + "");
sb.append("");
}
注意是否需要减1,因为表示是跨多少列,那就是合并其它的几列,不包括自己,所以需要减 1
万能方法:
如果突然需要增加某些未知的属性,可以自己先创建一个Excel文件,做一个模板出来,然后另存为Xml文件,注意是Xml文件,保存后打开Xml文件查看自己创建的模板的某些属性应该怎么设置。但打开的xml文件比较乱,所以通过搜索找到自己对应的那个格子。
源码下载见:http://fanshuyao.iteye.com/blog/2393131
(如果你觉得文章对你有帮助,欢迎捐赠,^_^,谢谢!)
=============================
©Copyright 蕃薯耀 2017年9月13日
http://www.cnblogs.com/fanshuyao/