Vue實現(xiàn)點擊按鈕下載文件的操作代碼(后端Java)
上篇文章給大家介紹過vue實現(xiàn)點擊按鈕下載文件功能,今天繼續(xù)vue點擊按鈕下載文件的話題。
最近項目中需要實現(xiàn)點擊按鈕下載文件的需求,前端用的vue,因為文件是各種類型的,比如圖片、pdf、word之類的。這里后端是可以返回文件的地址給前端的,但我看了下網(wǎng)上各種五花八門的答案,感覺都不是我想要的。
因為不確定文件是哪種類型的,所以我們在保存文件到數(shù)據(jù)庫的時候,應該把文件的 Content-Type 一起存入,這樣從數(shù)據(jù)庫取出返回前端的時候,帶上 Content-Type 標識是哪種類型的文件,前端解析即可。
1、后端代碼
這里我先寫后端的接口,考慮一下后端需要什么東西。因為文件信息已經(jīng)提前存入數(shù)據(jù)庫,所以我們只需要傳入主鍵id就可以拿到文件的信息。確定參數(shù)后,就需要確定一下返回值類型。這里可以使用 ResponseEntity 返回。 ResponseEntity 可以一次返回多個信息,包括狀態(tài)碼,響應頭信息,響應內(nèi)容等。
話不多說,看代碼。
/**
* 下載附件
* @param attachmentId
* @return
*/
public ResponseEntity<byte[]> download(Long attachmentId) {
// 查詢附件是否存在
SysAttachment sysAttachment = sysAttachmentMapper.selectSysAttachmentById(attachmentId);
if (StringUtils.isNull(sysAttachment)) {
return null;
}
ByteArrayOutputStream bos = null;
InputStream ins = null;
try {
String fileName = sysAttachment.getOrgFileName();
String ossFileName = sysAttachment.getUrl();
bos = new ByteArrayOutputStream();
ins = OssUtils.getInstance().getObject(ossFileName).getObjectContent();
// 取流中的數(shù)據(jù)
int len = 0;
byte[] buf = new byte[256];
while ((len = ins.read(buf, 0, 256)) > -1) {
bos.write(buf, 0, len);
}
// 防止中文亂碼
fileName = URLEncoder.encode(fileName, "utf-8");
// 設置響應頭
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename=" + fileName);
headers.add("Content-Type", sysAttachment.getContentType());
// 設置響應嗎
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(bos.toByteArray(), 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("下載失敗");
}
}
}
這里我們從數(shù)據(jù)庫拿出文件的url后,再通過阿里云oss拿到文件的輸入流,接著把文件輸出為二進制,封裝到 ResponseEntity 中,并把文件的類型設置到 Content-Type 中,同時為了防止文件名帶有中文名亂碼,設置 utf-8 編碼,至此后端接口完成。
通過上面的信息,我們在數(shù)據(jù)庫保存文件信息時,至少應該保存下面幾個字段:文件的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'
}
有需要的可以繼續(xù)補充。接下來自然就是發(fā)請求了,這里的返回類型可以設置為 blob ,使用axios直接發(fā)送。
/**
* 下載附件
* @param path 接口地址
* @param param 請求參數(shù)
*/
export function downloadAttachment(path, param) {
var url = baseUrl + path + param
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': getToken() }
}).then(res => {
resolveBlob(res, res.data.type)
})
}
接口地址和請求參數(shù)從外部傳入。同時需要攜帶token,不然會跨域訪問。拿到后端返回的數(shù)據(jù)后,需要解析二進制文件,這里定義 resolveBlob 方法,該方法有兩個參數(shù),返回對象和文件的類型,文件的類型,我們在后端已經(jīng)放入 Content-Type 中了,這里直接取。
/**
* 解析blob響應內(nèi)容并下載
* @param {*} res blob響應內(nèi)容
* @param {String} mimeType MIME類型
*/
export function resolveBlob(res, mimeType) {
const aLink = document.createElement('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 = patt.exec(contentDisposition)
var fileName = result[1]
fileName = fileName.replace(/\"/g, '')
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', fileName) // 設置下載文件名稱
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink);
}
這代碼不用多解釋了吧,前端大佬們自然看得懂。OK了啊,到這里前后端代碼都完成了。
3、使用
使用那就更簡單啦。先掛載到全局
import { downloadAttachment } from "@/utils/download"
Vue.prototype.downloadAttac = downloadAttachment
在使用的地方直接調(diào)用即可
<el-button
type="text"
icon="el-icon-download"
size="mini"
@click="downloadAttachRow(scope.row.attachmentId)"
></el-button>
/** 下載附件 */
downloadAttachRow(attachId) {
this.$confirm('是否確認下載該文件?', "警告", {
confirmButtonText: "確定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.downloadAttac('/system/attachment/download/', attachId)
}).then(() => {
this.msgSuccess("下載成功")
}).catch(() => {})
}
到此結(jié)束。
到此這篇關于Vue實現(xiàn)點擊按鈕下載文件的操作代碼(后端Java)的文章就介紹到這了,更多相關Vue點擊按鈕下載文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
crypto-js對稱加密解密的使用方式詳解(vue與java端)
這篇文章主要介紹了如何在Vue前端和Java后端使用crypto-js庫進行AES加密和解密,前端通過創(chuàng)建AES.js文件來實現(xiàn)加密解密功能,并在Vue文件或JavaScript中使用,后端則可以直接使用Java代碼進行AES加密和解密操作,需要的朋友可以參考下2025-01-01
vue通過指令(directives)實現(xiàn)點擊空白處收起下拉框
這篇文章主要介紹了vue通過指令(directives)實現(xiàn)點擊空白處收起下拉框,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12

