@GetMapping("/downloadTemplate")
public void downloadExcelFile(HttpServletResponse response) throws IOException {
// 第一种获取项目文件的方法(resource目录下的template文件夹下的testImport.xlsx文件的路径)
// String path = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "template" + "/" + "testImport.xlsx";
// 第二种获取项目文件的方法(resource目录下的template文件夹下的testImport.xlsx文件)
// getClass().getResourceAsStream("/template/testImport.xlsx");
// 第三种获取项目文件的方法(resource目录下的template文件夹下的testImport.xlsx文件)
ClassPathResource classPathResource = new ClassPathResource("/template/testImport.xlsx");
InputStream is = classPathResource.getInputStream();
BufferedInputStream inputStream = new BufferedInputStream(is);
response.reset();
// 设置响应头为二进制文件流
response.setContentType("application/octet-stream");
// 文件名(前端会重新设置)
String filename = "testImport.xlsx";
// 设置header,附件形式,方便下载
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
// 获取响应的OutputStream
ServletOutputStream outputStream = response.getOutputStream();
byte[] b = new byte[1024];
int len;
// 从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
while ((len = inputStream.read(b)) > 0) {
// 写入输出流中
outputStream.write(b, 0, len);
}
// 关闭外层输入流
inputStream.close();
// 关闭内层输入流
is.close();
}
以上是后端方法,因为代码较少,就不写service了。
下面是前端代码(Vue3):
/**
* 下载excel导入模板
*/
const downloadImportExcelTemplate = () => {
fetchBinaryFile();
};
const fetchBinaryFile = async () => {
try {
// 发送 GET 请求获取二进制文件
const response = await axios.get('/api/manage/visitorReporting/downloadTemplate', {
// 设置 responseType 为 blob
responseType: 'blob',
// 添加 token 到请求头
headers: {
Authorization: `Bearer ${Session.getToken()}`
}
});
console.log("下载文件响应结果:", response);
// 处理响应数据
handleBinaryResponse(response);
} catch (error) {
console.error('Error fetching binary file:', error);
}
};
const handleBinaryResponse = (response) => {
// 检查响应数据是否为 Blob 类型
if (response.data instanceof Blob) {
downloadFile(response.data, '访客导入模板.xlsx');
} else {
console.error('Response data is not a Blob:', response.data);
}
};
const downloadFile = (blob, filename) => {
// 创建一个隐藏的可下载链接
const link = document.createElement('a');
console.log("blob内容:", blob);
const url = URL.createObjectURL(blob);
link.href = url;
link.setAttribute('download', filename); // 设置下载文件名
document.body.appendChild(link);
link.click();
// 清理工作
document.body.removeChild(link);
URL.revokeObjectURL(url);
};
注意:如果前端下载完成,点开文件,显示文件损坏,那很可能是你的项目里,maven再build的时候压缩了你的文件,尤其是office文件,例如xlsx、word等。验证办法就是点开target文件夹,找到你的项目文件,双击,如果是提示文件损坏,那就是maven的问题了。
解决办法:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
pom文件中加上这一段就好了,build项目时候,就不会压缩xlsx类型的文件。