[英]Create a CSV and return as byte[] for download in a Spring Controller
摘要: ResponseEntity<byte[]>
包含 CSV 不返回為 CSV
我正在為下載按鈕編寫 controller ,該按鈕將生成一個 CSV ,其中包含從另一個依賴項中檢索到的數據。
@PostMapping(BASE_ROUTE + "/download")
public ResponseEntity<byte[]> downloadCases(@RequestBody RequestType request, final HttpServletResponse response) throws IOException {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
PrintWriter writer = new PrintWriter(outputStreamWriter, true)) {
String nextPageToken = null;
do {
ServiceResponse serviceResponse = makeServiceCall(request.getParam());
// write a String of comma separated values
writer.println(serviceResponse.getLine());
// eventually null
nextPageToken = serviceResponse.getToken();
} while (nextPageToken != null);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, "text/csv")
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"report.csv\"")
.body(outputStream.toByteArray());
}
作為測試,我還嘗試將正文設置為.body("Case ID,Assignee".getBytes(StandardCharsets.UTF_8))
。 這應該等同於https://stackoverflow.com/a/34508533/10327093
在這兩種情況下,我得到的響應都類似於 Base64。 示例(縮短): Q2FzZSBJRCxBc3NpZ25lZQ==
它似乎實際上不是 Base64。 使用.body(Base64.getDecoder().decode(outputStream.toByteArray()))
給我java.lang.IllegalArgumentException: Illegal base64 character
如果我返回void
並將 outputStream 復制到 response.getOutputStream() 與IOUtils.write(outputStream.toByteArray(), response.getOutputStream());
,下載的文件是正確的(CSV)。
但是我想避免直接調用 response.getOutputStream() 。 如果之后我得到任何異常,我會得到錯誤getOutputStream() has already been called for this response
in the @ExceptionHandler
編輯: Base64 解碼響應給了我正確的值
System.out.println(new String(Base64.getDecoder().decode("Q2FzZSBJRCxBc3NpZ25lZQ==")));
// Case ID,Assignee
似乎 byte[] 在返回 ResponseEntity 和客戶端之間進行了 Base64 編碼(嘗試使用 Postman 和瀏覽器)。
不幸的是,我無法發表評論,所以我會發布作為答案,但這只是一些建議:
您是否嘗試過使用“應用程序/csv”而不是“文本”/csv?
不久前我不得不做一些非常相似的事情,只看你的代碼,我沒有發現任何問題。
這是我所做的一個例子:
public ResponseEntity<Object> myMethod() {
String filename = "filename.xlsx";
byte[] bytes = getBytes();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/vnd.ms-excel;");
headers.setContentDispositionFormData(filename, filename);
return new ResponseEntity<Object>(bytes, headers, HttpStatus.OK);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.