ajax发送请求下载字节流形式的excel文件

原文链接:ajax发送请求下载字节流形式的excel文件

解决办法

原生开发

当原生开发的时候,就要依靠操作XMLHttpRequest对象来获取响应的二进制流。经过百度我发现虽然这个对象没有提供直接获取流的属性,但是它的文档中responseType是可以返回一个Blob对象的。而Blob对象就是一个二进制数据的对象,只要我们获取到这个对象,就可以通过浏览器获取到需要的excel文件。

代码:

$('.exportBtn').bind("click", function () {
    var method = 'post';//请求方法
    var url = 'http://localhost.....';//请求url
    var xhr = new XMLHttpRequest();//定义一个XMLHttpRequest对象
    xhr.open(method, url, true);
    xhr.responseType = 'blob';//设置ajax的响应类型为blob
    xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8');
    xhr.onload = function ()//当请求完成,响应就绪进入
    {
        if (this.status == 200)//当响应状态码为200时进入
        {
            var blob = this.response;//获取响应返回的blob对象
            //这一段用来判断是否是IE浏览器,因为下面有些代码不支持IE
            if (typeof window.navigator.msSaveBlob !== 'undefined') {
                window.navigator.msSaveBlob(blob, "NPI_PROJECT.xlsx");
                return;
            }
            var a = document.createElement('a');//在dom树上创建一个a标签
            var url = window.URL.createObjectURL(blob);//我的理解是生成一个相对于浏览器的虚拟url,用于指向传入的blob对象,让浏览器可以通过这个url找到这个blob对象
            a.href = url;//将url赋值给a标签的href属性
            a.download = 'NPI_PROJECT.xlsx';//设置设置下载文件的名称
            a.click();//主动触发a标签点击事件
        }
    };
    xhr.send(JSON.stringify({
        name: '',
        status: ''
    }));//附带参数发送请求
});

jquery插件开发 -->jquery.fileDownload  githiub地址

$('.exportBtn').bind("click", function () {
    var httpMethod = 'post';
    var url = "http://localhost.....";
    var params = {
        name: '',
        status: ''
    };
    $.fileDownload(url, {
        httpMethod: httpMethod,
        // 因为这个插件貌似只支持URL参数,所以要用jquery param将js对象转成URL参数
        data: $.param(params),
        prepareCallback: function (url) {
            console.log("正在导出...");
        },
        //要想成功回调失败和成功方法,要在响应首部加 response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        successCallback: function (url) {
            console.log("导出成功");
        },
        failCallback: function (html, url) {
            console.log("导出失败");
        }
    })

后台代码:

action:

public void exportExcel(){
        String tankfarmIdStr = null;
        if(tankfarmId > 0){
            tankfarmIdStr = Long.toString(tankfarmId);
        }else{
            IDMmOrderMap orderMap = (IDMmOrderMap) ResourceFactory.getInstance().getBeanFromContext("dMmOrderMap");
            tankfarmIdStr = orderMap.getTankfarmIds(this.getLoginUser());
        }
        IMmExcelRptMap rptMap = (IMmExcelRptMap) ResourceFactory.getInstance().getMapFromContext("mmExcelRptMap");
        byte[] content = rptMap.exportVDImBalance(matlId, startDate, endDate, tankfarmIdStr);
        OutputStream os = null;
        try {
            os = this.getServletResponse().getOutputStream();
            this.getServletResponse().setContentType("application/vnd.ms-excel");
            this.getServletResponse().setHeader("Content-disposition", "attachment; filename=" + "balance_monthly.xls");
            os.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
            } catch (IOException e) {
                
                e.printStackTrace();
            }
        }
    }

map:

public byte[] exportVDImBalance(Long matlId, String startDate, String endDate, String tankfarmIdStr) {
        IDImBalanceMap map = (IDImBalanceMap) ResourceFactory.getInstance().getMapFromContext("dImBalanceMap");
        List<Map<String, Object>> datas = map.findVBalanByMatlAndTime(matlId, startDate, endDate, null, tankfarmIdStr); //获取数据
        IJExcelReportMap rptMap = new JExcelReportMap();
        byte[] content = rptMap.exportReport(new File(this.getFilePath(IM_BALANCE_MONTHLY)), datas, null);
        return content;
    }
public byte[] exportReport(File template, Collection datas, Map params) {
        byte[] content = null;
        
        if (template != null && template.exists())
        {
            Workbook wb = null;
            WritableWorkbook wwb = null;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                try {
                    wb = Workbook.getWorkbook(template);
                    WorkbookSettings settings = new WorkbookSettings ();
                    settings.setWriteAccess(null);
                    
                    wwb = Workbook.createWorkbook(bos, wb);
                    WritableSheet[] sheets = wwb.getSheets();
                    for (int i = 0; i < sheets.length; i ++){
                        this.fillSheet(sheets[i], datas, params);
                    }
                    wwb.write();
                } catch (Exception e) {
                    throw new InteriorException("", e);
                } finally {
                    try {
                        wwb.close();
                    } catch (WriteException e) {
                        
                        e.printStackTrace();
                    } catch (IOException e) {
                        
                        e.printStackTrace();
                    }
                    wb.close();
                } 
                content = bos.toByteArray();
            }finally {
                try {
                    bos.close();
                } catch (IOException e) {
                    
                    e.printStackTrace();
                }
            }
        }
        
        return content;
        
    }
protected void fillSheet(WritableSheet sheet, Collection datas, Map params) throws RowsExceededException, WriteException{
        int row = sheet.getRows();
        int column = sheet.getColumns();
        int beginRow = -1;
        int beginCol = -1;
        List<WritableCell> cellFields = new ArrayList<WritableCell>();
        Map<WritableCell, Boolean> groupMap = new HashMap<WritableCell, Boolean>();
        //
        for (int i = 0; i < row; i ++) {
            //
            for (int j = 0; j < column; j ++){
                //根据列,行获取到单元格
                WritableCell cell = sheet.getWritableCell(j, i);
                //获取到单元格值
                String cellExp = cell.getContents();
                //判断单元格内是否有标签
                if (cellExp != null && cellExp.length() > 0){
                    //如果有$F{标志
                    if (cellExp.indexOf("$F{") >= 0) {
                        if (beginRow == -1){
                            beginRow = i;
                        } 
                        if (beginCol == -1) {
                            beginCol = j;
                        }
                        if (i > beginRow)
                            break;
                        cellFields.add(cell);
                        if (this.isGroup(cellExp)) {
                            groupMap.put(cell, Boolean.TRUE);
                        }
                        
                        sheet.addCell(this.fillCell(cell, null, cell.getCellFormat()));
                      //表头,副标
                    } else {
                        Object value = this.fillCellByExp(cellExp, params, datas);
                        sheet.addCell(this.fillCell(cell, value, cell.getCellFormat()));
                    }
                }
            }
        }
        this.fillDatas(datas, params, sheet, cellFields, groupMap, beginRow, beginCol);


    }

Excel模板:

原文地址:https://www.cnblogs.com/hnzkljq/p/12529615.html