1. 程式人生 > >java中,list集合資料匯出到excel表格通用工具類

java中,list集合資料匯出到excel表格通用工具類

1.建立CustomTag類(實體類class自定義欄位名稱註解類)

package CzExcel;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
 * 實體類class欄位名稱註解類
 * @author xgf
 *
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomTag {
    //欄位的描述註解
     String desc();
}

2.建立CustomTagMethod類(實體類自定義方法註解類)

package CzExcel;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 
/**
 * 實體類方法註解類
 * @author xgf
 *
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomTagMethod {
    //欄位的描述註解
     String name();
}

3.建立CustomTagClass類(實體類class名稱自定義註解類)

package CzExcel;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 /**
  * 實體類class名稱註解類
  * @author xgf
  *
  */
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomTagClass {
    //欄位的描述註解
     String name();
}

4.建立ClassUtil類(實體類操作工具類)

package CzExcel;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 實體類操作工具類
 * @author xgf
 *
 */
public class ClassUtil {
	private static Logger logger = LoggerFactory.getLogger(ClassUtil.class);
	/**
	 * 通過屬性取得屬性的描述註解
	 * 
	 * @param field
	 * @return
	 */
	public static String getDesc(Field field) {
		String result = null;
		try {
			field.setAccessible(true);
			Annotation[] annotation = field.getAnnotations();
			for (Annotation tag : annotation) {
				if (tag instanceof CustomTag) {
					result = ((CustomTag) tag).desc();
					break;
				}
			}
		} catch (SecurityException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return result;
		// return getAnnotation(DESC, field);
		// return getAnnotation(field);
	}
 
	/**
	 * 通過物件和屬性名稱取得屬性的描述註解
	 * 
	 * @param obj
	 * @param propertyName
	 * @return
	 */
	public static String getDesc(Object obj, String propertyName) {
		String result = null;
		try {
			Field[] fields = obj.getClass().getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.getName().equals(propertyName)) {
					String desc = getDesc(field);
					if (desc != null && !desc.isEmpty()) {
						result = desc;
						break;
					}
				}
			}
		} catch (SecurityException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return result;
	}
 
	
 
	/**
	 * 取得obj所有屬性的描述註解,返回值為key為obj的屬性名稱,value為此屬性的描述註解
	 * 
	 * @param obj
	 * @return
	 */
	public static Map<String, String> getAllDesc(Object obj) {
		try {
			Field[] fields = obj.getClass().getDeclaredFields();
			return getResult(fields);
		} catch (SecurityException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}
 
	/**
	 * 取得obj所有屬性的描述註解,返回值為key為obj的屬性名稱,value為此屬性的描述註解
	 * 
	 * @param obj
	 * @return
	 */
	public static Map<String, String> getAllDesc(String clzName) {
		try {
			Field[] fields = Class.forName(clzName).getDeclaredFields();
			return getResult(fields);
		} catch (SecurityException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}
 
	/**
	 * 將field[]裡的欄位名稱做為key和欄位描述做value放在map中
	 * 
	 * @param fields
	 * @param map
	 */
	private static Map<String, String> getResult(Field[] fields) {
		Map<String, String> result = new HashMap<String, String>();
		for (Field field : fields) {
			field.setAccessible(true);
			if (field.getName().equals("id")) {
				continue;
			}
			String desc = getDesc(field);
			if (desc != null && !desc.isEmpty()) {
				result.put(field.getName(), getDesc(field));
			}
		}
		return result;
	}
	public static String getClassName(Class<?> class1){
		 //獲取類上的註解值  
		CustomTagClass anno = class1.getAnnotation(CustomTagClass.class);  
        if(anno != null){  
            Method[] met = anno.annotationType().getDeclaredMethods();  
            for(Method me : met ){  
                if(!me.isAccessible()){  
                    me.setAccessible(true);  
                }  
                try {  
                    return (String) me.invoke(anno, null);  
                } catch (IllegalAccessException e) {  
                    e.printStackTrace();  
                } catch (IllegalArgumentException e) {  
                    e.printStackTrace();  
                } catch (InvocationTargetException e) {  
                    e.printStackTrace();  
                }  
            }  
        } 
        return "";
	}
}

5.建立Model類(自定義實體類)

package CzExcel;

import java.sql.Timestamp;
import java.util.Date;

/**
 * 實體類
 * @author xgf
 *
 */
@CustomTagClass(name="測試類")
public class Model {
	@CustomTag(desc="名稱")
	private String mc;
	@CustomTag(desc="日期")
	private Date rq;
	@CustomTag(desc="時間")
	private Timestamp sj;
	@CustomTag(desc="類別")
	private String type;
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getMc() {
		return mc;
	}
	public void setMc(String mc) {
		this.mc = mc;
	}
	public Date getRq() {
		return rq;
	}
	public void setRq(Date rq) {
		this.rq = rq;
	}
	public Timestamp getSj() {
		return sj;
	}
	public void setSj(Timestamp sj) {
		this.sj = sj;
	}
}

6.建立MapKeyComparator類(map排序比較器類)

package CzExcel;

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

/**
 * map排序比較器類
 * @author xgf
 *
 */
public class MapKeyComparator implements Comparator<String>{
	@Override
    public int compare(String str1, String str2) {
        return str1.compareTo(str2);
    }
	/**
     * 使用 Map按key進行排序
     * @param map
     * @return
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, Object> sortMap = new TreeMap<String, Object>(
                new MapKeyComparator());

        sortMap.putAll(map);

        return sortMap;
    }
}

7.建立ExportExcel類(list集合資料匯出到excel表格中通用工具類)

package CzExcel;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
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.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * list資料匯出到excel表格中工具類
 * @author xgf
 *
 */
public class ExportExcel
{
    private static Logger logger = LoggerFactory.getLogger(ExportExcel.class);
    /**
     * 資料轉換
     * @param list 資料
     * @param fileName 檔案地址
     * @param type 是否需要排序:1需要排序,2不需要排序
     * @param headersNew 排序欄位
     */
    public static void exportExcelUtil(List<?> list,String fileName,String type,String[] headersNew,Object obj) {
		try {
			//List<Model>轉List<Map>
	    	List<Map> dataset=new ArrayList<Map>();
	    	
	    	Map<String,String> mapPx=new HashMap<String,String>();//獲取排序陣列下標
	    	for (int i = 0; i < headersNew.length; i++) {
	    		mapPx.put(headersNew[i], i+"");
			}
	    	
	    	for (int i = 0; i < list.size(); i++) {
	    		if(type.equals("1")){
	    			Map map=transBean2Map(list.get(i));
		    		Map mapNew=new HashMap<>();
		    		for (Object key : map.keySet()) {
		    			mapNew.put(mapPx.get(key.toString()), map.get(key));
		    		}
		    		mapNew=MapKeyComparator.sortMapByKey(mapNew);
		    		dataset.add(mapNew);
	    		}else{
	    			dataset.add(transBean2Map(list.get(i)));
	    		}
			}
	    	
	    	//獲取表頭
	    	Map<String,String> map = ClassUtil.getAllDesc(obj);
	    	
	    	//設定excel表頭
	    	//String[] headers={"mc","rq","sj"};
	    	String[] headers=null;
	    	
	    	Object[] keys  =  map.keySet().toArray();//從實體類中取欄位
	    	String[]  headersZd=new String[keys.length];
	    	for (int i = 0; i < keys.length; i++) {
	    		headersZd[i]=keys[i].toString();
			}
	    	if(type.equals("1")){
		    	headers=headersNew;
	    	}else{
	    		headers=headersZd;
	    	}
	    	
	    	String[] headersTitle=null;
	    	
	    	Object[] keysTitle  =  map.values().toArray();//從實體類中取欄位註釋
	    	String[] headersTitleZs=new String[keysTitle.length];
	    	for (int i = 0; i < keysTitle.length; i++) {
	    		headersTitleZs[i]=keysTitle[i].toString();
			}
	    	
	    	if(type.equals("1")){
	    		Map<String,String> mapZs=new HashMap<String,String>();
	    		for (int i = 0; i < headersZd.length; i++) {
	    			mapZs.put(headersZd[i], headersTitleZs[i]);
				}
	    		headersTitle=new String[headersTitleZs.length];
	    		for (int i = 0; i < headers.length; i++) {
	    			headersTitle[i]=mapZs.get(headers[i]);
				}
	    		
	    	}else{
	    		headersTitle=headersTitleZs;
	    	}
	    	
	    	
	    	//獲取類上的註解值  
	    	String title=ClassUtil.getClassName(obj.getClass());
	    	if(StringUtils.isNotBlank(title)==false){
	    		title="Sheet1";
	    	}
	    	
	    	exportExcel(fileName,title,headers,headersTitle,dataset,"yyyy-MM-dd","2");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 把內容寫入excel表格中
	 * @param fileName 檔案地址
	 * @param title excel表格工作空間名稱
	 * @param headers 表格列欄位
	 * @param headersTitle 表格表頭中文欄位
	 * @param dataset 資料
	 * @param pattern 日期、時間格式化輸出
	 * @param type 表格表頭展示方式:1實體類欄位名,2實體類欄位名註釋
	 * @return
	 */
	public static boolean exportExcel(String fileName, String title, String[] headers,String[] headersTitle, List<Map> dataset, String pattern,String type)
    {
        boolean flag = false;
        Workbook workbook = null;
        if (fileName.endsWith("xlsx"))
        {
            workbook = new XSSFWorkbook();
        } else if (fileName.endsWith("xls"))
        {
            workbook = new HSSFWorkbook();
        } else
        {
            try
            {
                throw new Exception("invalid file name, should be xls or xlsx");
            } catch (Exception e)
            {
                logger.info("必須是xls或者xlsx結尾的檔案.");
                e.printStackTrace();
            }
            
        }

        Sheet sheet = workbook.createSheet(title);
          CellStyle style = workbook.createCellStyle();
        
        // 列名
        Row row = sheet.createRow(0);
        switch (type) {
		case "1":
			for (int i = 0; i < headers.length; i++)
	        {
	            Cell cell = row.createCell(i);
	            sheet.setColumnWidth(i, 5000);
	            style.setAlignment(CellStyle.ALIGN_CENTER);
	            cell.setCellValue(headers[i]);
	        }
			break;
		case "2":
			for (int i = 0; i < headersTitle.length; i++)
	        {
	            Cell cell = row.createCell(i);
	            sheet.setColumnWidth(i, 5000);
	            style.setAlignment(CellStyle.ALIGN_CENTER);
	            cell.setCellValue(headersTitle[i]);
	        }
			break;
		}
        

        Iterator<Map> it = dataset.iterator();
        int index = 0;
        while (it.hasNext())
        {
            index++;
            row = sheet.createRow(index);
            
            Map map = it.next();
            logger.info(map.toString());
            Set<String> mapKey = (Set<String>)map.keySet();
            logger.info(mapKey.toString());
            Iterator<String> iterator = mapKey.iterator();
            logger.info(iterator.toString());
            int num  = 0;
            while(iterator.hasNext()){
                Cell cell = row.createCell(num);
                num++;
                String key = iterator.next();
                logger.info(key);
                Object obj = map.get(key);
                if (obj instanceof Date || obj instanceof Timestamp)
                {
                    SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                    cell.setCellValue(sdf.format(obj));
                } else if (obj instanceof Integer)
                {
                    cell.setCellValue((Integer) obj);
                } else if (obj instanceof Double)
                {
                    cell.setCellValue((Double) obj);
                }else
                {
                    cell.setCellValue((String) obj);
                }
            }
        }
        
        FileOutputStream fos;
        try
        {
            fos = new FileOutputStream(fileName);
            workbook.write(fos);
            fos.close();
            flag = true;
        } catch (FileNotFoundException e)
        {
            logger.info("檔案不存在");
            flag = false;
            e.printStackTrace();
        } catch (IOException e)
        {
            logger.info("檔案寫入錯誤");
            flag = false;
            e.printStackTrace();
            
        }
        return flag;
    }
    /**
     * 實體類轉map
     * @param obj
     * @return
     */
    public static Map<String, Object> transBean2Map(Object obj) {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 過濾class屬性
				if (!key.equals("class")) {
					// 得到property對應的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
 
					map.put(key, value);
				}
 
			}
		} catch (Exception e) {
			logger.error("transBean2Map Error {}" ,e);
		}
		return map;
 
	}
}

8.建立Test類(測試類)

package CzExcel;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 測試類
 * @author xgf
 *
 */
public class Test {
	public static void main(String[] args) {
    	
    	//初始化資料
    	List<Model> list=new ArrayList<Model>();
    	for (int i = 0; i < 10; i++) {
    		Model model=new Model();
        	model.setMc("測試"+i);
        	model.setRq(new Date());
        	model.setSj(new Timestamp(System.currentTimeMillis()));
        	model.setType("111111111111111");
        	list.add(model);
		}
    	String fileName="D:\\test\\text.xlsx";
    	
    	
    	//自定義excel表格表頭展示欄位順序
    	//獲取實體類欄位
    	Map<String,String> map = ClassUtil.getAllDesc(new Model());
    	Object[] keys  =  map.keySet().toArray();//從實體類中取欄位
    	String[]  headers=new String[keys.length];
    	StringBuffer str=new StringBuffer("{");
    	for (int i = 0; i < keys.length; i++) {
    		headers[i]=keys[i].toString();
    		str.append("\""+keys[i].toString()+"\"");
    		if(i<(keys.length-1)){
    			str.append(",");
    		}
		}
    	str.append("}");
    	System.out.println(str.toString());//把打印出來的字串拷貝到headers=後面,根據需要,調整欄位顯示的順序
    	
    	
    	//String[] headers={"type","mc","rq","sj"};
    	ExportExcel.exportExcelUtil(list,fileName,"1",headers,new Model());
	}
}

例項程式碼(例項程式碼中支援多個工作空間資料的匯入)

https://download.csdn.net/download/qq_19640525/10567891