上一篇写了上传文件,这一篇接着来一个下载导出的案例
下载Excel文件的一个核心逻辑,需要你自己构建一个函数,如下方downloadGridData
,下面是原理:
- 获取后端传递来的二进制数据流
- 传递到封装的函数当中,需要传递二进制数据和文件名
- 将二进制数据流包裹成一个new Blob对象
- 将Blob对象转化为一个URL资源地址,这个地址时一个本地地址
- 创建一个a标签,设置隐藏,添加下载属性,添加到body当中,启动下载
- 下载完毕之后,删除a标签;
注意事项:
在vue框架当中,数据请求是借助axios的,为此,在发送请求的时候,需要修改responseType,改为arraybuffer,axios默认情况下responseType为json,若是不修改,很可能下载时候会是乱码,或者为null,还需注意很多项目中对axios进行了封装拦截返回一直导致获取不到返回的数据这个一点也各位也要注意;
下方提供两个案例:
- 案例1
- 前端
downloadGridData: function () {
var _this = this
_this.$http({
method: 'get',
url: '/proxy/api/v1/disk/testDownload',
data: {},
headers: {
'Content-Type': 'application/json',
'debug': 1,
},
responseType:"blob",
}).then(response => {
let blob = new Blob([response.data], {type: 'application/vnd.ms-excel'})
let dateTime = new Date()
let dateTimeStr = dateTime.getFullYear() + '-' + dateTime.getMonth() + '-' + dateTime.getDay()
let filename = '意向患者-' + dateTimeStr + '_' + new Date().getTime() + '.xls'
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename)
} else {
var blobURL = window.URL.createObjectURL(blob)// 将blob对象转为一个URL
var tempLink = document.createElement('a')// 创建一个a标签
tempLink.style.display = 'none'
tempLink.href = blobURL
tempLink.setAttribute('download', filename)// 给a标签添加下载属性
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank')
}
document.body.appendChild(tempLink)// 将a标签添加到body当中
tempLink.click()// 启动下载
document.body.removeChild(tempLink)// 下载完毕删除a标签
window.URL.revokeObjectURL(blobURL)
}
}).catch((error) => {
//
console.log(error)
})
},
- 后端
public void orderDownload(@RequestBody OrderProductsReq req,
HttpServletResponse response) {
String orderToStr = dateToStr(req.getOrderTo() == null ? null : req.getOrderTo());
String orderFromStr = dateToStr(req.getOrderFrom() == null ? null : req.getOrderFrom());
//----------------处理文件名--------------------
String fromTempStr = orderFromStr == null ? "最开始" : orderFromStr;
String toTempStr = orderToStr == null ? "现在" : orderToStr;
String fileName = fromTempStr+"-"+toTempStr+"意向记录:" + System.currentTimeMillis();
//-------------------------------------------------
try {
response.setHeader("Content-type", "application/vnd.ms-excel");
// 解决导出文件名中文乱码
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
orderProductsService.orderDownload(req,response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
//数据写入流部分代码
List<OrderProductsQueryRes> rowList = result.getResult();
// 1.创建Excel工作薄对象
Workbook wb = new XSSFWorkbook();
// 2.创建Excel工作表对象
Sheet sheet = wb.createSheet("意向患者");
//3.将数据写入sheet
bulidFirstSheet(sheet, rowList);
try {
//4.将Excel写入到输出流里面
wb.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
wb.close();
outputStream.close();
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
- 案例2
- 前台: 文件名可以通过response.headers获取设置或者在前端处理
downloadGridData: function () {
var _this = this
this.$http.post(_this.$host + 'admin_product_order_manage/orderListDownload', _this.search, {responseType: 'arraybuffer'}
).then(response => {
let blob = new Blob([response.data], {type: 'application/vnd.ms-excel'})
let dateTime = new Date()
let dateTimeStr = dateTime.getFullYear() + '-' + dateTime.getMonth() + '-' + dateTime.getDay()
let filename = '意向患者-' + dateTimeStr + '_' + new Date().getTime() + '.xls'
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename)
} else {
var blobURL = window.URL.createObjectURL(blob)// 将blob对象转为一个URL
var tempLink = document.createElement('a')// 创建一个a标签
tempLink.style.display = 'none'
tempLink.href = blobURL
tempLink.setAttribute('download', filename)// 给a标签添加下载属性
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank')
}
document.body.appendChild(tempLink)// 将a标签添加到body当中
tempLink.click()// 启动下载
document.body.removeChild(tempLink)// 下载完毕删除a标签
window.URL.revokeObjectURL(blobURL)
}
}).catch((error) => {
//
console.log(error)
})
}
- 后端同上