通過 HttpServletResponse 設置響應頭,將數據流直接寫入瀏覽器下載,無需在服務器生成臨時文件。關鍵步驟:
Content-Type: text/plainContent-Disposition: attachment; filename=xxx.txt 觸發下載BufferedOutputStream 包裝 ServletOutputStream 高效寫入@RequestMapping(value = "/grab/export/csv", method = RequestMethod.GET)
public void exportCsv(HttpServletRequest request, HttpServletResponse response) {
String userId = ServletRequestUtils.getStringParameter(request, "userId", "test");
List<VideoListModel> list = sqlVideoList.selectSuccessDate(userId);
response.setContentType("text/plain;charset=UTF-8");
String fileName = "videolist.txt";
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
try (BufferedOutputStream buff = new BufferedOutputStream(response.getOutputStream())) {
StringBuilder write = new StringBuilder();
String enter = "\r\n";
if (list != null && !list.isEmpty()) {
for (VideoListModel model : list) {
write.append(model.getUrl()).append(",")
.append(model.getTitle()).append(enter);
}
}
buff.write(write.toString().getBytes("UTF-8"));
buff.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/{exchangeId}/{packageId}/export", method = RequestMethod.GET)
public void writeToTxt(@PathVariable String exchangeId, @PathVariable String packageId,
HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String schoolId = getSchoolId(request);
List<VipCode> vipCodes = vipExchangeManager.getVipCode(example);
if (vipCodes.isEmpty()) return;
response.setContentType("text/plain;charset=UTF-8");
String fileName = URLEncoder.encode(vipCodes.get(0).getName(), "UTF-8") + ".txt";
response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
try (BufferedOutputStream buff = new BufferedOutputStream(response.getOutputStream())) {
StringBuilder write = new StringBuilder();
String tab = "\t";
String enter = "\r\n";
for (int i = 0; i < vipCodes.size(); i++) {
VipCode code = vipCodes.get(i);
write.append(i + 1).append(tab) // 序號
.append(code.getExchangeCode()).append(tab) // 兌換碼
.append("normal".equals(code.getStatus()) ? "正常" : "已兌換") // 狀態
.append(enter);
}
buff.write(write.toString().getBytes("UTF-8"));
buff.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| 文件名亂碼 | 文件名未 URLEncoder.encode | 下載前對文件名編碼 |
| 內容亂碼 | 寫入編碼與聲明不一致 | 統一使用 UTF-8 |
| 下載空文件 | 流未 flush/close | 確保 buff.flush() 執行 |
| 大文件導出慢 | 一次性載入所有數據 | 流式查詢 + 分批寫入 |