单文件直接下载

前端在拿到后端返回文件数据和这个数据对应的类型的时候,的时候,可以通过以下的方式来实现文件的自动下载。
这样下载的前提是返回的数据已经是正确的了(正确指的是,数据正确,例如:我们要下载一个xlsx的文件,只有返回得数据是xlsx格式的时候,才可以这样直接下载。如果返回的是json,则我们这样是没法转成xlsx的;需要借助其他工具)
(1)创建基于文件内容的Blob对象;
(2)通过URL上的createObjectURL方法,将blob对象转换成一个能被浏览器解析的文件地址。
(3)将上述的文件地址指向a标签的href,并设置a标签的download属性为要保存成的文件名。
(4)点击a标签,即可下载对应的文件。

  1. //下载文件
  2. //content: 是数据,即文件的数据
  3. //filename:是等会生成的文件的名字;
  4. //fileType:是文件的类型
  5. function downLoadFile( content, filename, fileType) {
  6. //创建一个BLob对象,传入内容和知道的参数【后端返回的数据的类型】,下面有举例一些类型
  7. var blob = new Blob([content], { type: '数据的类型' });
  8. var a = document.getElementById('downloadFileTestBtn');
  9. if (a == undefined) {
  10. a = document.createElement('a');
  11. a.id = 'downloadFileTestBtn';
  12. a.style.display = 'none';
  13. a.target = '_blank';
  14. document.body.appendChild(a);
  15. }
  16. var URL = window.URL || window.webkitURL;
  17. a.href = URL.createObjectURL(blob);
  18. a.download = filename;
  19. if (typeof navigator.msSaveBlob == "function") { //IE
  20. navigator.msSaveBlob(blob, filename);
  21. }
  22. a.click();
  23. }

转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
.pdf application/pdf

读取Blob数据

Blob相当于是一个不可变、原始数据的类文件对象。如果我们要读取这个文件的对象的话,可以使用FileRender对象的方法来实现。
具体的实现方法如下:

  1. 1.先创建一个FileReader的实例
  2. 2.使用对应的读取方法
  3. 3.监听读取完成,在回调里那对转换后的数据 转换后的数据存储在FileReader实例的result里面
  4. const reader = new FileReader();
  5. reader.addEventListener("loadend", function () {
  6. console.log(reader.result)
  7. });
  8. reader.readAsText(blobData, 'utf-8'); //还有很多的读取方法,具体见MDN

一个互相转化的例子:

  1. // 定义JSON数据
  2. let data = { "name": "小明" };
  3. // 转换成字符串数组
  4. let string = JSON.stringify(data);
  5. // 转换成Blob类型数据
  6. let blobData = new Blob([string]);
  7. console.log(blobData) // 打印Blob结果: Blob { size: 17, type: "" }
  8. let reader = new FileReader(); // 创建读取文件对象
  9. reader.addEventListener("loadend", function () { //
  10. let res = JSON.parse(reader.result); // 返回的数据
  11. console.log(res,'返回结果数据') // { name: "小明" }
  12. });
  13. reader.readAsText(blobData, 'utf-8'); // 设置读取的数据以及返回的数据类型为utf-8

多sheet的xlsx文件

有一个需求就是,我们需要下载一个xlsx的文件,但是这文件里面将会包含多个sheet的表。这个实现我们就需要借助xlsx的包,来实现了。
方式一:

  1. //这是我们的JSON数据,也就是表的数据
  2. let data1 = [{ "大区": "杭夏", "人数": '123' }, { "大区": "上合", "人数": '222' }]
  3. const wb = XLSX.utils.book_new()
  4. //注意:这里,我们使用JSON数据转化为Sheet,其他的数据还不知道如何转化
  5. const sheet1 = XLSX.utils.json_to_sheet(data1)
  6. //给wb添加两个sheet:这里两个Sheet的数据是一样的
  7. XLSX.utils.book_append_sheet(wb, sheet1, '表一')
  8. XLSX.utils.book_append_sheet(wb, sheet1, '表二')
  9. //导出wb,生成文件
  10. XLSX.writeFile(wb, 'file.xlsx')

方式二:
不使用XLSX的writeFile,而是使用我们自己在单文件下载中的方式,实现,单文件中多sheet的下载

  1. let data1 = [{ "大区": "杭夏", "人数": '123' }, { "大区": "上合", "人数": '333' }]
  2. const wb = XLSX.utils.book_new()
  3. const sheet1 = XLSX.utils.json_to_sheet(data1)
  4. XLSX.utils.book_append_sheet(wb, sheet1, '表一')
  5. XLSX.utils.book_append_sheet(wb, sheet1, '表二')
  6. downLoadFile('file.xlsx', wb)
  7. //wb转Blob
  8. function wb2BLob(wb) {
  9. const wbOpts = {
  10. bootType: "xlsx",
  11. bookSST: false,
  12. type: 'binary'
  13. }
  14. const wbOut = XLSX.write(wb, wbOpts);
  15. return S2AB(wbOut)
  16. }
  17. //字符串转ArrayBuffer
  18. function S2AB(s) {
  19. let ab = new ArrayBuffer(s.length);
  20. ab = new Uint8Array(ab)
  21. for (let i = 0; i < s.length; i++) ab[i] = s[i].charCodeAt() & 0xff;
  22. return ab
  23. }
  24. function downLoadFile(filename, content) {
  25. const t = wb2BLob(content)
  26. var blob = new Blob([t]);
  27. var a = document.getElementById('downloadFileTestBtn');
  28. if (a == undefined) {
  29. a = document.createElement('a');
  30. a.id = 'downloadFileTestBtn';
  31. a.style.display = 'none';
  32. a.target = '_blank';
  33. document.body.appendChild(a);
  34. }
  35. var URL = window.URL || window.webkitURL;
  36. a.href = URL.createObjectURL(blob);
  37. a.download = filename;
  38. if (typeof navigator.msSaveBlob == "function") { //IE
  39. navigator.msSaveBlob(blob, filename);
  40. }
  41. a.click();
  42. }