场景:前端需要下载后端文件,并且需要给个参数id来下载某个记录的文件
以前不带参数不用token时,可以直接用a标签调用get请求,但现在需要加参数和请求头,a标签无法实现,笔者后来采用button触发js方法,调用接口,但最后的效果就是,后端的响应流返回不到前端的浏览器!!!
所以,只能前端模拟a标签
特此记录
效果图:
一、前端代码
还是正常的按钮
<el-button @click="clickCall('handleExport', scope)">导出</el-button>
import Cookie from "js-cookie";
import axios from "axios";
import Domain from "../../../api/domain";
const URL_DOMAIN = `${Domain.domain}`;
// 文件下载操作
handleExport(row) {
axios
.get(`${URL_DOMAIN}` + "/biz/master/route/exportXml?id=" + row.id, {
responseType: "blob",
headers: { Authorization: Cookie.get("droneToken") },
})
.then((res) => {
var elink = document.createElement("a");
elink.download = "飞行路径.xml";
elink.style.display = "none";
elink.href = window.URL.createObjectURL(res.data);
elink.click();
this.$message({
type: "success",
message: "数据导出成功",
});
})
.catch((err) => {
this.$message.error(`数据导出失败,${err.message}`);
});
},
二、后端代码
Controller层
@ApiOperation("导出XML数据")
@GetMapping("exportXml")
public void exportData(HttpServletResponse response,@RequestParam(value="id")Long id) throws Exception {
routeService.exportData(response,id);
}
Service层
@Override
public void exportData(HttpServletResponse response, Long id) {
Blob blob = getXmlFile(id);
byte[] buf = new byte[1024 * 5];
try(OutputStream output = response.getOutputStream(); InputStream is = blob.getBinaryStream()){
response.reset();
//设置响应头,
response.setHeader("Content-disposition", "attachment; filename=temp.xml");
response.setContentType("application/xml");
System.out.println("输出内容");
while (is.read(buf) > 0) {
String s = new String(buf);
output.write(s.getBytes(), 0, s.length());
}
System.out.println("输出内容");
output.flush();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Blob getXmlFile(Long id) {
Connection connection = null;
PreparedStatement ps = null;
Blob blob = null;
try {
connection = new JDBCConnection().getConnection();
String sql = "select * from tb_route where id=?";
ps = connection.prepareStatement(sql);
ps.setLong(1, id);
//获取到数据库中的二进制数据
ResultSet rs = ps.executeQuery();
rs.next();
blob = rs.getBlob("file_txt");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (!connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (!ps.isClosed()) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return blob;
}