1. 程式人生 > >excel匯出資料反射+註解

excel匯出資料反射+註解

package com.xx.system.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util
.Iterator; import java.util.Map; import org.apache.log4j.Logger; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util
.HSSFColor; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress
; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.xx.common.anno.Merge; import com.xx.common.utils.DateUtil; public class ExportExcelUtils<T> { private Logger log = Logger.getLogger("log"); @SuppressWarnings({"unused"}) public Workbook ExportExcel(String sheetName, String heading, String[] titles, Collection<T> dataset, int[] mergeCells, Map<String, Object> total){ return ExportExcelEx(null,sheetName,heading,titles,dataset,mergeCells,total,null); } public Workbook ExportExcelEx(Workbook workbook,String sheetName, String heading, String[] titles, Collection<T> dataset, int[] mergeCells, Map<String, Object> total, Map<Integer,Integer> cols){ Workbook[] wbs = new Workbook[]{new HSSFWorkbook(), new XSSFWorkbook()}; //設定表格版本 Workbook wb = null; if(workbook==null){ wb=wbs[0]; }else{ wb=workbook; } // 建立標題樣式 CellStyle titleStyle = wb.createCellStyle(); titleStyle.setFillForegroundColor(HSSFColor.PALE_BLUE.index); titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); titleStyle.setBorderTop(CellStyle.BORDER_THIN); titleStyle.setBorderLeft(CellStyle.BORDER_THIN); titleStyle.setBorderRight(CellStyle.BORDER_THIN); titleStyle.setBorderBottom(CellStyle.BORDER_THIN); titleStyle.setAlignment(CellStyle.ALIGN_CENTER); titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); Font titleFont = wb.createFont(); titleFont.setColor(HSSFFont.COLOR_NORMAL); titleFont.setFontHeightInPoints((short)11); titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD); titleStyle.setFont(titleFont); // 建立內容樣式 CellStyle dataStyle = wb.createCellStyle(); dataStyle.setBorderTop(CellStyle.BORDER_THIN); dataStyle.setBorderLeft(CellStyle.BORDER_THIN); dataStyle.setBorderRight(CellStyle.BORDER_THIN); dataStyle.setBorderBottom(CellStyle.BORDER_THIN); dataStyle.setAlignment(CellStyle.ALIGN_CENTER); dataStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); Font dataFont = wb.createFont(); dataFont.setFontHeightInPoints((short)11); dataStyle.setFont(dataFont); // 建立工作薄 Sheet sheet = wb.createSheet(sheetName); sheet.setDefaultColumnWidth((short)17);// 預設列寬 sheet.createFreezePane(0, 2, 0, 2); //設定列寬 if(cols!=null){ for(Map.Entry<Integer, Integer> entry:cols.entrySet()){ sheet.setColumnWidth(entry.getKey(), entry.getValue()); } } Row row = null; Cell cell = null; // 1. 建立標題(第一行) row = sheet.createRow(0); sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, (short)(titles.length - 1)));// 合併標題列 row.setHeightInPoints(20); cell = row.createCell(0); cell.setCellValue(heading); cell.setCellStyle(titleStyle); // 2. 建立列頭(第二行) row = sheet.createRow(1); row.setHeightInPoints(20); for(short i = 0; i < titles.length; i++){ cell = row.createCell(i); cell.setCellStyle(titleStyle); HSSFRichTextString text = new HSSFRichTextString(titles[i]); cell.setCellValue(text); } // 3. 建立內容 Iterator<T> it = dataset.iterator(); int index = 1;// 內容啟始行 String rowMergeFlag = null;// 要合併的數值標識 int startRow = index + 1;// 要合併的開始行號 int endRow = index + 1;// 要合併的結束行號 int rowNumber = 1;// 合併後的行號 while(it.hasNext()){ index++; row = sheet.createRow(index); T t = it.next(); Field[] fields = t.getClass().getDeclaredFields(); for(int i = 0; i < fields.length; i++){ Field field = fields[i]; String fieldName = field.getName(); String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); if(!fieldName.equals("rowMergeFlag")){ cell = row.createCell(i); cell.setCellStyle(dataStyle); } // 第一列為序號 if(i == 0){ cell.setCellValue(rowNumber); continue; } Class tCls = t.getClass(); try{ Method getMethod = tCls.getMethod(getMethodName, new Class[]{}); Object value = getMethod.invoke(t, new Object[]{}); String textVlaue = null; if(value != null){ if(fieldName.equals("rowMergeFlag")){ if(rowMergeFlag != null){ if(rowMergeFlag.equals(value.toString())){ endRow = index; if(!it.hasNext()){ for(int j = 0; j < mergeCells.length; j++){ sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, mergeCells[j], mergeCells[j]));// 合併 } } if(mergeCells.length == 0){ rowNumber++; startRow = index; } }else{ if(startRow < endRow){ for(int j = 0; j < mergeCells.length; j++){ sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, mergeCells[j], mergeCells[j]));// 合併 } } rowNumber++; startRow = index; } }else{ rowNumber++; startRow = index; } rowMergeFlag = value.toString(); continue; } if(value instanceof Date){ Date date = (Date)value; textVlaue = DateUtil.fmtDateToStr(date, "yyyy-MM-dd HH:mm:ss"); }else if(value instanceof BigDecimal){ NumberFormat point = NumberFormat.getCurrencyInstance(); point.setMaximumFractionDigits(2); textVlaue = point.format(value); }else{ textVlaue = value.toString(); } } if(textVlaue != null){ HSSFRichTextString text = new HSSFRichTextString(textVlaue); cell.setCellValue(text); }else{ cell.setCellValue(""); } }catch(NoSuchMethodException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(SecurityException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(IllegalAccessException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(IllegalArgumentException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(InvocationTargetException e){ // TODO Auto-generated catch block e.printStackTrace(); } } } /** 合計處理 */ // 金額樣式 CellStyle moneyStyle = wb.createCellStyle(); moneyStyle.setBorderTop(CellStyle.BORDER_THIN); moneyStyle.setBorderLeft(CellStyle.BORDER_THIN); moneyStyle.setBorderRight(CellStyle.BORDER_THIN); moneyStyle.setBorderBottom(CellStyle.BORDER_THIN); moneyStyle.setAlignment(CellStyle.ALIGN_RIGHT); moneyStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); Font moneyFont = wb.createFont(); moneyFont.setColor(HSSFColor.RED.index); moneyFont.setBoldweight(Font.BOLDWEIGHT_BOLD); moneyStyle.setFont(moneyFont); if(total != null){ if(!it.hasNext()){ StringBuffer totalVal = new StringBuffer("合計 - "); for (String key : total.keySet()) { String textVlaue = null; if(total.get(key) instanceof BigDecimal){ NumberFormat point = NumberFormat.getCurrencyInstance(); point.setMaximumFractionDigits(2); textVlaue = point.format(total.get(key)); } totalVal.append(key+":").append(textVlaue+" "); } int lastRow = index+1; row = sheet.createRow(lastRow); sheet.addMergedRegion(new CellRangeAddress(lastRow, lastRow, 0, (short)(titles.length - 1)));// 合併標題列 row.setHeightInPoints(20); cell = row.createCell(0); cell.setCellValue(totalVal.toString()); cell.setCellStyle(moneyStyle); } } return wb; } /** * * <p> * 支援多項合併 * 通過註解@Merge(isKey=true)確定主合併項,次合併項註解為@Merge * </p> */ public Workbook ExportExcelWithMoreMergeValue(Workbook workbook,String sheetName, String heading, String[] titles, Collection<T> dataset, Map<String,int[]> mergeCellsMap, Map<String, Object> total, Map<Integer,Integer> cols) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ Workbook[] wbs = new Workbook[]{new HSSFWorkbook(), new XSSFWorkbook()}; //設定表格版本 Workbook wb = null; if(workbook==null){ wb=wbs[0]; }else{ wb=workbook; } // 建立標題樣式 CellStyle titleStyle = wb.createCellStyle(); titleStyle.setFillForegroundColor(HSSFColor.PALE_BLUE.index); titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); titleStyle.setBorderTop(CellStyle.BORDER_THIN); titleStyle.setBorderLeft(CellStyle.BORDER_THIN); titleStyle.setBorderRight(CellStyle.BORDER_THIN); titleStyle.setBorderBottom(CellStyle.BORDER_THIN); titleStyle.setAlignment(CellStyle.ALIGN_CENTER); titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); Font titleFont = wb.createFont(); titleFont.setColor(HSSFFont.COLOR_NORMAL); titleFont.setFontHeightInPoints((short)11); titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD); titleStyle.setFont(titleFont); // 建立內容樣式 CellStyle dataStyle = wb.createCellStyle(); dataStyle.setBorderTop(CellStyle.BORDER_THIN); dataStyle.setBorderLeft(CellStyle.BORDER_THIN); dataStyle.setBorderRight(CellStyle.BORDER_THIN); dataStyle.setBorderBottom(CellStyle.BORDER_THIN); dataStyle.setAlignment(CellStyle.ALIGN_CENTER); dataStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); Font dataFont = wb.createFont(); dataFont.setFontHeightInPoints((short)11); dataStyle.setFont(dataFont); // 建立工作薄 Sheet sheet = wb.createSheet(sheetName); sheet.setDefaultColumnWidth((short)17);// 預設列寬 sheet.createFreezePane(0, 2, 0, 2); //設定列寬 if(cols!=null){ for(Map.Entry<Integer, Integer> entry:cols.entrySet()){ sheet.setColumnWidth(entry.getKey(), entry.getValue()); } } Row row = null; Cell cell = null; // 1. 建立標題(第一行) row = sheet.createRow(0); sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, (short)(titles.length - 1)));// 合併標題列 row.setHeightInPoints(20); cell = row.createCell(0); cell.setCellValue(heading); cell.setCellStyle(titleStyle); // 2. 建立列頭(第二行) row = sheet.createRow(1); row.setHeightInPoints(20); for(short i = 0; i < titles.length; i++){ cell = row.createCell(i); cell.setCellStyle(titleStyle); HSSFRichTextString text = new HSSFRichTextString(titles[i]); cell.setCellValue(text); } // 3. 建立內容 Iterator<T> it = dataset.iterator(); Integer index = 1;// 內容啟始行 Integer startRow = index + 1;// 要合併的開始行號 Integer endRow = index + 1;// 要合併的結束行號 Integer rowNumber = 1;// 合併後的行號 Map<String,CellRangeAddress> mergeAddressMap=new HashMap<String,CellRangeAddress>(); Map<String,Integer> startRowMap=new HashMap<String,Integer>(); Map<String,Object> mergeMap=new HashMap<String,Object>(); while(it.hasNext()){ T t = it.next(); Field[] fields = t.getClass().getDeclaredFields(); Object keyValue=null; String keyFiledName=null; Class tCls = t.getClass(); for(int i = 0; i < fields.length; i++){ Field field = fields[i]; Merge anno=field.getAnnotation(Merge.class); if(anno!=null&&anno.isKey()){ keyFiledName=field.getName(); String getMethodName = "get" + keyFiledName.substring(0, 1).toUpperCase() + keyFiledName.substring(1); Method getMethod = tCls.getMethod(getMethodName, new Class[]{}); keyValue = getMethod.invoke(t, new Object[]{}); } } index++; row = sheet.createRow(index); // Field[] fields = t.getClass().getDeclaredFields(); int[] mergeCells=null; log.info("---------"+index+"-----------------"); for(int i = 0; i < fields.length; i++){ Field field = fields[i]; String fieldName = field.getName(); String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Merge anno=field.getAnnotation(Merge.class); /*if(anno==null){ cell = row.createCell(i); cell.setCellStyle(dataStyle); }*/ cell = row.createCell(i); cell.setCellStyle(dataStyle); // 第一列為序號 if(i == 0){ cell.setCellValue(rowNumber); continue; } try{ Method getMethod = tCls.getMethod(getMethodName, new Class[]{}); Object value = getMethod.invoke(t, new Object[]{}); String textVlaue = null; if(value != null){ if(anno!=null){ mergeCells=mergeCellsMap.get(fieldName); String mergeValue=mergeMap.get(fieldName)==null?"--":mergeMap.get(fieldName).toString(); log.info("mergeMap:get:mergeValue=>"+mergeValue); if(mergeMap.get(fieldName) != null){ String key=keyFiledName+"_"+keyValue.toString()+"_"+value; startRow=startRowMap.get(key); if(mergeMap.get(fieldName).equals(value.toString())&&startRow!=null){ endRow = index; /* String key=keyFiledName+"_"+keyValue.toString()+"_"+value; startRow=startRowMap.get(key);*/ log.info("get=>key:value=>"+key+":"+startRow); for(int j = 0; j < mergeCells.length; j++){ //sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, mergeCells[j], mergeCells[j]));// 合併 mergeAddressMap.put(key+"_"+mergeCells[j], new CellRangeAddress(startRow, endRow, mergeCells[j], mergeCells[j])); log.info("put=>key:start:end:colsnumber=>"+key+"_"+mergeCells[j]+":"+startRow+":"+endRow+":"+j); } if(anno.isKey()){ mergeAddressMap.put(key+"_0", new CellRangeAddress(startRow, endRow, 0, 0)); } if(mergeCells.length == 0){ startRow = index; } }else{ if(anno.isKey()){ rowNumber++; } startRowMap.put(key, index); log.info("put=>key:value=>"+key+":"+index); } }else{ if(anno.isKey()){ rowNumber++; } String key=keyFiledName+"_"+keyValue.toString()+"_"+value; startRowMap.put(key, index); log.info("put=>key:value=>"+key+":"+index); } mergeMap.put(fieldName, value); log.info("mergeMap:put:mergeValue=>"+fieldName+":"+value); } if(value instanceof Date){ Date date = (Date)value; textVlaue = DateUtil.fmtDateToStr(date, "yyyy-MM-dd HH:mm:ss"); }else if(value instanceof BigDecimal){ NumberFormat point = NumberFormat.getCurrencyInstance(); point.setMaximumFractionDigits(2); textVlaue = point.format(value); }else{ textVlaue = value.toString(); } } if(textVlaue != null){ HSSFRichTextString text = new HSSFRichTextString(textVlaue); cell.setCellValue(text); }else{ cell.setCellValue(""); } //rowNumber++; }catch(NoSuchMethodException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(SecurityException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(IllegalAccessException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(IllegalArgumentException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch(InvocationTargetException e){ // TODO Auto-generated catch block e.printStackTrace(); } } } /**合併處理**/ if(mergeAddressMap!=null){ for(CellRangeAddress address:mergeAddressMap.values()){ if(address.getFirstRow()<address.getLastRow()){ sheet.addMergedRegion(address); } } } /** 合計處理 */ // 金額樣式 CellStyle moneyStyle = wb.createCellStyle(); moneyStyle.setBorderTop(CellStyle.BORDER_THIN); moneyStyle.setBorderLeft(CellStyle.BORDER_THIN); moneyStyle.setBorderRight(CellStyle.BORDER_THIN); moneyStyle.setBorderBottom(CellStyle.BORDER_THIN); moneyStyle.setAlignment(CellStyle.ALIGN_RIGHT); moneyStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); Font moneyFont = wb.createFont(); moneyFont.setColor(HSSFColor.RED.index); moneyFont.setBoldweight(Font.BOLDWEIGHT_BOLD); moneyStyle.setFont(moneyFont); if(total != null){ if(!it.hasNext()){ StringBuffer totalVal = new StringBuffer("合計 - "); for (String key : total.keySet()) { String textVlaue = null; if(total.get(key) instanceof BigDecimal){ NumberFormat point = NumberFormat.getCurrencyInstance(); point.setMaximumFractionDigits(2); textVlaue = point.format(total.get(key)); } totalVal.append(key+":").append(textVlaue+" "); } int lastRow = index+1; row = sheet.createRow(lastRow); sheet.addMergedRegion(new CellRangeAddress(lastRow, lastRow, 0, (short)(titles.length - 1)));// 合併標題列 row.setHeightInPoints(20); cell = row.createCell(0); cell.setCellValue(totalVal.toString()); cell.setCellStyle(moneyStyle); } } return wb; } }