Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类相关的知识,希望对你有一定的参考价值。

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 <T> void exportExcel(String sheetName, String firstRowTitle, List<T> 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("<Workbook xmlns=\\"urn:schemas-microsoft-com:office:spreadsheet\\"");
		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("<Styles>\\n");
		
		/*设置列头样式*/
		sb.append("<Style ss:ID=\\"header\\" ss:Name=\\"header\\">\\n");//ss:ID=“header”对应下面的Row ss:StyleID=“header”
		sb.append("<Interior ss:Color=\\"#c4d79b\\" ss:Pattern=\\"Solid\\"/>\\n");// 设置背景颜色
		sb.append("<Font ss:FontName=\\"微软雅黑\\" x:CharSet=\\"134\\" ss:Bold=\\"Bolder\\" ss:Size=\\"12\\"/>\\n");//设置字体
		sb.append("</Style>\\n");
		
		/*其它默认样式设置*/
		sb.append("<Style ss:ID=\\"Default\\" ss:Name=\\"Normal\\">\\n");
		//sb.append("<Alignment ss:Vertical=\\"Center\\"/>\\n");
		sb.append("<Alignment ss:Horizontal=\\"Center\\" ss:Vertical=\\"Center\\" ss:WrapText=\\"1\\"/>\\n");// 左中右设置,一个是水平,一个是垂直
		sb.append("<Borders>\\n");
		sb.append("<Border ss:Position=\\"Left\\" ss:LineStyle=\\"Continuous\\" ss:Color=\\"#666\\" ss:Weight=\\"1\\"/>\\n");//左边框设置
		sb.append("<Border ss:Position=\\"Right\\" ss:LineStyle=\\"Continuous\\" ss:Color=\\"#666\\" ss:Weight=\\"1\\"/>\\n");//右边框设置
		sb.append("<Border ss:Position=\\"Bottom\\" ss:LineStyle=\\"Continuous\\" ss:Color=\\"#666\\" ss:Weight=\\"1\\"/>\\n");//下边框设置
		sb.append("<Border ss:Position=\\"Top\\" ss:LineStyle=\\"Continuous\\" ss:Color=\\"#666\\" ss:Weight=\\"1\\"/>\\n");//上边框设置
		sb.append("</Borders>\\n");
		sb.append("<Font ss:FontName=\\"宋体\\" x:CharSet=\\"134\\" ss:Size=\\"12\\"/>\\n");
		sb.append("<Interior/>\\n");
		sb.append("<NumberFormat/>\\n");
		sb.append("<Protection/>\\n");
		sb.append("</Style>\\n");
		
		sb.append("</Styles>\\n");
		
		try {
			
			// 生成表格
			int headersLength = headers.length;
			
			sb.append("<Worksheet ss:Name=\\"" + sheetName + "\\">");
			sb.append("\\n");
			sb.append("<Table ss:ExpandedColumnCount=\\"" + headersLength
					+ "\\" 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("<Column ss:AutoFitWidth=\\"0\\" ss:Width=\\""+widths[i]+"\\"/>");
					}
				}else{
					for (int i = 0; i < headersLength; i++) {
						sb.append("<Column ss:AutoFitWidth=\\"0\\" ss:Width=\\""+widths[0]+"\\"/>");
					}
				}
			}
			
			
			// 输出第一行的标题
			if(!StrUtils.isBlank(firstRowTitle)){
				//ss:StyleID可以加row或者Cell,加在Row,整行(包括空的Cell)都有,加上Cell,只有Cell才有。
				sb.append("<Row  ss:Height=\\"30\\">");
				sb.append("<Cell ss:StyleID=\\"header\\" ss:MergeAcross=\\""+ (headersLength - 1)+"\\"><Data ss:Type=\\"String\\">" + firstRowTitle + "</Data></Cell>");
				sb.append("</Row>");
			}
			
			// 输出列头
			sb.append("<Row>");
			for (int i = 0; i < headersLength; i++) {
				sb.append("<Cell ss:StyleID=\\"header\\"><Data ss:Type=\\"String\\">" + headers[i] + "</Data></Cell>");
			}
			sb.append("</Row>");
			
			// 构建表体数据
			for (int j = 0; j < list.size(); j++) {
				
				sb.append("<Row>");
				
				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("<Cell><Data ss:Type=\\"String\\">");
					
					// 如果不是图片数据,就利用正则表达式判断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("</Data></Cell>");
					
				}
				
				sb.append("</Row>");
				sb.append("\\n");
				
			}
			
			sb.append("</Table>");
			sb.append("<WorksheetOptions xmlns=\\"urn:schemas-microsoft-com:office:excel\\">");
			sb.append("\\n");
			sb.append("<ProtectObjects>False</ProtectObjects>");
			sb.append("\\n");
			sb.append("<ProtectScenarios>False</ProtectScenarios>");
			sb.append("\\n");
			sb.append("</WorksheetOptions>");
			sb.append("\\n");
			sb.append("</Worksheet>");
			sb.append("</Workbook>");
			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<MsCard> 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("<Row  ss:Height=\\"30\\">");
	sb.append("<Cell ss:StyleID=\\"header\\" ss:MergeAcross=\\""+ (headersLength - 1)+"\\"><Data ss:Type=\\"String\\">" + firstRowTitle + "</Data></Cell>");
	sb.append("</Row>");
}

  

 注意是否需要减1,因为表示是跨多少列,那就是合并其它的几列,不包括自己,所以需要减 1

 

万能方法:

如果突然需要增加某些未知的属性,可以自己先创建一个Excel文件,做一个模板出来,然后另存为Xml文件,注意是Xml文件,保存后打开Xml文件查看自己创建的模板的某些属性应该怎么设置。但打开的xml文件比较乱,所以通过搜索找到自己对应的那个格子。

 

源码下载见:http://fanshuyao.iteye.com/blog/2393131

 

=============================

?Copyright 蕃薯耀 2017年9月13日

http://www.cnblogs.com/fanshuyao/



以上是关于Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类的主要内容,如果未能解决你的问题,请参考以下文章

Java通过FreeMarker作为模板导出Excel

java使用freemarker作为模板导出Excel表格

java导出大批量(百万以上)数据的excel文件

如何导出java工程项目里面的excel文件

Java:SpringBoot使用EasyExcel实现Excel文件的导出下载和上传导入功能

求java导出大量数据到excel解决方法