簡體   English   中英

創建一個 CSV 並以 byte[] 形式返回,以便在 Spring Controller 中下載

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM