SSM POI Excel匯出 封裝類拿走直接用
新手上路,經過查詢其他部落格的poi匯出,自己寫了一個限制條件特別多的封裝類,同時又特別實用,希望能幫助大家。
- 如果使用的不是SSM框架,簡單更改程式碼即可,工具類無需改變。
我使用的框架是maven搭建的SSM框架
匯入poi依賴,這裡使用的是老版本穩定的poi依賴。
最新穩定版本是4.0
下載jar包可以去官網下載
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.6</version> </dependency>
為什麼要說我寫的這個封裝類是個限制條件特別多的封裝類呢?
首先,Mybaits配置檔案查詢返回值必須是LinkedHashMap型別,無需使用任何實體類。
將在最後講述為什麼使用LinkedHashMap型別
Mybatis配置檔案:
DAO層,service層
方法返回值均為List<map<String,Object>> 型別
控制器程式碼:
控制器程式碼比較簡單,只需要將response和list傳入進工具類即可。
@Controller public class XController { @Resource private XService xserivce; @RequestMapping("/findAll") public String findAll(HttpServletRequest request,HttpServletResponse response) { List<Map<String,Object>> list = xserivce.findAll(); HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(response,list); return "index"; } }
excel匯出工具類:
public class ExcelUtil { /** * * @author [email protected] * @param response * @param list * @return HSSFWorkbook */ public static HSSFWorkbook getHSSFWorkbook(HttpServletResponse response, List<Map<String, Object>> list) { // 生成檔名稱 String fileName = System.currentTimeMillis() + RandomUtils.nextInt(100000) + ".xls"; // 獲取標題內容 Set<String> set = new LinkedHashSet<String>(); Set<String> sets = new LinkedHashSet<String>(); for (int i = 0; i < list.size(); i++) { set = list.get(i).keySet(); for (String value : set) { sets.add(value); } } for (int i = 0; i < list.size(); i++) { for (String s : sets) { if (list.get(i).get(s) == null || list.get(i).get(s) == "") { list.get(i).put(s, ""); } } } // 建立標題長度 String title[] = new String[sets.size()]; // 標題內容賦值(賦值,未建立標題) int titleSize = 0; for (String s : sets) { title[titleSize++] = s; } // 第一步,建立一個HSSFWorkbook,對應一個Excel檔案 HSSFWorkbook wb = new HSSFWorkbook(); // 第二步,在workbook中新增一個sheet,對應Excel檔案中的sheet HSSFSheet sheet = wb.createSheet("sheet"); // 第三步,在sheet中新增表頭第0行,注意老版本poi對Excel的行數列數有限制 HSSFRow row = sheet.createRow(0); // 第四步,建立單元格,並設定值表頭 設定表頭居中 HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 建立一個居中格式 // 宣告列物件 HSSFCell cell = null; // 建立標題 for (int i = 0; i < title.length; i++) { cell = row.createCell(i); cell.setCellValue(title[i]); cell.setCellStyle(style); } // 建立內容 for (int i = 0; i < list.size(); i++) { row = sheet.createRow(i + 1); int j = 0; for (String s : sets) { row.createCell(j++).setCellValue(list.get(i).get(s).toString()); } } try { setResponseHeader(response, fileName); OutputStream os = response.getOutputStream(); wb.write(os); os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } return wb; } public static void setResponseHeader(HttpServletResponse response, String fileName) { try { try { fileName = new String(fileName.getBytes(), "ISO8859-1"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } response.setContentType("application/octet-stream;charset=ISO8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); response.addHeader("Pargam", "no-cache"); response.addHeader("Cache-Control", "no-cache"); } catch (Exception ex) { ex.printStackTrace(); } } }
最後要在最後跳轉的JSP頁面新增上
<%
out.clear();
out = pageContext.pushBody();
%>
否則會出現如下錯誤:
報錯原因:
產生這樣的異常原因:是web容器生成的servlet程式碼中有out.write(""),
這個和JSP中呼叫的response.getOutputStream()產生衝突.即Servlet規範說明,
不能既呼叫response.getOutputStream(),又呼叫response.getWriter(),
無論先呼叫哪一個,在呼叫第二個時候應會丟擲IllegalStateException,因為在jsp中,
out變數實際上是通過response.getWriter得到的,你的程式中既用了response.getOutputStream,又用了out變數,故出現以上錯誤。
作者:安_shuai
來源:CSDN
原文:https://blog.csdn.net/xyajia/article/details/78730751
版權宣告:本文為博主原創文章,轉載請附上博文連結!
這裡引用其他博主文章,不再進行多餘解釋
最後講述一下為什麼要使用sql返回值為什麼使用LinkedHashMap,LinkedHashMap的Key和Value都允許空,LinkedHashMap會按從資料庫查詢時的順序進行儲存,這樣查詢到的資料就不會順序顛倒。HashMap會導致我們excel表內的內容亂套,比如三個欄位id,name,pass。其中一條資料id值為1,name值為“小明”,pass值為123456,那麼excel表內就會出現這樣的情況
name | id | pass |
---|---|---|
小明 | 1 | 123456 |
使用LinkedHashMap就不會出現這種情況,我還嘗試過TreeMap,效果同樣不理想。
哪裡有不足希望大家多多提一下意見,我會努力完善的。