java導出excel工具類(賊好用)

項目中自用的導出excel工具:

 

實體類:

package com.mapuni.survey.entity;

public class ExcelEntity {
	private String field;
	private String title;
	public String getField() {
		return field;
	}
	public void setField(String field) {
		this.field = field;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

 工具類:

package com.mapuni.survey.util;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletResponse;

import com.mapuni.survey.entity.ExcelEntity;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

/**
 * 導入導出Excel工具類(必須有對應的實體類)
 * @author ccf
 *
 */
public class ExcelUtil_cf  {

    /**
     * @MethodName  : listToExcel
     * @Description : 導出Excel(可以導出到本地文件系統,也可以導出到瀏覽器,可自定義工作表大小)
     * @param list      數據源
     * @param fieldMap      類的英文屬性和Excel中的中文列名的對應關係
     * 如果需要的是引用對象的屬性,則英文屬性使用類似於EL表達式的格式
     * 如:list中存放的都是student,student中又有college屬性,而我們需要學院名稱,則可以這樣寫
     * fieldMap.put("college.collegeName","學院名稱")
     * @param sheetName 工作表的名稱
     * @param sheetSize 每個工作表中記錄的最大個數
     * @param out       導出流
     * @throws ExcelException
     */
    public static <T>  void   listToExcel (
            List<T> list ,
            LinkedHashMap<String,String> fieldMap,
            String sheetName,
            int sheetSize,
            OutputStream out
            ) throws ExcelException{


        if(list.size()==0 || list==null){
            throw new ExcelException("數據源中沒有任何數據");
        }

        if(sheetSize>65535 || sheetSize<1){
            sheetSize=65535;
        }

        //創建工作簿併發送到OutputStream指定的地方
        WritableWorkbook wwb;
        try {
            wwb = Workbook.createWorkbook(out);

            //因爲2003的Excel一個工作表最多可以有65536條記錄,除去列頭剩下65535條
            //所以如果記錄太多,需要放到多個工作表中,其實就是個分頁的過程
            //1.計算一共有多少個工作表
            double sheetNum=Math.ceil(list.size()/new Integer(sheetSize).doubleValue());

            //2.創建相應的工作表,並向其中填充數據
            for(int i=0; i<sheetNum; i++){
                //如果只有一個工作表的情況
                if(1==sheetNum){
                    WritableSheet sheet=wwb.createSheet(sheetName, i);
                    fillSheet(sheet, list, fieldMap, 0, list.size()-1);

                //有多個工作表的情況
                }else{
                    WritableSheet sheet=wwb.createSheet(sheetName+(i+1), i);

                    //獲取開始索引和結束索引
                    int firstIndex=i*sheetSize;
                    int lastIndex=(i+1)*sheetSize-1>list.size()-1 ? list.size()-1 : (i+1)*sheetSize-1;
                    //填充工作表
                    fillSheet(sheet, list, fieldMap, firstIndex, lastIndex);
                }
            }

            wwb.write();
            wwb.close();

        }catch (Exception e) {
            e.printStackTrace();
            //如果是ExcelException,則直接拋出
            if(e instanceof ExcelException){
                throw (ExcelException)e;

            //否則將其它異常包裝成ExcelException再拋出
            }else{
                throw new ExcelException("導出Excel失敗");
            }
        }

    }

    /**
     * @MethodName  : listToExcel
     * @Description : 導出Excel(可以導出到本地文件系統,也可以導出到瀏覽器,工作表大小爲2003支持的最大值)
     * @param list      數據源
     * @param fieldMap      類的英文屬性和Excel中的中文列名的對應關係
     * @param out       導出流
     * @throws ExcelException
     */
    public static  <T>  void   listToExcel (
            List<T> list ,
            LinkedHashMap<String,String> fieldMap,
            String sheetName,
            OutputStream out
            ) throws ExcelException{

        listToExcel(list, fieldMap, sheetName, 65535, out);

    }


    /**
     * @MethodName  : listToExcel
     * @Description : 導出Excel(導出到瀏覽器,可以自定義工作表的大小)
     * @param list      數據源
     * @param fieldMap      類的英文屬性和Excel中的中文列名的對應關係
     * @param sheetSize    每個工作表中記錄的最大個數
     * @param response  使用response可以導出到瀏覽器
     * @throws ExcelException
     */
    public static  <T>  void   listToExcel (
            List<T> list ,
            LinkedHashMap<String,String> fieldMap,
            String sheetName,
            int sheetSize,
            HttpServletResponse response 
            ) throws ExcelException{

        //設置默認文件名爲當前時間:年月日時分秒
        String fileName=new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()).toString();

        //設置response頭信息
        response.reset();          
        response.setContentType("application/vnd.ms-excel");        //改成輸出excel文件
        response.setHeader("Content-disposition","attachment; filename="+fileName+".xls" );

        //創建工作簿併發送到瀏覽器
        try {

            OutputStream out=response.getOutputStream();
            listToExcel(list, fieldMap, sheetName, sheetSize,out );

        } catch (Exception e) {
            e.printStackTrace();

            //如果是ExcelException,則直接拋出
            if(e instanceof ExcelException){
                throw (ExcelException)e;

            //否則將其它異常包裝成ExcelException再拋出
            }else{
                throw new ExcelException("導出Excel失敗");
            }
        }
    }


    /**
     * @MethodName  : listToExcel
     * @Description : 導出Excel(導出到瀏覽器,工作表的大小是2003支持的最大值)
     * @param list      數據源
     * @param fieldMap      類的英文屬性和Excel中的中文列名的對應關係
     * @param response  使用response可以導出到瀏覽器
     * @throws ExcelException
     */
    public static <T>  void   listToExcel (
            List<T> list ,
            LinkedHashMap<String,String> fieldMap,
            String sheetName,
            HttpServletResponse response 
            ) throws ExcelException{

        listToExcel(list, fieldMap, sheetName, 65535, response);
    }

     




    /*<-------------------------輔助的私有方法----------------------------------------------->*/
    /**
     * @MethodName  : getFieldValueByName
     * @Description : 根據字段名獲取字段值
     * @param fieldName 字段名
     * @param o 對象
     * @return  字段值
     */
    private static  Object getFieldValueByName(String fieldName, Object o) throws Exception{

        Object value=null;
        Map<String,String> map = (Map<String,String>)o;
        String field=getFieldByName(fieldName, map);

//        if(field !=null){
//            field.setAccessible(true);
//            value=field.get(o);
//        }else{
//            throw new ExcelException(o.getClass().getSimpleName() + "類不存在字段名 "+fieldName);
//        }

        return field;
    }

    /**
     * @MethodName  : getFieldByName
     * @Description : 根據字段名獲取字段
     * @param fieldName 字段名
     * @param clazz 包含該字段的類
     * @return 字段
     */
    private static String getFieldByName(String fieldName, Map<String,String>  clazz){
        //拿到本類的所有字段
        String selfFields=clazz.get(fieldName);
        //如果本類中存在該字段,則返回
//        for(Field field : selfFields){
//            if(selfFields.equals(fieldName)){
                return selfFields;
//            }
//        }

//        //否則,查看父類中是否存在此字段,如果有則返回
//        Class<?> superClazz=clazz.getSuperclass();
//        if(superClazz!=null  &&  superClazz !=Object.class){
//            return getFieldByName(fieldName, superClazz);
//        }

        //如果本類和父類都沒有,則返回空
//        return null;
    }



    /**
     * @MethodName  : getFieldValueByNameSequence
     * @Description : 
     * 根據帶路徑或不帶路徑的屬性名獲取屬性值
     * 即接受簡單屬性名,如userName等,又接受帶路徑的屬性名,如student.department.name等
     * 
     * @param fieldNameSequence  帶路徑的屬性名或簡單屬性名
     * @param o 對象
     * @return  屬性值
     * @throws Exception
     */
    private static  Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception{

        Object value=null;

        //將fieldNameSequence進行拆分
        String[] attributes=fieldNameSequence.split("\\.");
        if(attributes.length==1){
            value=getFieldValueByName(fieldNameSequence, o);
        }else{
            //根據屬性名獲取屬性對象
            Object fieldObj=getFieldValueByName(attributes[0], o);
            String subFieldNameSequence=fieldNameSequence.substring(fieldNameSequence.indexOf(".")+1);
            value=getFieldValueByNameSequence(subFieldNameSequence, fieldObj);
        }
        return value; 

    } 


    /**
     * @MethodName  : setFieldValueByName
     * @Description : 根據字段名給對象的字段賦值
     * @param fieldName  字段名
     * @param fieldValue    字段值
     * @param o 對象
     */
    @SuppressWarnings("unchecked")
    private static void setFieldValueByName(String fieldName,Object fieldValue,Object o) throws Exception{
    	Map<String,String> map = (Map<String,String>)o;
            String field=getFieldByName(fieldName, map);
//            if(field!=null){
//                field.setAccessible(true);
//                //獲取字段類型
//                Class<?> fieldType = field.getType();  
//
//                //根據字段類型給字段賦值
//                if (String.class == fieldType) {  
//                    field.set(o, String.valueOf(fieldValue));  
//                } else if ((Integer.TYPE == fieldType)  
//                        || (Integer.class == fieldType)) {  
//                    field.set(o, Integer.parseInt(fieldValue.toString()));  
//                } else if ((Long.TYPE == fieldType)  
//                        || (Long.class == fieldType)) {  
//                    field.set(o, Long.valueOf(fieldValue.toString()));  
//                } else if ((Float.TYPE == fieldType)  
//                        || (Float.class == fieldType)) {  
//                    field.set(o, Float.valueOf(fieldValue.toString()));  
//                } else if ((Short.TYPE == fieldType)  
//                        || (Short.class == fieldType)) {  
//                    field.set(o, Short.valueOf(fieldValue.toString()));  
//                } else if ((Double.TYPE == fieldType)  
//                        || (Double.class == fieldType)) {  
//                    field.set(o, Double.valueOf(fieldValue.toString()));  
//                } else if (Character.TYPE == fieldType) {  
//                    if ((fieldValue!= null) && (fieldValue.toString().length() > 0)) {  
//                        field.set(o, Character  
//                                .valueOf(fieldValue.toString().charAt(0)));  
//                    }  
//                }else if(Date.class==fieldType){
//                    field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fieldValue.toString()));
//                }else{
//                    field.set(o, fieldValue);
//                }
//            }else{
//                throw new ExcelException(o.getClass().getSimpleName() + "類不存在字段名 "+fieldName);
//            }
    }


    /**
     * @MethodName  : setColumnAutoSize
     * @Description : 設置工作表自動列寬和首行加粗
     * @param ws
     */
    private static void setColumnAutoSize(WritableSheet ws,int extraWith){
        //獲取本列的最寬單元格的寬度
        for(int i=0;i<ws.getColumns();i++){
            int colWith=0;
            for(int j=0;j<ws.getRows();j++){
                String content=ws.getCell(i,j).getContents().toString();
                int cellWith=content.length();
                if(colWith<cellWith){
                    colWith=cellWith;
                }
            }
            //設置單元格的寬度爲最寬寬度+額外寬度
            ws.setColumnView(i, colWith+extraWith);
        }

    }

    /**
     * @MethodName  : fillSheet
     * @Description : 向工作表中填充數據
     * @param sheet     工作表 
     * @param list  數據源
     * @param fieldMap 中英文字段對應關係的Map
     * @param firstIndex    開始索引
     * @param lastIndex 結束索引
     */
    private static <T> void fillSheet(
            WritableSheet sheet,
            List<T> list,
            LinkedHashMap<String,String> fieldMap,
            int firstIndex,
            int lastIndex
            )throws Exception{

        //定義存放英文字段名和中文字段名的數組
        String[] enFields=new String[fieldMap.size()];
        String[] cnFields=new String[fieldMap.size()];

        //填充數組
        int count=0;
        for(Entry<String,String> entry:fieldMap.entrySet()){
            enFields[count]=entry.getKey();
            cnFields[count]=entry.getValue();
            count++;
        }
        //填充表頭
        for(int i=0;i<cnFields.length;i++){
            Label label=new Label(i,0,cnFields[i]);
            sheet.addCell(label);
        }

        //填充內容
        int rowNo=1;
        for(int index=firstIndex;index<=lastIndex;index++){
            //獲取單個對象
            T item=list.get(index);
            for(int i=0;i<enFields.length;i++){
                Object objValue=getFieldValueByNameSequence(enFields[i], item);
                String fieldValue=objValue==null ? "" : objValue.toString();
                Label label =new Label(i,rowNo,fieldValue);
                sheet.addCell(label);
            }

            rowNo++;
        }

        //設置自動列寬
        setColumnAutoSize(sheet, 5);
    }
    
    
    
	/**
	 * 導出excel工具類
	 * @param data 字段及中文
	 * @param string 數據
	 * @param response 
	 */
	public static void toExcelUtil(List<Map<String, String>> list,List<ExcelEntity> data1,HttpServletResponse response){
		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String,String>();
		for (int i = 0; i < data1.size(); i++) {//字段及表標題需要放入map中(必須要有實體類包含map中的key,value爲導出表格中列名)
			linkedHashMap.put(data1.get(i).getField(), data1.get(i).getTitle());
		}
		try {
//			linkedHashMap.put("Id", "標識列");//測試數據
//			linkedHashMap.put("UserId", "用戶ID");
			ExcelUtil_cf.listToExcel(list, linkedHashMap, "點位校驗結果", list.size(), response);//50爲一個sheet頁中顯示多少條數據
		} catch (ExcelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	

}

 異常類:

package com.mapuni.survey.util;

public class ExcelException extends Exception {

    public ExcelException() {
        // TODO Auto-generated constructor stub
    }

    public ExcelException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public ExcelException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

    public ExcelException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }


}

Controller層:

	@RequestMapping(value="rightListToExcel", produces = "application/json; charset=utf-8")
	public void expRightList(HttpServletRequest request,HttpServletResponse response,
			PrintWriter pw,String page,String size) {
				Gson gson = new Gson();
		try {
			List<Map<String, String>> selectDataToExcel = this.serviceFactory
					.getSpaceCheckService().selectDataToExcel(
							regionCode, errorCodes, keyWord);//查詢需要導出的結果
			String field = "[{\"field\":\"ENTERPRISE_NAME\",\"title\":\"企業名稱\"},{\"field\":\"CELLCODE\",\"title\":\"行政區劃代碼\"},{\"field\":\"ERROR_CODE\",\"title\":\"點位錯誤代碼\"},{\"field\":\"ERROR_TEXT\",\"title\":\"點位錯誤說明\"},{\"field\":\"LONGITUDE\",\"title\":\"經度\"},{\"field\":\"LATITUDE\",\"title\":\"緯度\"}]";
			Type listType = new TypeToken<LinkedList<ExcelEntity>>(){}.getType(); 
			List<ExcelEntity> lstfield = gson.fromJson(field, listType);//解析json
			ExcelUtil_cf.toExcelUtil(selectDataToExcel, lstfield, response);//第一個參數必須爲List<Map<String, String>>
		} catch (MapuniException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

HTML頁面中按鈕點擊調用:

document.location=encodeURI("../gis/gisToExcel.do?field="+fieldData+"&data="+listData);//url轉碼

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章