目录结构如下:
后端方法
FileEntity 内容为文件的一些相关信息,例如文件名等。
说明:模板文件为xlsx文件,因此设置response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
如果是其他类型的文件,需要更换为相关内容
@PostMapping("/importTemplate")
public void importTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody FileEntity fileEntity) throws Exception {
String path="fileTemplates/"+fileEntity.getFileName();
InputStream inputStream = null;
OutputStream outputStream = null;
try {
ClassPathResource classPathResource = new ClassPathResource(path);
if (!classPathResource.exists()) {
throw new Exception("模板不存在");
}
File file = classPathResource.getFile();
//获取路径
String path1 = classPathResource.getPath();
System.out.println("path:" + path1);
System.out.println("file:" + file.length());
//读取要下载的文件,保存到文件输入流
inputStream = classPathResource.getInputStream();
outputStream = response.getOutputStream();
// response.setContentType("application/octet-stream");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");;
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" +fileEntity.getFileName().substring(0,fileEntity.getFileName().indexOf("."))+ ".xlsx");
byte[] buff = new byte[2048];
int i = 0;
while ((i = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, i);
outputStream.flush();
}
} catch (Exception e) {
throw new Exception("模板下载失败");
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
throw new Exception("模板下载失败");
}
}
}
通常情况下,到这一步已经可以完成模板文件的下载。
但是,本人的情况是虽然可以下载,但是下载后的文件无法打开。
以下是原因以及解决方案:
排除了一下原因,发现下载后 的模板文件大小与源文件不一致。
原因是打包后的target下的模板文件有问题,无法打开,并且文件大小与源文件不一致。
也就是说maven打包的过程中,只是将src/main/resources/目录下的文件变大了。因为我们在pom中开启了资源过滤。
解决办法:打包到classpath下,但是不进行资源过滤
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>*.xlsx</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>*.xlsx</include>
</includes>
</resource>
</resources>
至此,问题解决~
vue前端内容:
请求内容注意使用responseType为 “blob”,
// 模板下载
export function importTemplate(data) {
return request({
url: '/ccr/project/file/importTemplate',
method: 'post',
responseType: "blob",
data: data
})
}
页面调用:
let param={
fileName :"自挣卡损失兑现汇总模板.xlsx"
}
importTemplate(param).then(res => {
const _exportFileUrl = window.URL.createObjectURL(
new Blob([res], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,charset=utf-8'
})
)
const _link = document.createElement('a')
const _curDate = moment(new Date()).format('YYYYMMDD')
_link.download = `模板名称_${_curDate}`
_link.href = _exportFileUrl
_link.click()
window.URL.revokeObjectURL(_exportFileUrl)
})