JQuery 中 AJAX 如何實現 Excel 檔案 下載
阿新 • • 發佈:2019-01-26
我們知道,JQuery的ajax函式的返回型別只有xml、text、json、html等型別,沒有“流”型別,所以我們要實現ajax下載,不能夠使用相應的ajax函式進行檔案下載。但在js中 生成一個form,用這個form提交引數,並返回“流”型別的資料。在實現過程中,頁面也沒有進行重新整理。
注意,如果伺服器端是Spring MVC,則該server端必須支援 post方法且 content type 是 "application/x-www-form-urlencoded"
下面的例子均已除錯通過。
前端JS頁面例子:
mp.jsp
manipulationHistory.downloadData = function() { //定義一個form表單 var myform = $("<form></form>"); myform.attr('method','post') myform.attr('action',"/manipulationHistory/exportManipulationInfo"); var myProductId = $("<input type='hidden' name='productId' />") myProductId.attr('value',$("#query-param-product-id").val()); var myPurchaseOrderId = $("<input type='hidden' name='purchaseOrderId' />") myPurchaseOrderId.attr('value',$("#query-param-dispatched-po").val()); var myWarehouseId = $("<input type='hidden' name='warehouseId' />") myWarehouseId.attr('value', $("#query-param-warehouse-id").val()); var myRelatedOrderId = $("<input type='hidden' name='relatedOrderId' />") myRelatedOrderId.attr('value', $("#query-param-order-id").val()); var myUpdateReason = $("<input type='hidden' name='updateReason' />") myUpdateReason.attr('value', $("#query-param-update-reason").val()); var myStartTime = $("<input type='hidden' name='startTime' />") myStartTime.attr('value', $("#operate-time-start-value").val()); var myEndTime = $("<input type='hidden' name='endTime' />") myEndTime.attr('value', $("#operate-time-end-value").val()); myform.append(myProductId); myform.append(myPurchaseOrderId); myform.append(myWarehouseId); myform.append(myRelatedOrderId); myform.append(myUpdateReason); myform.append(myStartTime); myform.append(myEndTime); myform.appendTo('body').submit(); //must add this line for higher html spec };
後臺server端的java程式碼如下(用SPring MVC來支援)
/* * Ajax not support stream response message, so front page need to use form * to submit request with APPLICATION_FORM_URLENCODED */ @Consumes({ MediaType.APPLICATION_FORM_URLENCODED }) @RequestMapping(value = "/exportManipulationInfo", method = RequestMethod.POST) @ResponseBody public boolean exportManipulationInfo(HttpServletRequest request, HttpServletResponse response) { ManipulationInfoQuery manipulationInfoQuery = generateMHQuery(request); LOG.info("[IMS_INFO][exportManipulationInfo] received request: " + JsonHelper.toJson(manipulationInfoQuery)); List<ManipulationInfo> resultList = manipulationHistoryPageService.getManipulationInfoListWithoutPage(manipulationInfoQuery); if (null == resultList || resultList.isEmpty()) { LOG.info(" no data retrieved for query: " + JsonHelper.toJson(manipulationInfoQuery)); } return downLoadsExcel(resultList, response); } private ManipulationInfoQuery generateMHQuery(HttpServletRequest request) { ManipulationInfoQuery resultQuery = new ManipulationInfoQuery(); resultQuery.setProductId(request.getParameter("productId")); resultQuery.setPurchaseOrderId(request.getParameter("purchaseOrderId")); String warehouseID = request.getParameter("warehouseId"); if (StringUtils.isNotBlank(warehouseID)) { resultQuery.setWarehouseId(Integer.parseInt(warehouseID)); } else { resultQuery.setWarehouseId(null); } resultQuery.setRelatedOrderId(request.getParameter("relatedOrderId")); resultQuery.setUpdateReason(request.getParameter("updateReason")); resultQuery.setStartTime(request.getParameter("startTime")); resultQuery.setEndTime(request.getParameter("endTime")); resultQuery.setPageInd(null); resultQuery.setPageSize(null); return resultQuery; } private boolean downLoadsExcel(List<ManipulationInfo> dataList, HttpServletResponse response) { FileOutputStream fos = null; try { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("ManipulationInfo_details"); sheet.setDefaultColumnWidth(40); HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_LEFT); String fileName = "ManipulationInfoData-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls"; fos = new FileOutputStream(fileName); // column name String[] label = { "index", "productId", "productName", "warehouseId", "warehouseName", "dispatchedPo", "relatedOrderId", "updateField", "action", "result", "updateReason", "operator", "operateTime" }; int columnNum = label.length; // set title column at line 0 HSSFRow titleRow = sheet.createRow((int) 0); // the most left column is index of column HSSFCell titleCell = null; for (int n = 0; n < columnNum; n++) { titleCell = titleRow.createCell(n); titleCell.setCellType(HSSFCell.CELL_TYPE_STRING); titleCell.setCellValue(label[n]); titleCell.setCellStyle(style); } if (null != dataList && !dataList.isEmpty()) { for (int rowIndex = 0; rowIndex < dataList.size(); rowIndex++) { ManipulationInfo item = dataList.get(rowIndex); /* * the line 0 is title line,so actual data line begins from * the next one line. */ HSSFRow row = sheet.createRow(rowIndex + 1); String rowData[] = { item.getProductId(), item.getProductName(), item.getWarehouseId().toString(), item.getWarehouseName(), item.getDispatchedPo(), item.getRelatedOrderId(), item.getUpdateField(), item.getAction(), item.getResult().toString(), item.getUpdateReason(), item.getOperator(), item.getOperateTime() }; // create the most left column as index column HSSFCell cell = row.createCell(0, HSSFCell.CELL_TYPE_NUMERIC); cell.setCellValue(rowIndex + 1); cell.setCellStyle(style); // create the remaining cells at the same line for (int columnIndex = 1; columnIndex < columnNum; columnIndex++) { cell = row.createCell(columnIndex, HSSFCell.CELL_TYPE_STRING); cell.setCellValue(rowData[columnIndex - 1]); cell.setCellStyle(style); } } } else { LOG.info(" no data retrieved"); } // set all columns to automatically adjust column width for (int i = 0; i < columnNum; i++) { sheet.autoSizeColumn(i); } wb.write(fos); // write workbook into file .xls fos.flush(); // flush buffer to file fos.close(); // remember to close it if (wb != null) { response.reset(); response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-Disposition", "filename=" + new String(fileName.getBytes(), "iso-8859-1")); OutputStream out = response.getOutputStream(); wb.write(out); out.flush(); out.close(); } } catch (Exception e) { LOG.error( downLoadsExcel exception:" + e); return false; } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { LOG.error(" close FileOutputStream error:" + e); return false; } } } return true; }
在上面的JAVA後端程式碼中,注意沒有@RequestBody來修飾傳入引數,這是因為如下說明:
關於@ResponseBody,@RequestBody,@PathVariable比較通俗的解釋就是: @PathVariable主要是用來處理URl路徑的問題,利用@PathVariable可以是實現在URL路徑中實現引數的隱藏效果。@RequestBody主要是用來處理請求型別轉換問題,例如可以把json字串通過配置自動轉換為物件之類的。
@ResponseBody主要是用來處理返回型別轉換問題,例如可以把json字串通過配置自動轉換為物件之類的。
一般@ResponseBody,@RequestBody都是用來處理json和xml資料型別,不能用於傳統的html解析,因為@ResponseBody,@RequestBody都只是獲取內容而已,並不是整個html,所以在有用到json或者xml資料型別傳輸的時候才可以考慮使用@ResponseBody,@RequestBody這兩個註解,否則不要使用。
一個不錯的連線是:
http://blog.csdn.net/linzhiqiang0316/article/details/52328153