Vue实现点击按钮进⾏⽂件下载(后端Java)
java下载过程最近项⽬中需要实现点击按钮下载⽂件的需求,前端⽤的vue,因为⽂件是各种类型的,⽐如图⽚、pdf、word之类的。这⾥后端是可以返回⽂件的地址给前端的,但我看了下⽹上各种五花⼋门的答案,感觉都不是我想要的。
因为不确定⽂件是哪种类型的,所以我们在保存⽂件到数据库的时候,应该把⽂件的Content-Type⼀起存⼊,这样从数据库取出返回前端的时候,带
上Content-Type标识是哪种类型的⽂件,前端解析即可。
1、后端代码
这⾥我先写后端的接⼝,考虑⼀下后端需要什么东西。因为⽂件信息已经提前存⼊数据库,所以我们只需要传⼊主键id就可以拿到⽂件的信息。确定参数后,就需要确定⼀下返回值类型。这⾥可以使⽤ResponseEntity返回。ResponseEntity可以⼀次返回多个信息,包括状态码,响应头信息,响应内容等。
话不多说,看代码。
/**
* 下载附件
* @param attachmentId
* @return
*/
public ResponseEntity<byte[]> download(Long attachmentId) {
messagedigest过时了吗// 查询附件是否存在
SysAttachment sysAttachment = sysAttachmentMapper.selectSysAttachmentById(attachmentId);
if (StringUtils.isNull(sysAttachment)) {
return null;
}
ByteArrayOutputStream bos = null;
InputStream ins = null;
try {
String fileName = OrgFileName();
String ossFileName = Url();
bos = new ByteArrayOutputStream();
ins = Instance().getObject(ossFileName).getObjectContent();
// 取流中的数据
int len = 0;
byte[] buf = new byte[256];
while ((len = ad(buf, 0, 256)) > -1) {
bos.write(buf, 0, len);
}
// 防⽌中⽂乱码
fileName = de(fileName, "utf-8");
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename=" + fileName);
headers.add("Content-Type", ContentType());
// 设置响应吗
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(ByteArray(), headers, statusCode);
return response;
} catch (Exception e) {
throw new CustomException("下载失败");
} finally {
try {
if (ins != null) {
ins.close();
}
if (bos != null) {
bos.close();
}
} catch (Exception e) {
throw new CustomException("下载失败");
}
}
}
这⾥我们从数据库拿出⽂件的url后,再通过阿⾥云oss拿到⽂件的输⼊流,接着把⽂件输出为⼆进制,封装到ResponseEntity中,并把⽂件的类型设置
到Content-Type中,同时为了防⽌⽂件名带有中⽂名乱码,设置utf-8编码,⾄此后端接⼝完成。
通过上⾯的信息,我们在数据库保存⽂件信息时,⾄少应该保存下⾯⼏个字段:⽂件的url(⼀般在上传到oss后会给你⼀个)、⽂件的类型、原始⽂件名、⽂件⼤⼩等。
2、前端代码
有了后端接⼝,接下来就是前端了。这⾥可以把⽂件下载的⽅法封装成⼀个通⽤⽅法全局挂载,之后需要使⽤的地⽅直接使⽤即可。
我们需要标识不同的⽂件,所以我们需要⼀个键值对表⽰不同的⽂件。
const mimeMap = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
xls: 'application/vnd.ms-excel',
zip: 'application/zip',
jpg: 'image/jpg',
jpeg: 'image/jpeg',
png: 'image/png',
doc: 'application/msword',
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
ppt: 'application/vnd.ms-powerpoint',
txt: 'text/plain',
pdf: 'application/pdf'
eclipse单词补全快捷键}
有需要的可以继续补充。接下来⾃然就是发请求了,这⾥的返回类型可以设置为blob,使⽤axios直接发送
/**
* 下载附件
* @param path 接⼝地址
* @param param  请求参数
*/
export function downloadAttachment(path, param) {
var url = baseUrl + path + param
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': getToken() }
}).then(res => {
resolveBlob(res, pe)
})
}
接⼝地址和请求参数从外部传⼊。同时需要携带token,不然会跨域访问。拿到后端返回的数据后,需要解析⼆进制⽂件,这⾥定义resolveBlob⽅法,该⽅法有两个参数,返回对象和⽂件的类型,⽂件的类型,我们在后端已经放⼊Content-Type中了,这⾥直接取。
/**
* 解析blob响应内容并下载
* @param {*} res blob响应内容
* @param {String} mimeType MIME类型
*/
export function resolveBlob(res, mimeType) {
const aLink = ateElement('a')
var blob = new Blob([res.data], { type: mimeType })
// 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的⽂件名;
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
var contentDisposition = decodeURI(res.headers['content-disposition'])
var result = (contentDisposition)
var fileName = result[1]
fileName = place(/\"/g, '')
aLink.href = ateObjectURL(blob)
aLink.setAttribute('download', fileName) // 设置下载⽂件名称
document.body.appendChild(aLink)
aLink.click()
veChild(aLink);
}
这代码不⽤多解释了吧,前端⼤佬们⾃然看得懂。OK了啊,到这⾥前后端代码都完成了。
3、使⽤
sql除法保留两位小数使⽤那就更简单啦。先挂载到全局
import { downloadAttachment } from "@/utils/download"
Vue.prototype.downloadAttac = downloadAttachment
在使⽤的地⽅直接调⽤即可
<el-button
type="text"
数据库新手教程
icon="el-icon-download"
size="mini"
@click="w.attachmentId)"
></el-button>
/** 下载附件 */
downloadAttachRow(attachId) {
this.$confirm('是否确认下载该⽂件?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.downloadAttac('/system/attachment/download/', attachId)
}).then(() => {
this.msgSuccess("下载成功")
verilog左移一位
}).catch(() => {})
}
到此结束。如果过程中遇到什么问题,可以在下⽅留⾔,我会回复的。
觉得好的可以帮忙点个赞啊,也可以关注我的【秃头哥编程】

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。