Java Spring - dynamically generated csv file download response is hanging

jon*_*rdo 5 java csv spring opencsv

On my company's site we have some tables that we need to export to a csv file.
There are some varying parameters, so the csv file needs to be dynamically created on request.

My problem is that after clicking to download, the response hangs, and waits for the whole file to be created (which can take some time) and only then downloads the entire file in one instant.

I'm using AngularJS, so I'm using window.location = <url_for_file_download> In order to make the browser download the file.

On the server side I'm using Java Spring and I've followed all the instructions I could find on the web in order to create a file download controller.

My controller code is something like this:

@RequestMapping(value = "http://yada.yada.yada/csv/myFile.csv", method = RequestMethod.GET)
public @ResponseBody
void getCustomers(HttpServletResponse response,
                         @RequestParam(required = false) String someParameters) 
                         throws NotAuthorizedException, IOException {  
// set headers
setHeaders(response);
// generate writer
CSVWriter write = generateWriter(response);
// get data
List<String[]> data = getData();
// write and flush and all that
.
.
.
}
Run Code Online (Sandbox Code Playgroud)

My code for setting the response headers are:

response.setContentType("text/csv;charset=utf-8");
response.setHeader("Content-Disposition","attachment; filename=\"" + fileName + ".csv\"");
Run Code Online (Sandbox Code Playgroud)

I've also tried adding the following headers:

response.setHeader("Transfer-Encoding", "Chunked");
response.setHeader("Content-Description", "File Transfer");
Run Code Online (Sandbox Code Playgroud)

and I've also tried setting the Content-type to "application/octet-stream".

请注意,我没有添加Content-length标题,因为该文件尚不存在,并且正在即时写入。

为了编写 csv 文件,我使用的是 OpenCSV,我的代码如下:

OutputStream resOs = response.getOutputStream();
OutputStream buffOs = new BufferedOutputStream(resOs);
OutputStreamWriter outputWriter = new OutputStreamWriter(buffOs,"UTF-8");
CSVWriter writer = new CSVWriter(outputWriter);
Run Code Online (Sandbox Code Playgroud)

我遍历数据并像这样写:

for (String[] row: data) {
    writer.writeNext(line);
}
Run Code Online (Sandbox Code Playgroud)

(这不完全是代码 - 但这更多,否则代码中会发生什么)

最后我刷新并关闭:

writer.flush();
writer.close();
Run Code Online (Sandbox Code Playgroud)

我也尝试在我写的每一行之后冲洗。

那么为什么在文件全部写入之前不传输文件呢?为什么我的浏览器(谷歌浏览器)在等待了很长时间后立即下载了文件?我该如何解决这个问题。

我希望我已经添加了足够的代码,如果有什么遗漏请告诉我,我会尝试在这里添加它。

非常感谢你。

Tho*_*mas 3

你可以尝试在你的java中返回一个空值吗

返回空值;

或者您也可以尝试下面的代码 1. 单击提交按钮后的 Jquery 代码

$(document).ready( function() {
     $('#buttonName').click(function(e){
    $("#formName").submit();
     //alert("The file ready to be downloaded");

});
});
Run Code Online (Sandbox Code Playgroud)

您的控制器代码

@RequestMapping(value="/name",method=RequestMethod.POST)                


public ModelAndView downloadCSV(ModelMap model,HttpSession session,@ModelAttribute(value="Pojo") Pojo pojo
            ,HttpServletRequest request,HttpServletResponse response){

----------------some code----------------

response.setContentType("application/csv");   
("application/unknown"); 
response.setHeader("content-disposition","attachment;filename =filename.csv"); 
ServletOutputStream  writer = response.getOutputStream();   
            logger.info("downloading contents to csv");

            writer.print("A");
            writer.print(',');
            writer.println("B");            

        for(int i=0;i<limit;i++){

                writer.print(""+pojo.get(i).getA());
                writer.print(',');
                writer.print(pojo.get(i).getB()); 
                writer.println();   
        }

        writer.flush();
        writer.close();

---------------some code-----------
return null;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助