excel匯出資料反射+註解
阿新 • • 發佈:2019-01-02
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;
}
}