通常的文件下载方法

@RequestMapping("/downLoadFile")
public void downLoadLineStruImportTemplateFile(HttpServletResponse response) {
// 创建缓冲区
byte buffer[] = new byte[1024];// 缓冲区大小1k
int len = 0;
// 重点就是获取输入流和输出流,还有设置请求头
try (InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/lineStruImportTemplate.xlsx");
OutputStream out = response.getOutputStream()) {
// 设置头部信息
// 文件类型application/octet-stream
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
// 文件名称
response.setHeader(
"Content-disposition",
"attachment;filename="
+ new String(("线路结构导入模板.xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));

//循环将输入流中的内容读取到缓冲区当中
while ((len = in.read(buffer)) > 0) {
//输出缓冲区的内容到浏览器,实现文件下载
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}

文件的下载:浏览器带进度显示

@RequestMapping("/download")
public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
String filePath = "文件路径";
File file = new File(filePath);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
// 文件名称
response.setHeader(
"Content-disposition",
"attachment;filename="
+ new String((file.getName()).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
// 这里正确设置,浏览器下载时就会显示进度
response.setContentLengthLong(file.length());
try (FileInputStream fileInputStream = new FileInputStream(file)) {
OutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}

// 这里可关可不关
// 不建议关,响应结束时,Servlet 会自动将 out 关闭
// outputStream.flush();
// outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}

}

文件的预览(此时浏览器不会下载文件,而是会尽量渲染文件,比如音视频文件播放,图片、pdf会展示等

文件的预览和上面的代码基本一致,
但是去除设置头部信息的两行代码,
同时根据文件的类型设置不同的ContentType

@RequestMapping("/downLoadFile")
public void downLoadLineStruImportTemplateFile(HttpServletResponse response) {
// 创建缓冲区
byte buffer[] = new byte[1024];// 缓冲区大小1k
int len = 0;
// 重点就是获取输入流和输出流,还有设置请求头
try (InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/lineStruImportTemplate.xlsx");
OutputStream out = response.getOutputStream()) {
// 设置头部信息(文件的mineType)
// pdf就设置application/pdf
// response.setContentType(MediaType.APPLICATION_PDF_VALUE);
// jpg就设置image/jpeg
// response.setContentType(MediaType.IMAGE_JPEG_VALUE);
// png就设置image/png
// response.setContentType(MediaType.IMAGE_PNG_VALUE);
// 使用工具类(最好是在文件上传的时候读取文件的mineType,保存在数据库里,然后预览的时候从数据库里查找)
response.setContentType(getMineType("lineStruImportTemplate.xlsx"));


//循环将输入流中的内容读取到缓冲区当中
while ((len = in.read(buffer)) > 0) {
//输出缓冲区的内容到浏览器,实现文件下载
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}


/**
* 文件的mineType可以根据Apache Tika(一个java工具集)来获取
* <dependency>
* <groupId>org.apache.tika</groupId>
* <artifactId>tika-core</artifactId>
* <version>2.7.0</version>
* </dependency>
*/

/**
* 已知文件名,获取文件类型,在某些情况下比通过字节数组准确,例如使用jar文件时,通过名字更为准确
*
* @param name 文件名
* @return mineType 无法识别时会返回“application/octet-stream”
*/
public static String getMineType(String name) {
return TIKA.get().detect(name);
}

/**
* 在拥有文件和数据的情况下,最好使用此方法,最为准确
*
* @param data 文件内容
* @param name 文件名
* @return mineType 无法识别时会返回“application/octet-stream”
*/
public static String getMineType(byte[] data, String name) {
return TIKA.get().detect(data, name);
}
}