На сайте моей компании есть несколько таблиц, которые нужно экспортировать в CSV-файл.
Существуют различные параметры, поэтому CSV-файл необходимо создавать динамически по запросу.
Моя проблема в том, что после нажатия на загрузку ответ зависает и ждет создания всего файла (что может занять некоторое время) и только затем загружает весь файл в одно мгновение.
Я использую AngularJS, поэтому я использую window.location = <url_for_file_download>
, чтобы браузер загрузил файл.
На стороне сервера я использую Java Spring и выполнил все инструкции, которые смог найти в Интернете, чтобы создать контроллер загрузки файлов.
Мой код контроллера выглядит примерно так:
@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
.
.
.
}
Мой код для установки заголовков ответа:
response.setContentType("text/csv;charset=utf-8");
response.setHeader("Content-Disposition","attachment; filename=\"" + fileName + ".csv\"");
Я также попытался добавить следующие заголовки:
response.setHeader("Transfer-Encoding", "Chunked");
response.setHeader("Content-Description", "File Transfer");
и я также попытался установить Content-type на "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);
Я перебираю данные и пишу так:
for (String[] row: data) {
writer.writeNext(line);
}
(Это не совсем код, но это нечто большее, чем то, что происходит в коде)
И в конце смываю и закрываю:
writer.flush();
writer.close();
Я также пробовал сбрасывать после каждой строки, которую я пишу.
Так почему же файл не передается до того, как он будет записан? Почему мой браузер (Google Chrome) загружает файл в одно мгновение после долгого ожидания? И как я могу это исправить.
Надеюсь, я добавил достаточно кода, если чего-то не хватает, просто сообщите мне, и я постараюсь добавить это сюда.
Огромное спасибо заранее.