解决办法
原生开发
当原生开发的时候,就要依靠操作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模板: