常用前端文件下载方法
经常在项目中会遇到需要下载文件的需求,根据不同的需求和项目实现情况,通常有以下几种做法。
使用a标签下载
这种情况一般是,文件放置在后端服务器中,这种下载相当于一个 get 请求,a标签属性href访问下载文件的地址,浏览器帮助进行下载。但是对于浏览器支持直接浏览的txt、png、jpg、gif等文件,点击时浏览器会直接预览文件不会直接下载(或者使用右键另存为方式下载)。
可以使用 download 属性告诉浏览器这个 a 标签不是打开页面预览而是进行下载。
注意: download 属性 仅支持 IE13 以上的版本,并且只支持同源下载链接,如果下载的文件资源跨域,则 download 属性不起作用。
// href 表示对应的请求资源的路径,download表示下载后文件的文件名
<a href="http://localhost:3000/test.xlsx" download="test.xlsx">
点击下载
</a>;
使用window.open()或者location.href
使用方法与 a标签类似,利用浏览器帮助下载文件,对于浏览器支持预览的文件类型无法下载。
window.open("http://localhost:3000/test.xlsx");
location.href = "http://localhost:3000/test.xlsx";
使用Blob对象下载
利用Blob对象可以将文件流转化成Blob二进制对象。
为了避免直接打开问题,在解决了跨域问题的前提下(如Nginx),可以直接通过请求的方式拿到文件流,将文件流转为Blob格式,再通过a标签的download属性下载。
Blob解决下载问题还有一个场景是,如果后端无法提供一个文件下载地址,而是从接口返回文件二进制流,也可以使用这个方法。
以下新建Node应用,模拟后端接口返回二进制流的情况
const http = require("http");
const fs = require("fs");
// 创建服务
const server = http.createServer((req, res) => {
// 下载接口
if (req.url === "/download") {
res.writeHead(200, {
"Content-type": "application/vnd.ms-excel", // 返回excel文件
// 跨域设置
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "content-type",
});
// 异步读取文件内容
fs.readFile("test.xlsx", (err, data) => {
// 返回二进制流文件
res.end(data);
});
}
});
// 服务启动在3000端口
server.listen(3000);
console.log("server run at 3000");
前端调用接口拿到返回数据后,转化为Blob对象,利用URL.createObjectUrl生成url地址,赋值在a标签的href属性上,结合download进行下载。
.then(resp=>{
resp.blob().then(
blobRes=>{
// 用返回二进制数据创建一个Blob实例
const blob = new Blob([blobRes], {
type: "type: `application/octet-stream` ",
})
// 通过URL.createObjectURL生成文件路径
const url = window.URL.createObjectURL(blob)
// 创建a标签
const a = document.createElement("a")
document.body.appendChild(a);
a.style = "display: none";
// 设置href属性为文件路径,download属性可以设置文件名称
a.href = url;
a.download = "test.xlxs";
a.click()
document.body.removeChild(a);
},
()=>{
throw new Error("下载失败")
}
)
})
前端生成 excel 文件
有时项目中会出现大量 Table 表格展示数据的情况,需要导出当前 Table中的数据生成 Excel文件,也可以选择前端生成 excel 文件的方式。
注意:简单的列表数据导出Excel文件可以使用这个方法,但是使用这个方法导出的文件无法调整文件样式。
需要先引入 “js-export-excel”这个库
npm install js-export-excel
js-export-excel 基本使用:
// 直接引入文件
import ExportJsonExcel from "js-export-excel";
const download = () => {
// 新建 Excel 文件实例
var option = {};
// 设置 Excel 文件名,默认自带xlsx后缀
option.fileName = 'excel';
/*多个sheet*/
/*每个sheet为datas中的一个object */
option.datas = [
{
// Table中的数据数组
sheetData: [
{ one: '一行一列', two: '一行二列' },
{ one: '二行一列', two: '二行二列' },
],
// sheet名字
sheetName: 'sheet',
// 列数据过滤,按顺序表格列显示对应属性名下的数据。
// 只有在 data 为 Array<object> 下起作用,可不传
sheetFilter: ['one', 'two'],
// 第一行 表头数据
sheetHeader: ['第一列', '第二列'],
// number 列宽 需与列顺序对应,屏幕宽度为100 20即为 1/5屏幕大小
columnWidths: [20, 20],
},
{
sheetData: [
{ one: '一行一列', two: '一行二列', three: '一行三列' },
{ one: '二行一列', two: '二行二列', three: '二行三列' },
],
sheetName: 'sheet1',
sheetFilter: ['one', 'one','three'],
sheetHeader: ['第一列', '第二列', '第三列'],
columnWidths: [20, 20, 20],
},
];
var toExcel = new ExportJsonExcel(option); //new
toExcel.saveExcel(); //下载保存文件
};
导出 excel 文件如图所示: