獲取jqGrid中的全部數據導出並生成Excel文件流供用戶下載(post請求實現文件下載)

最近有一個需求是:javascript

將jqGrid表格中的數據生成報表Excel文件返回給用戶。css

個人想法是獲取jqGrid中的數據而後生成json數據,傳給後端,生成文件流,響應到前端,保存爲excel文件。html

ajax爲何不可以實現下載文件

ajax的返回值類型是json,text,html,xml類型,或者能夠說ajax的接收類型只能是string字符串,不是流類型,因此沒法實現文件下載。前端

但用ajax仍然能夠得到文件的內容,該文件將被保留在內存中,沒法將文件保存到磁盤。這是由於JavaScript沒法和磁盤進行交互,不然這會是一個嚴重的安全問題,js沒法調用到瀏覽器的下載處理機制和程序,會被瀏覽器阻塞。html5

而且 我用ajax實現的時候出現了不少bug。java

在網上參考好多博客,通過不斷的調試,我仍是選擇了原生的XMLHttpRequest對象進行post請求。web

blob(HTML5 新特性)

二進制大對象,是一個能夠存儲二進制文件的容器。ajax

做用

Js一直以來都沒有比較好的能夠直接處理二進制的方法。而Blob的存在,容許咱們能夠經過JS直接操做二進制數據。chrome

Blob對象能夠看作是存放二進制數據的容器,此外還能夠經過Blob設置二進制數據的MIME類型。數據庫

BLOB是一個大文件,典型的BLOB是一張圖片或一個聲音文件,因爲它們的尺寸,必須使用特殊的方式來處理(例如:上傳、下載或者存放到一個數據庫)。

重點應用
  • 目前作的經過URL下載文件。
  • 分片上傳文件(將大文件分片,輪詢向後臺提交各文件片斷)。

後端代碼

/** * 生成Excel報表 * Error:存在問題 * 1. 前端表格中沒有Student對象的一些屬性,生成報表時沒必要要顯示的屬性字段在Excel中顯示。 * solve:加判斷控制。 * 2. (因爲blob是HTML5新出的)兼容性問題:chrome、firefox、opera無問題, * 3. 檢測grid表格中有無字段名稱衝突問題。 * solve:細心檢查便可 * 4. 下載完Excel,打開出現"文件已損壞 沒法打開"問題,這是由於office受保護試圖致使(安全問題) * solve:在office選項裏邊修改一下便可(客戶端問題) * @param list * @param response */ @RequestMapping(value = "/exstudent",consumes = "application/json;charset=utf-8") public void export (@RequestBody List<Student> list, HttpServletResponse response){ OutputStream out = null; String name = "學生信息管理表"; for (Student stu:list) { System.out.println(stu.getStudentname()); } try { response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(name, "UTF-8")+".xlsx"); out = response.getOutputStream(); //調用老師本身寫的庫,本篇文章不詳細說生成Excel文件的事情。 TExcel.exportExcel(name,Student.class,list,out); System.out.println("下載ok"); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); }finally{ } } /** * 生成Excel報表 * Error:存在問題 * 1. 前端表格中沒有Student對象的一些屬性,生成報表時沒必要要顯示的屬性字段在Excel中顯示。 * solve:加判斷控制。 * 2. (因爲blob是HTML5新出的)兼容性問題:chrome、firefox、opera無問題, * 3. 檢測grid表格中有無字段名稱衝突問題。 * solve:細心檢查便可 * 4. 下載完Excel,打開出現"文件已損壞 沒法打開"問題,這是由於office受保護試圖致使(安全問題) * solve:在office選項裏邊修改一下便可(客戶端問題) * @param list * @param response */ @RequestMapping(value = "/exstudent",consumes = "application/json;charset=utf-8") public void export (@RequestBody List<Student> list, HttpServletResponse response){ OutputStream out = null; String name = "學生信息管理表"; for (Student stu:list) { System.out.println(stu.getStudentname()); } try { response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(name, "UTF-8")+".xlsx"); out = response.getOutputStream(); //調用老師本身寫的庫,本篇文章不詳細說生成Excel文件的事情。 TExcel.exportExcel(name,Student.class,list,out); System.out.println("下載ok"); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); }finally{ } }

前端代碼:

//導出按鈕被點擊以後,將按鈕製爲無效(防止屢次生成) function abideBtn(){ console.log("禁止按鈕......"); $("#download").attr({"href":"#"}); $("#download").css("cursor","not-allowed"); } //下載過程當中出錯誤, function downloadError(){ console.log("發生錯誤,下載失敗"); alert("下載中出現錯誤!請重試"); $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } //導出表格數據 //注意:下面獲取jqGrid中全部行數據的前提是分頁在前端,而不是後端。 //若是你是在後端分頁,那麼你會發現,你會將全部數據都顯示出來。 function exportData() { var grid = jQuery("#grid"); //獲取當前顯示的數據 var rowNum = grid.jqGrid('getGridParam', 'rowNum'); //獲取顯示配置記錄數量 var total = grid.jqGrid('getGridParam', 'records'); //獲取查詢獲得的總記錄數量 //設置rowNum爲總記錄數量而且刷新jqGrid,使全部記錄現出來調用getRowData方法才能獲取到全部數據 grid.jqGrid('setGridParam',{rowNum: total,}).trigger('reloadGrid'); var rows = o.jqGrid('getRowData'); grid.jqGrid('setGridParam',{rowNum: rowNum,}).trigger('reloadGrid'); postToPOM(rows); } //發送post請求 function postToPOM(rows) { console.log(rows); var url = "../student/exstudent"; var xhr = new XMLHttpRequest(); xhr.open('POST',url,true); xhr.responseType = "blob"; xhr.setRequestHeader("Content-Type" , "application/json;charset=utf-8"); //添加監聽事件。 xhr.addEventListener("load",abideBtn,false); xhr.addEventListener("error",downloadError,false); xhr.onload = function (){ if(this.status === 200){ //建立Bolb對象 var blob = this.response;//html5新出的 var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function(e){ //建立a標籤,構造下載彈窗 var a = document.createElement("a"); a.id = "downloadTag"; a.download = '學生信息管理表.xlsx'; a.href = e.target.result; $("body").append(a); a.click(); $("#downloadTag").remove(); console.log("下載完成!"); //恢復按鈕 $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } } }; xhr.send(JSON.stringify(rows)); } //導出按鈕被點擊以後,將按鈕製爲無效(防止屢次生成) function abideBtn(){ console.log("禁止按鈕......"); $("#download").attr({"href":"#"}); $("#download").css("cursor","not-allowed"); } //下載過程當中出錯誤, function downloadError(){ console.log("發生錯誤,下載失敗"); alert("下載中出現錯誤!請重試"); $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } //導出表格數據 //注意:下面獲取jqGrid中全部行數據的前提是分頁在前端,而不是後端。 //若是你是在後端分頁,那麼你會發現,你會將全部數據都顯示出來。 function exportData() { var grid = jQuery("#grid"); //獲取當前顯示的數據 var rowNum = grid.jqGrid('getGridParam', 'rowNum'); //獲取顯示配置記錄數量 var total = grid.jqGrid('getGridParam', 'records'); //獲取查詢獲得的總記錄數量 //設置rowNum爲總記錄數量而且刷新jqGrid,使全部記錄現出來調用getRowData方法才能獲取到全部數據 grid.jqGrid('setGridParam',{rowNum: total,}).trigger('reloadGrid'); var rows = o.jqGrid('getRowData'); grid.jqGrid('setGridParam',{rowNum: rowNum,}).trigger('reloadGrid'); postToPOM(rows); } //發送post請求 function postToPOM(rows) { console.log(rows); var url = "../student/exstudent"; var xhr = new XMLHttpRequest(); xhr.open('POST',url,true); xhr.responseType = "blob"; xhr.setRequestHeader("Content-Type" , "application/json;charset=utf-8"); //添加監聽事件。 xhr.addEventListener("load",abideBtn,false); xhr.addEventListener("error",downloadError,false); xhr.onload = function (){ if(this.status === 200){ //建立Bolb對象 var blob = this.response;//html5新出的 var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function(e){ //建立a標籤,構造下載彈窗 var a = document.createElement("a"); a.id = "downloadTag"; a.download = '學生信息管理表.xlsx'; a.href = e.target.result; $("body").append(a); a.click(); $("#downloadTag").remove(); console.log("下載完成!"); //恢復按鈕 $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } } }; xhr.send(JSON.stringify(rows)); }
相關文章
相關標籤/搜索