一、導入依賴
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency>
二、編寫工具類
package cn.pms.util; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map.Entry; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 導出Excel * @author Guang * */ public class ExportExcelUtils { private static final Logger logger =LoggerFactory.getLogger(ExportExcelUtils.class); /** * 導出Excel * @param excelName 要導出的excel名稱 * @param list 要導出的數據集合 * @param fieldMap 中英文字段對應Map,即要導出的excel表頭 * @param response 使用response可以導出到瀏覽器 * @return */ public static <T> void export(String excelName,List<T> list,LinkedHashMap<String, String> fieldMap,HttpServletResponse response){ // 設置默認文件名為當前時間:年月日時分秒 if (excelName==null || excelName=="") { excelName = new SimpleDateFormat("yyyyMMddhhmmss").format( new Date()).toString(); } // 設置response頭信息 response.reset(); response.setContentType("application/vnd.ms-excel"); // 改成輸出excel文件 try { response.setHeader("Content-disposition", "attachment; filename=" +new String(excelName.getBytes("gb2312"), "ISO-8859-1") + ".xls"); } catch (UnsupportedEncodingException e1) { logger.info(e1.getMessage()); } try { //創建一個WorkBook,對應一個Excel文件 HSSFWorkbook wb=new HSSFWorkbook(); //在Workbook中,創建一個sheet,對應Excel中的工作薄(sheet) HSSFSheet sheet=wb.createSheet(excelName); //創建單元格,並設置值表頭 設置表頭居中 HSSFCellStyle style=wb.createCellStyle(); //創建一個居中格式 style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 填充工作表 fillSheet(sheet,list,fieldMap,style); //將文件輸出 OutputStream ouputStream = response.getOutputStream(); wb.write(ouputStream); ouputStream.flush(); ouputStream.close(); } catch (Exception e) { logger.info("導出Excel失敗!"); logger.error(e.getMessage()); } } /** * 根據字段名獲取字段對象 * * @param fieldName * 字段名 * @param clazz * 包含該字段的類 * @return 字段 */ public static Field getFieldByName(String fieldName, Class<?> clazz) { logger.info("根據字段名獲取字段對象:getFieldByName()"); // 拿到本類的所有字段 Field[] selfFields = clazz.getDeclaredFields(); // 如果本類中存在該字段,則返回 for (Field field : selfFields) { //如果本類中存在該字段,則返回 if (field.getName().equals(fieldName)) { return field; } } // 否則,查看父類中是否存在此字段,如果有則返回 Class<?> superClazz = clazz.getSuperclass(); if (superClazz != null && superClazz != Object.class) { //遞歸 return getFieldByName(fieldName, superClazz); } // 如果本類和父類都沒有,則返回空 return null; } /** * 根據字段名獲取字段值 * * @param fieldName 字段名 * @param o 對象 * @return 字段值 * @throws Exception 異常 * */ public static Object getFieldValueByName(String fieldName, Object o) throws Exception { logger.info("根據字段名獲取字段值:getFieldValueByName()"); Object value = null; //根據字段名得到字段對象 Field field = getFieldByName(fieldName, o.getClass()); //如果該字段存在,則取出該字段的值 if (field != null) { field.setAccessible(true);//類中的成員變量為private,在類外邊使用屬性值,故必須進行此操作 value = field.get(o);//獲取當前對象中當前Field的value } else { throw new Exception(o.getClass().getSimpleName() + "類不存在字段名 " + fieldName); } return value; } /** * 根據帶路徑或不帶路徑的屬性名獲取屬性值,即接受簡單屬性名, * 如userName等,又接受帶路徑的屬性名,如student.department.name等 * * @param fieldNameSequence 帶路徑的屬性名或簡單屬性名 * @param o 對象 * @return 屬性值 * @throws Exception 異常 * */ public static Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception { logger.info("根據帶路徑或不帶路徑的屬性名獲取屬性值,即接受簡單屬性名:getFieldValueByNameSequence()"); Object value = null; // 將fieldNameSequence進行拆分 String[] attributes = fieldNameSequence.split("\\."); if (attributes.length == 1) { value = getFieldValueByName(fieldNameSequence, o); } else { // 根據數組中第一個連接屬性名獲取連接屬性對象,如student.department.name Object fieldObj = getFieldValueByName(attributes[0], o); //截取除第一個屬性名之后的路徑 String subFieldNameSequence = fieldNameSequence .substring(fieldNameSequence.indexOf(".") + 1); //遞歸得到最終的屬性對象的值 value = getFieldValueByNameSequence(subFieldNameSequence, fieldObj); } return value; } /** * 向工作表中填充數據 * * @param sheet * excel的工作表名稱 * @param list * 數據源 * @param fieldMap * 中英文字段對應關系的Map * @param style * 表格中的格式 * @throws Exception * 異常 * */ public static <T> void fillSheet(HSSFSheet sheet, List<T> list, LinkedHashMap<String, String> fieldMap,HSSFCellStyle style) throws Exception { logger.info("向工作表中填充數據:fillSheet()"); // 定義存放英文字段名和中文字段名的數組 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++; } //在sheet中添加表頭第0行,注意老版本poi對Excel的行數列數有限制short HSSFRow row=sheet.createRow((int)0); // 填充表頭 for (int i = 0; i < cnFields.length; i++) { HSSFCell cell=row.createCell(i); cell.setCellValue(cnFields[i]); cell.setCellStyle(style); sheet.autoSizeColumn(i); } // 填充內容 for (int index = 0; index < list.size(); index++) { row = sheet.createRow(index + 1); // 獲取單個對象 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(); row.createCell(i).setCellValue(fieldValue); } } } }
三、編寫Controller
package cn.pms.controller; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import com.alibaba.fastjson.JSON; import com.wordnik.swagger.annotations.Api; import com.wordnik.swagger.annotations.ApiOperation; import cn.pms.model.User; import cn.pms.service.UserService; import cn.pms.util.ExcelImportUtil; import cn.pms.util.ExportExcelUtils; /** * 用戶Controller * * @author eluzhu * */ @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/excel/exportBankCheckInfo", method = RequestMethod.GET) public void ExportBankCheckInfo(HttpServletRequest request, HttpServletResponse response) { //得到所要導出的數據 List<User> errLst = userService.selectAllUser(); //定義導出excel的名字 String excelName="用戶表"; // 獲取需要轉出的excle表頭的map字段 LinkedHashMap<String, String> fieldMap =new LinkedHashMap<String, String>() ; fieldMap.put("userNo", "編號"); fieldMap.put("userName", "姓名"); fieldMap.put("password", "密碼"); //導出用戶相關信息 new ExportExcelUtils().export(excelName, errLst, fieldMap, response); } }
四、瀏覽器輸入對應的URL進行測試(成功的標識如下)
控制台打印和瀏覽器顯示