JQuery 中 AJAX 如何实现 Excel 文件 下载

102 篇文章 2 订阅
21 篇文章 0 订阅

我们知道,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


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值