Java 通過Xml導出Excel文件,Java Excel 導出工具類,Java導出Excel工具類
阿新 • • 發佈:2017-09-13
public emp cep sdf value 提交 bsp datetime rtm
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工具類