难以从Servlet发送Excel工作簿

时间:2014-03-03 21:38:09

标签: java jquery servlets apache-poi

我的项目涉及创建一个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 + "<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”
  Content-Type application / vnd.openxml
  日期星期一,03三月2014 20:56:15 GMT
  服务器Apache-Coyote / 1.1
  Transfer-Encoding chunked

同样在Response选项卡下的FireBug中,我得到了一堆乱码:

enter image description here

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

是否有人能告诉我出错的地方?我希望浏览器提示我要放置文件的位置。感谢。

1 个答案:

答案 0 :(得分:2)

我使用了一个非常古老的代码库,该公司的政策是“如果它不能解决它”,那么这就是我们对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用于定义发送到服务器的内容(您似乎已经指出它正常工作),所以我不会过分关注它。