须要导出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