SpringMVC 下载文本实现边转码边下载
方案一: PrintWriter + CharacterEncoding
SpringMVC 框架的接口中 Response 有 ServletOutputStream 和 PrintWriter 两种输出,还有一个 setCharacterEncoding 方法。
OutPutStream 视为写入二进制数据,容器不对二进制数据进行编码,即 setCharacterEncoding 无效。所以先采用 PrintWriter 搭配 setCharacterEncoding 方法。
@GetMapping("/downloadFile1")
public void downloadFile1(HttpServletResponse response) throws IOException{
//读取本地文件
File file = new File(LOCAL_FILE_PATH);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
//设置下载
response.setHeader("Content-Disposition", "attachment;filename=file.csv");
response.setContentType("application/octet-stream");
response.setCharacterEncoding("GB2312");
//传输
BufferedWriter bufferedWriter = new BufferedWriter(response.getWriter());
String line;
while ((line = bufferedReader.readLine()) != null) {
bufferedWriter.write(line + "\r\n");
bufferedWriter.flush();
}
bufferedReader.close();
bufferedWriter.close();
}
无用,没有仔细研究,应该 setCharacterEncoding 只是告诉浏览器是什么编码,没有解码功能。
方案二:ServletOutputStream + OutputStreamWriter
将 response.getOutputStream() 获取到的流用 OutputStreamWriter 包装。结果可行。
@GetMapping("/downloadFile2")
public void downloadFile2(HttpServletResponse response) throws IOException{
//读取本地文件
File file = new File(LOCAL_FILE_PATH);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
//设置下载
response.setHeader("Content-Disposition", "attachment;filename=file.csv");
response.setContentType("application/octet-stream");
//传输
OutputStreamWriter writerStream = new OutputStreamWriter(response.getOutputStream(),"GBK");
String line;
while ((line = bufferedReader.readLine()) != null) {
writerStream.write(line + "\r\n");
writerStream.flush();
}
bufferedReader.close();
writerStream.close();
}
方案三:ServletOutputStream + getBytes
在按行写入字符串时,使用 getBytes 方法将字符串转换为想要输出的编码格式。结果可行。
@GetMapping("/downloadFile3")
public void downloadFile3(HttpServletResponse response) throws IOException{
//读取本地文件
File file = new File(LOCAL_FILE_PATH);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
//设置下载
response.setHeader("Content-Disposition", "attachment;filename=file.csv");
response.setContentType("application/octet-stream");
//传输
OutputStream outputStream = response.getOutputStream();
String line;
while ((line = bufferedReader.readLine()) != null) {
outputStream.write((line + "\r\n").getBytes("GB2312"));
outputStream.flush();
}
bufferedReader.close();
outputStream.close();
}
无需转码的写法
若不需要转码的话,就很简短了,用字节流就行了。
@GetMapping("/downloadFile4")
public void downloadFile4(HttpServletResponse response) throws IOException{
//读取本地文件
File file = new File(LOCAL_FILE_PATH);
FileInputStream fis = new FileInputStream(file);
//设置下载
response.setHeader("Content-Disposition", "attachment;filename=file.csv");
response.setContentType("application/octet-stream");
//传输
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[4096];
int b = -1;
while ((b = fis.read(buffer)) != -1) {
os.write(buffer, 0, b);
}
fis.close();
os.close();
}
简写的话可以用第三方包。
import org.springframework.util.FileCopyUtils;
@GetMapping("/downloadFile5")
public void downloadFile5(HttpServletResponse response) throws IOException{
//读取本地文件
File file = new File(LOCAL_FILE_PATH);
InputStream inputStream= new BufferedInputStream(new FileInputStream(file));
//设置下载
response.setHeader("Content-Disposition", "attachment;filename=file.csv");
response.setContentType("application/octet-stream");
//传输
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
补充:
- 使用 Nginx 可以不通过接口前端直接下载,后续可以尝试采用此方法。
Last modified on 2020-03-04