1. 程式人生 > 實用技巧 >Spring MVC 優雅下載和檔名正常顯示(轉載)

Spring MVC 優雅下載和檔名正常顯示(轉載)

https://blog.csdn.net/jiaobuchong/article/details/84641668

使用 Spring MVC 的 ResponseEntity 傳入檔案的位元組碼即可實現下載功能,不用往HttpServletResponse response的輸出流寫位元組了。

public class BasicController {
    protected ResponseEntity<byte[]> getFile(String fileName, byte[] dataArray) throws Exception {
        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"; filename*=utf-8''" + fileName);
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(dataArray);
    }

    protected ResponseEntity<byte[]> getExcelFile(String fileName, byte[] dataArray) throws Exception {
//        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
        // Safari 和 Chrome 都可以正常下載包含中文檔名的 excel 檔案
        fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"; filename*=utf-8''" + fileName);
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        return ResponseEntity
                .ok()
                .headers(headers)
                .body(dataArray);
    }
}

  getFile方法在 Safari 瀏覽器不能正常下載 Excel 檔案,下載的是一個字尾名為.dms檔案。getExcelFile指定 Excel 的 MIME 型別,並將檔名編碼為ISO_8859_1,相容 Chrome 和 Safari 的下載。

@RestController
public class FileProcessController extends BasicController {
    @GetMapping("/test/download")
    public ResponseEntity<byte[]> downloadFile(d) throws Exception {
    	 // 得到檔案的位元組陣列 
    	 byte[] dataArray = getData(); 
        return this.getExcelFile("excel-檔案下載.xlsx", dataArray);
    }
}

  在瀏覽器裡模擬一下:

Spring MVC 檔案下載測試: <a href="http://localhost:8080/test/download">點選下載</a>