須要導出excel,沒有想到springMVC已經將poi匹配進來,表示贊前端
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>xxx</version> </dependency>
在org.springframework.web.servlet.view.document包下有不少的類,我這裏考慮到兼容因此繼承AbstractXlsViewjava
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; 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.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.tools.ant.util.DateUtils; import org.springframework.web.servlet.view.document.AbstractXlsView; public class ExportExcelView extends AbstractXlsView { /** * 填充的數據 */ public static String DATA_LIST = "dataList"; /** * 標題頭,定義的內容爲LinkedHashMap<String, String><br> * 示例:LinkedHashMap<"name", "名字"> */ public static String TITLE_MAP = "titleMap"; @Override protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { response.setHeader("content-disposition", "attachment;filename=export.xls"); @SuppressWarnings("rawtypes") List datas = (List) model.get(DATA_LIST); // 獲取頭 @SuppressWarnings("unchecked") LinkedHashMap<String, String> titles = (LinkedHashMap<String, String>) model.get(TITLE_MAP); // 建立一個工做表sheet Sheet sheet = workbook.createSheet("導出數據"); if (null == datas || datas.isEmpty()) { // 空數據 if (null != titles && !titles.isEmpty()) { // 有標題 this.writeTitle(sheet, titles); } return; } if (null == titles || titles.isEmpty()) { titles = this.getTitle(datas.get(0)); } this.writeTitle(sheet, titles); this.writeDataList(sheet, titles, datas); } /** * 寫title */ private void writeTitle(Sheet sheet, LinkedHashMap<String, String> titles) { Row row = sheet.createRow(0); Cell cell = null; int i = 0; for (Entry<String, String> entry : titles.entrySet()) { cell = row.createCell(i); cell.setCellValue(entry.getValue()); i++; } } /** * 寫dataList */ private void writeDataList(Sheet sheet, LinkedHashMap<String, String> titles, @SuppressWarnings("rawtypes") List Datas) { Row row; Class<? extends Object> class1; Cell cell; Method method; int i = 1; for (Object object : Datas) { class1 = object.getClass(); row = sheet.createRow(i++); int y = 0; for (Entry<String, String> entry : titles.entrySet()) { cell = row.createCell(y++); // 反射獲取其值 try { method = class1.getDeclaredMethod("get" + toUpperCase4Index(entry.getKey())); Object invoke = method.invoke(object); cell.setCellValue(formatValue(invoke)); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // e.printStackTrace(); } } } } /** * 格式化數據值 * * @param invoke * @return */ private String formatValue(Object invoke) { if (invoke instanceof Date) { Date new_name = (Date) invoke; return DateUtils.format(new_name, "yyyy-MM-dd HH:mm:ss"); } return invoke + ""; } /** * 獲取屬性名稱爲標題 * * @param object * @return */ private LinkedHashMap<String, String> getTitle(Object object) { LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>(); Class<? extends Object> class1 = object.getClass(); Field[] declaredFields = class1.getDeclaredFields(); @SuppressWarnings("unused") Method method; for (Field field : declaredFields) { String fieldName = field.getName(); try { method = class1.getDeclaredMethod("get" + toUpperCase4Index(fieldName)); // 若是不存在公開的get方法,則不加入標題 linkedHashMap.put(fieldName, fieldName); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block // e.printStackTrace(); } } return linkedHashMap; } /** * 首字母大寫 * * @param string * @return */ private String toUpperCase4Index(String string) { char[] methodName = string.toCharArray(); methodName[0] = toUpperCase(methodName[0]); return String.valueOf(methodName); } /** * 字符轉成大寫 * * @param chars * @return */ private char toUpperCase(char chars) { if (97 <= chars && chars <= 122) { chars ^= 32; } return chars; } }
在springMVC的方法中返回ModelAndViewweb
ModelAndView ret = new ModelAndView(); ret.setView(new ExportExcelView()); ret.getModel().put(ExportExcelView.DATA_LIST, blogList); return ret;
我在ExportExcelView 中使用了反射,斷言,只導出public的屬性,title能夠配合前端指定須要導出的屬性,比較適合大部分場景。後期想加入導出查詢的條件,再就是使用註解相似@requestBody這樣子的,若是你有想法和建議,但願你願意和我分享spring