項目中自用的導出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轉碼