难以从Servlet发送Excel工作簿

我的项目涉及创建一个HTML页面,该页面有一个表格,并在标有“导出到Excel”的页面上放置一个按钮。 目的是将Table数据转换为可以从servlet下载的Excel文件。 使用JQuery我从表中收集所有数据并使用以下代码将其发送到Servlet没有问题:

$("#export").click(function(){ var head = JSON.stringify({ header: header }); var table = JSON.stringify({ data: data }); //Combine the two into on big object var obj = head.substring(0,head.length - 1) + "," + table.substring(1,table.length); $.ajax({ type: "POST", url: 'ExportToExcel', data: obj, dataType: "json", contentType: "application/json; charset=utf-8", mimeType: 'application/json', error: function (xhr, ajaxOptions, thrownError) { $('#result').html(thrownError + "

" + xhr.responseText); } }) });

这是我的Servlet代码:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream())); String json = ""; if(br != null){ json = br.readLine(); } //System.out.println("json: " + json); br.close(); Gson gson = new Gson(); Table table = gson.fromJson(json, Table.class); ArrayList header = table.getHeader(); ArrayList data = table.getData(); XSSFWorkbook wb = new XSSFWorkbook(); //CreationHelper createHelper = wb.getCreationHelper(); XSSFSheet sheet = wb.createSheet("Sheet1"); //create the Header XSSFRow rowhead = sheet.createRow(0); for(int i = 0; i < header.size(); i++) { rowhead.createCell(i).setCellValue(header.get(i)); } XSSFRow row = null; XSSFCell cell = null; String[] temp = null; for(int i = 0; i < data.size(); i++) { temp = data.get(i); row = sheet.createRow(i); for(int j = 0; j < temp.length; j++) { cell = row.createCell(j); cell.setCellType(XSSFCell.CELL_TYPE_STRING ); cell.setCellValue(temp[j]); } } //response.setContentType("application/vnd.ms-excel"); response.setContentType("application/vnd.openxml"); //response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); String filename = "data.xlsx"; response.setHeader("Content-disposition", "attachment; filename=\"" + filename + "\"" ); ServletOutputStream out = response.getOutputStream(); wb.write(out); out.flush(); out.close(); } catch(Exception e){e.printStackTrace();} } class Table { private ArrayList header; private ArrayList data; public void setHeader(ArrayList list) { header = list; } public ArrayList getHeader() { return header; } public void setData(ArrayList value) { data = value; } public ArrayList getData() { return data; } } 

从Servlet代码中可以看出,我可以轻松地创建一个工作簿,并将通过JSON字符串发送的所有数据放入其中。 到现在为止还挺好。

对于从Servlet返回的响应,我在FireBug中获得以下内容:

响应标题
内容 – 处置附件; 文件名= “data.xlsx”
Content-Type application / vnd.openxml
日期星期一,03三月2014 20:56:15 GMT
服务器Apache-Coyote / 1.1
Transfer-Encoding chunked

同样在Response选项卡下的FireBug中,我得到了一堆垃圾字符:

在此处输入图像描述

我认为这是某种错误。 从JQuery Ajax错误函数我得到: SyntaxError:JSON.parse:意外的字符 。 我不知道那是什么??? 浏览器不会提示我将文件保存在任何地方。 我试过Firefox和IE浏览器,结果是一样的。 我尝试在: application / vnd.openxmlapplication / vnd.ms-excel之间来回更改ContentType,但结果再次相同。

有人能告诉我哪里出错了吗? 我希望浏览器提示我要放置文件的位置。 谢谢。

我使用一个非常古老的代码库,该公司的政策是“如果它不能解决它”,那么这就是我们对XLSX Export的servlet响应的看法。

 response.setHeader("Expires", "0"); response.setHeader("Content-disposition", "attachment;filename=" + exportTitle + "_" + fileDate + ".xlsx"); // I noticed you had "/" before and after the filename, try removing that, and add the extension. response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Our legacy code actually has "application/xlsx" and it works fine - but [other answers indicate better](https://stackoverflow.com/questions/974079/setting-mime-type-for-excel-document) 

…对于你的AJAX,我会尝试删除dataType规范,因为你的响应头定义了它,jQuery应该只是“滚动”它。 我相信mimeType和contentType用于定义发送到服务器的内容(您似乎已经指出它正常工作),所以我不会过分关注它。