理解
无论是上传还是下载,对前端来说,都是对数据流进行操作。
常见情况包括:
- 1、前端使用 input type=‘file’ 标签进行文件读取 获取到file对象这种类型的数据流,将其传给接口
- 2、前端使用html2canvas等插件进行截图,拿到的是生成后保存在内存中base64编码的二进制数据流, 此时需要根据接口的要求转成对应格式的数据在上传保存。
- 3.后台返回文件地址 前端访问地址进行文件下载
- 大部分情况下文件上传后台要求的都是formData对象的格式
文件上传案例
data(){
return {
filename:'',
inputFilee:'',
uploaded:false,
}
},
methods: {
// 选择文件
chooseFile(){
this.inputFilee = document.createElement('input');
this.inputFilee.type = 'file';
this.inputFilee.addEventListener('change', this.chang);
// 只允许excel文件
this.inputFilee.accept = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel';
this.inputFilee.click();
},
chang(){
this.filename = this.inputFilee.files[0].name;
},
// 点击上传 待补全
upload(){
if(this.inputFilee===''){
this.$message.error('请选择文件')
return
}
// formData.append("uploadFile",this.inputFilee.files[0])
// http.getFileUrl(`/ufile/upload/img`,formData).then(res => {
// if(res.errCode==='00'){
// this.uploaded = true;
// this.filename = '';
// this.inputFilee = '';
// }
// })
this.uploaded = true;
this.filename = '';
this.inputFilee = '';
},
// 重新上传
reUpload(){
this.uploaded = false;
},
},
html2canv生成图片上传案例
//文件上传完成后 上传后台文件服务器返回的文件地址链接
submit(){
this.write_title_img_url = await this.base64ImgtoFile(await this.createImg('printContent'));
},
methods: {
async createImg(whichOne){
return new Promise(resolve=>{
let view = document.getElementById(whichOne);
let iframe = view.children[0].children[0].getElementsByClassName('edui-editor-iframeholder edui-default')[0].children[0].contentWindow.document;
// await this.$nextTick();// this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行
resolve(this.makeImg(iframe.getElementsByClassName('view')[0].children[1].children[0]))
})
},
//插件截图
makeImg(printContent){
return new Promise(resolve=>{
html2canvas(printContent, {
scale: 2,
dpi: 2000,
height: printContent.clientHeight + 5, // dom 原始宽度
width: printContent.clientWidth + 5, // dom 原始宽度
scrollY: 0, // 偏移值
scrollX: 0,
useCORS: true// 跨域
}).then(canvas => {
let dataURL = canvas.toDataURL('image/png');
resolve(dataURL);
}).catch(err => {
console.log(err);
});
})
},
// 工具函数 base64转换
async base64ImgtoFile(data) {
return new Promise(resolve=>{
var form=document.forms[0];
var formData = new FormData(form);
let filename = this.revtimeToString(new Date)+'.png'
var arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
let file = new File([u8arr], filename, {type:mime});
formData.append("uploadFile",file)
http.getFileUrl(`........后台地址`,formData).then(res => {
resolve(res.data)
})
})
},
},
提出下载报表数据的需求,且有格式要求.
数据处理原理与之前一样,根据需求修改逻辑即可.以下是关于JS文件下载的学习:(直接下载页面数据,无需调用后台)
var result = ["张三","李四","王五"];//处理好的要下载的数据集result
var blob = new Blob(["\ufeff" + result.join("")], {type: 'text/csv'}); // ufeff解决乱码问题
var downloadLink = document.createElement("a");
downloadLink.setAttribute("href", URL.createObjectURL(blob));// 字符内容转变成blob地址
//下面设置文件名 点击触发后移除
var fileName="测试";
fileName=fileName.replace(new RegExp(">>", "g"),".");
fileName+="."+CurentTime()+".csv";
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
Blob对象简要介绍
Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 Blob 的功能并将其扩展使其支持用户系统上的文件。
语法
const aBlob = new Blob( array, options );
参数说明
array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。
options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:
type,默认值为 “”,它代表了将会被放入到blob中的数组内容的MIME类型。
endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: “native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持blob中保存的结束符不变
URL.createObjectURL() 与介绍
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。相当于这个方法创建了一个传入对象的内存引用地址
参考原理剖析:前端通过Blob实现文件下载
参考流程:JS知识点:文件下载
项目常用方式:
压缩包,word文件等普通下载
preview(url) {
// window.open(url);
let a = document.createElement("a");
a.style.display = "none";
a.target = "_blank";
document.body.appendChild(a);
a.href = url;
a.setAttribute("download", "link"); // 指示浏览器下载url,而不是导航到它
a.click();
document.body.removeChild(a);
},
图片 音频等会被浏览器直接打开的下载:
downloadFile(url,name){
var a = document.createElement('a');
// 先将地址转化为二进制
var blob = new Blob([url]);
a.href = URL.createObjectURL(blob);
// 剪切链接字符串最后的文件名称
// debugger
a.download = name;
a.click();
document.body.removeChild(a);
},
// 批量下载
downloadFile(url){
const iframe = document.createElement("iframe");
iframe.style.display = "none"; // 防止影响页面
iframe.style.height = 0; // 防止影响页面
iframe.src = url;
document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求
// 5分钟之后删除(onload方法对于下载链接不起作用,就先抠脚一下吧)
setTimeout(()=>{
iframe.remove();
}, 5 * 60 * 1000);
},
bulkDownload(urlList){
let jsonUrlList = JSON.parse(urlList);
let that = this;
for(let i =0;i<jsonUrlList.length;i++){ //循环遍历调用downloadFile方法
const url = jsonUrlList[i].response.msg;
this.downloadFile(url);
}
},