【发布时间】:2014-04-05 03:57:08
【问题描述】:
我的项目涉及创建一个带有表格的 HTML 页面,并在页面上放置一个标有“导出到 Excel”的按钮。整个目的是将表格数据转换为可以从 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 + "<br/><br/>" +
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<String> header = table.getHeader();
ArrayList<String[]> 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<String> header;
private ArrayList<String[]> data;
public void setHeader(ArrayList<String> list)
{
header = list;
}
public ArrayList<String> getHeader()
{
return header;
}
public void setData(ArrayList<String[]> value)
{
data = value;
}
public ArrayList<String[]> getData()
{
return data;
}
}
从 Servlet 代码中可以看出,我可以轻松地创建一个工作簿并将通过 JSON 字符串发送的所有数据放入其中。到目前为止,一切都很好。
对于 Servlet 的响应,我在 FireBug 中得到以下信息:
响应标头
内容处置附件;文件名="data.xlsx"
内容类型 application/vnd.openxml
日期 2014 年 3 月 3 日星期一 20:56:15 GMT
服务器 Apache-Coyote/1.1
传输编码分块
同样在 Response 标签下的 FireBug 中,我得到一堆乱码:
我认为这是某种错误。从 JQuery Ajax 错误函数我得到:SyntaxError: JSON.parse: unexpected character。不知道这是什么情况???浏览器不会提示我将文件保存在任何地方。我在Firefox和IE浏览器都试过了,结果是一样的。我尝试在 application/vnd.openxml 和 application/vnd.ms-excel,但结果还是一样。
有人能告诉我哪里出错了吗?我希望浏览器提示我要放置文件的位置。谢谢。
【问题讨论】:
-
我认为您不能将 Excel 文件返回给 Ajax。只需给用户一个指向 servlet 的链接,或使其成为提交给 servlet 的 HTML 表单。如果不是全部问题,使用 Ajax 可能是您问题的一半。
-
从 servlet 你已经为 excel 文件设置了 mime 类型并发送 excel 文件但是在 ajax 调用中你已经将 mime 类型设置为 json 这表示响应正文将包含 json 所以 jquery 将尝试将内容解析为json 并且显然响应不是有效的 json 所以它会抛出 JSON.parse 异常
-
现在看!我学到了一些新东西。是的,我在 ajax 调用中将 mime 类型设置为 json,因为我正在发送一个 json 字符串,但我认为因为响应是不同的 mime 类型,所以 ajax 会读取内容类型标头并处理它,而不管它是什么类型.显然我错了。看起来我将不得不发挥创造力并在网页上设置一个表单,将其隐藏,然后以编程方式将其发送到 servlet。我会努力的,让你知道结果如何。
-
顺便说一句,我想知道是否有办法告诉 ajax 期望什么 mime 类型作为响应?
标签: java jquery servlets apache-poi