单文件直接下载
前端在拿到后端返回文件数据和这个数据对应的类型的时候,的时候,可以通过以下的方式来实现文件的自动下载。
这样下载的前提是返回的数据已经是正确的了(正确指的是,数据正确,例如:我们要下载一个xlsx的文件,只有返回得数据是xlsx格式的时候,才可以这样直接下载。如果返回的是json,则我们这样是没法转成xlsx的;需要借助其他工具)
(1)创建基于文件内容的Blob对象;
(2)通过URL上的createObjectURL方法,将blob对象转换成一个能被浏览器解析的文件地址。
(3)将上述的文件地址指向a标签的href,并设置a标签的download属性为要保存成的文件名。
(4)点击a标签,即可下载对应的文件。
//下载文件//content: 是数据,即文件的数据//filename:是等会生成的文件的名字;//fileType:是文件的类型function downLoadFile( content, filename, fileType) {//创建一个BLob对象,传入内容和知道的参数【后端返回的数据的类型】,下面有举例一些类型var blob = new Blob([content], { type: '数据的类型' });var a = document.getElementById('downloadFileTestBtn');if (a == undefined) {a = document.createElement('a');a.id = 'downloadFileTestBtn';a.style.display = 'none';a.target = '_blank';document.body.appendChild(a);}var URL = window.URL || window.webkitURL;a.href = URL.createObjectURL(blob);a.download = filename;if (typeof navigator.msSaveBlob == "function") { //IEnavigator.msSaveBlob(blob, filename);}a.click();}
转Blob常见的MIME类型
| 后缀 | MIME Type |
|---|---|
| .doc | application/msword |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| .xls | application/vnd.ms-excel |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| .ppt | application/vnd.ms-powerpoint |
| .pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation |
| application/pdf |
读取Blob数据
Blob相当于是一个不可变、原始数据的类文件对象。如果我们要读取这个文件的对象的话,可以使用FileRender对象的方法来实现。
具体的实现方法如下:
1.先创建一个FileReader的实例2.使用对应的读取方法3.监听读取完成,在回调里那对转换后的数据 转换后的数据存储在FileReader实例的result里面const reader = new FileReader();reader.addEventListener("loadend", function () {console.log(reader.result)});reader.readAsText(blobData, 'utf-8'); //还有很多的读取方法,具体见MDN
一个互相转化的例子:
// 定义JSON数据let data = { "name": "小明" };// 转换成字符串数组let string = JSON.stringify(data);// 转换成Blob类型数据let blobData = new Blob([string]);console.log(blobData) // 打印Blob结果: Blob { size: 17, type: "" }let reader = new FileReader(); // 创建读取文件对象reader.addEventListener("loadend", function () { //let res = JSON.parse(reader.result); // 返回的数据console.log(res,'返回结果数据') // { name: "小明" }});reader.readAsText(blobData, 'utf-8'); // 设置读取的数据以及返回的数据类型为utf-8
多sheet的xlsx文件
有一个需求就是,我们需要下载一个xlsx的文件,但是这文件里面将会包含多个sheet的表。这个实现我们就需要借助xlsx的包,来实现了。
方式一:
//这是我们的JSON数据,也就是表的数据let data1 = [{ "大区": "杭夏", "人数": '123' }, { "大区": "上合", "人数": '222' }]const wb = XLSX.utils.book_new()//注意:这里,我们使用JSON数据转化为Sheet,其他的数据还不知道如何转化const sheet1 = XLSX.utils.json_to_sheet(data1)//给wb添加两个sheet:这里两个Sheet的数据是一样的XLSX.utils.book_append_sheet(wb, sheet1, '表一')XLSX.utils.book_append_sheet(wb, sheet1, '表二')//导出wb,生成文件XLSX.writeFile(wb, 'file.xlsx')
方式二:
不使用XLSX的writeFile,而是使用我们自己在单文件下载中的方式,实现,单文件中多sheet的下载
let data1 = [{ "大区": "杭夏", "人数": '123' }, { "大区": "上合", "人数": '333' }]const wb = XLSX.utils.book_new()const sheet1 = XLSX.utils.json_to_sheet(data1)XLSX.utils.book_append_sheet(wb, sheet1, '表一')XLSX.utils.book_append_sheet(wb, sheet1, '表二')downLoadFile('file.xlsx', wb)//wb转Blobfunction wb2BLob(wb) {const wbOpts = {bootType: "xlsx",bookSST: false,type: 'binary'}const wbOut = XLSX.write(wb, wbOpts);return S2AB(wbOut)}//字符串转ArrayBufferfunction S2AB(s) {let ab = new ArrayBuffer(s.length);ab = new Uint8Array(ab)for (let i = 0; i < s.length; i++) ab[i] = s[i].charCodeAt() & 0xff;return ab}function downLoadFile(filename, content) {const t = wb2BLob(content)var blob = new Blob([t]);var a = document.getElementById('downloadFileTestBtn');if (a == undefined) {a = document.createElement('a');a.id = 'downloadFileTestBtn';a.style.display = 'none';a.target = '_blank';document.body.appendChild(a);}var URL = window.URL || window.webkitURL;a.href = URL.createObjectURL(blob);a.download = filename;if (typeof navigator.msSaveBlob == "function") { //IEnavigator.msSaveBlob(blob, filename);}a.click();}
