Java 匯出Excel的各種嘗試

來源:互聯網
上載者:User

標籤:stat   open   統一   技術分享   tps   form   btn   方式   ;;   

  最近的一個項目比較忙,一直沒時間過來跟新部落格。今天過來分享一下在此項目中遇到的一個小問題:匯出Excel;相信匯出Excel這個功能是特別常見的,也有很多的方式。好了,不多說了,直接說說自己遇到的各種坑,我後台用的是poi匯出。

  首先,說一下需求,想要的結果就是:“符合匯出條件時,正常匯出,並彈出提示框讓使用者選,不符合匯出條件時,提示使用者不能匯出,還要在使用者匯出的同時將匯出按鈕禁用,當匯出成功後,再將匯出按鈕放開“

  (我首先會將我做的全過程的思路和所遇到的問題和解決方案說一下,乾貨會在下面貼出來)

    1、因為我們整個架構習慣用非同步請求,所以一開始我使用ajax非同步請求匯出Excel,結果發現匯出不了,背景程式也跑完了,日誌也記錄了,,就是沒有出現excel,更別說提示框了,網上查了很多,都說是因為ajax和後台交流用的是字元流,瀏覽器是不會識別你讓他下載的,所以此路不通。(也有小夥伴說用ajax同步,也試了,不行。又填上了一個坑。。。。)

  2、然後就準備用form表單submit提交匯出,試了一下,發現可以啊,很高興,但是問題又來了,form表單提交後頁面其實重新整理了,如果不符合匯出條件我該怎麼提示使用者呢?新跳轉一個頁面嗎?感覺這樣不太合適,因為使用者辛辛苦苦輸入了半天的條件,然後等了半天后台校正(涉及到大資料量),結果等來的是跑到另一個頁面跟你說不能匯出,如果是我我會崩潰的,等了半天不說,奶奶個腿,我輸入半天的查詢條件還得重新輸入,這個不能忍。。好吧,這種方法不行,然後試著從後台往jsp頁面寫指令碼,但是也發現根本不執行,也就納悶了,最後,網上有一位小夥伴說用一個iframe的隱藏欄位,如果不合格話,再用流的方式將問題寫回來,最終問題解決了(代碼將會統一貼在下面)。

  3、這樣感覺很完美了,但是問題還沒有完全解決,還有一個禁用按鈕的問題,這個問題想想很簡單,使用者點擊匯出時將按鈕禁用,匯出完成後傳回來一個標誌,然後再將按鈕放開,但是問題來了,這個標誌怎麼穿回來?一開始我想當然的想和錯誤提示一樣的結局方案,發現不行因為,我匯出Excel已經將response流給用掉了,我不可能在用流的方式將標誌寫回來了。這樣就會導致我放不開匯出按鈕,那老闆就不同意了,加班加點的找方法。終於,讓我找到了一個解決思路,用cookie來做。具體思路就是:使用者點擊匯出後,禁用按鈕,然後js寫個定時器輪訓找cookie,在將檔案流寫出後,我會放一個cookie在瀏覽器中,那麼此時js就能找到這個cookie了,找到後,首先將定時器給幹掉,再將cookie給幹掉(有點過河拆橋的感覺,哈哈),然後將匯出按鈕給放開。

  (雖然問題解決了,但是cookie和定時器輪訓還是有一點不靠譜,希望大家有更好的解決方案,請大家不吝賜教,謝謝!!!)

  前台代碼:

<button class="btn btn-sm btn-success" type="submit" id="detailEp" onclick="return exportCheck(true);" forbid="yes"><i class="icon-arrow-right bigger-110"></i> 匯出</button>
<script>$(function() {var timer = "";});//點擊匯出按鈕時禁用匯出按鈕$("#myForm").submit(function() {$("button[type=submit]",this).attr("disabled","disabled");//提交匯出後定時去查看有沒有匯出成功timer = setInterval(refrashPg,1000);})//匯出成功後會放開匯出按鈕的禁用function refrashPg() {if (getCk() =="1") {clearInterval(timer);$("#detailEp").removeAttr("disabled");}delCk();}//js擷取到cookiefunction getCk() {debuggervar ck = document.cookie.split(";"); var ckname = "";for (var i = 0;i<ck.length;i++) {var arr = ck[i].split("=");if (arr[0] =="updtstatus") {ckname = arr[1];break;}}return ckname;}//js刪除掉cookiefunction delCk() {var exp = new Date(); var name = "updtstatus";exp.setTime(exp.getTime()-1000);var cval = getCk();document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();}}
</script>

  後台匯出代碼就是普通的Java POI代碼:

 1 public void buildExcelDocument(Map<String, Object> obj,String fileName,String type,  2              HttpServletRequest request, HttpServletResponse response)   3             throws Exception {   4         HSSFWorkbook workbook = new HSSFWorkbook();   5         if ("1".equals(type)) { 6             List<Map<String, Object>> contentList =  (List<Map<String, Object>>) obj.get("content");   7             HSSFSheet sheet = workbook.createSheet("sheet1");//建立Excel的版本是2003-2007(xls) 如果需要2010的話,用 XSSFSheet    8             Map<String,String>  titleList = (Map<String, String>) obj.get("title"); 9             //表頭的key 對應內容listMap中的map的key10             List<String> mkey = new ArrayList<String>();11             //表頭的value 表頭12             List<String> mvalue = new ArrayList<String>();13             Iterator<Entry<String, String>> it = titleList.entrySet().iterator();14             while(it.hasNext()){15                 @SuppressWarnings("rawtypes")16                 java.util.Map.Entry entry = (java.util.Map.Entry)it.next();17                 mkey.add((String) entry.getKey());18                 mvalue.add((String) entry.getValue());19             }20             sheet.setDefaultColumnWidth((short) 12);    21             HSSFCell cell = null;  22             for (int i = 0;i<mvalue.size();i++) {23                 cell = getCell(sheet, 0, i);24                 setText(cell, mvalue.get(i));25             }26             27             for (short i = 0; i < contentList.size(); i++) {    28                 HSSFRow sheetRow = sheet.createRow(i+1);   29                 Map<String, Object> entity = contentList.get(i);  30                 for (int j = 0;j< mkey.size();j++) {31                         if (entity.get(mkey.get(j)) instanceof String) {32                             sheetRow.createCell(j).setCellValue((String)entity.get(mkey.get(j)));33                         } else if (entity.get(mkey.get(j)) instanceof Double) {34                             sheetRow.createCell(j).setCellValue((Double)entity.get(mkey.get(j)));35                         } else if (entity.get(mkey.get(j)) instanceof Date){36                             String date = (entity.get(mkey.get(j))).toString();37                             sheetRow.createCell(j).setCellValue(date.substring(0, 10));38                         } else if (entity.get(mkey.get(j)) instanceof BigDecimal){39                             sheetRow.createCell(j).setCellValue((entity.get(mkey.get(j))).toString());40                         }41                     }42                 }43             }44         } else if ("2".equals(type)) {45             List<String[]> contentList =  (List<String[]>) obj.get("content");  46             HSSFSheet sheet = workbook.createSheet("sheet1");    47             String[]  titleList = (String[]) obj.get("title");48             HSSFCell cell = null;  49             for (int i = 0;i<titleList.length;i++) {50                 cell = getCell(sheet, 0, i);51                 setText(cell, titleList[i]);52             }53             for (short i = 0; i < contentList.size(); i++) {    54                 HSSFRow sheetRow = sheet.createRow(i+1); 55                 String[] detail = contentList.get(i);56                 for (int j = 0;j< detail.length;j++) {57                     sheetRow.createCell(j).setCellValue((String)contentList.get(i)[j]);58                 }59             }60         }61         62        //設定下載時用戶端Excel的名稱     63         String filename = fileName + ".xls";  64       //處理中文檔案名稱  65         filename = Chineseutil.encodeFilename(filename, request);  66         response.setContentType("application/Vnd.ms-excel;charset=UTF-8");     67         response.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("gb2312"), "iso8859-1"));     68         OutputStream ouputStream = response.getOutputStream();69         workbook.write(ouputStream);     70         71         //匯出資料後將資訊存入cookie72      Cookie status = new Cookie("updtstatus", "1");73       status.setMaxAge(3600);//設定cookie存活時間1個小時74       response.addCookie(status);75         76         ouputStream.flush();     77         ouputStream.close();  78     }
View Code

 

Java 匯出Excel的各種嘗試

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.