当前位置:   article > 正文

javascript下载纯文本、下载Excel,前端解析Excel,下载的Excel无法打开问题解决_前端下载文件流无法打开

前端下载文件流无法打开

js支持下载xml至本地

const downloadContentFile = (filename, text) => {
  const element = document.createElement('a');
  element.setAttribute('href', `data:text/plain;charset=utf-8,${encodeURIComponent(text)}`);
  element.setAttribute('download', filename);
  element.style.display = 'none';
  element.click();
  element.remove();
} ;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

js读取后端返回文件流内容

//新建一个fileReader
let reader = new FileReader();
//执行读文件的函数,设置编码格式
reader.readAsText(file, "UTF-8");
//读取文件中的内容
reader.onload = function (e) {
    const content = e.target.result;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

后端返回Excel文件流(blob),下载excel

由于后端返回的是csv文件(例如模板.csv)Excel文件为csv后缀,所以new Blob([text], { type: "application/vnd.ms-excel" })

  • 读取后端返回的blob文件流信息
const getContentFile = (file) => {
 console.log("file", file);
  //新建一个fileReader
  let reader = new FileReader();
  //执行读文件的函数,设置编码格式
//Excel,需要将文件转为blob或文件流
  reader.readAsArrayBuffer(file, "UTF-8");
  //读取文件中的内容
  reader.onload = function (e) {
    const content = e.target.result;
    console.log("content", content);
    downloadContentFile(file.name, content);
  };
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 将文件内容生成URL放置标签a中下载
 const downloadContentFile = (filename, text) => {
  let blob = new Blob([text], { type: "application/vnd.ms-excel" });
  const element = document.createElement("a");
 const href = URL.createObjectURL(blob);
  element.href = href;
  element.setAttribute("download", filename);
  element.style.display = "none";
  element.click();
  //调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。
  URL.revokeObjectURL(href);
  element.remove();
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

下载Excel遇到的问题

  • 前端下载Excel无法打开
    可以看到后端返回的Excel类型
    在这里插入图片描述

后端返回Excel文件(blob)的借口

export const downloadTemplate = () => {
  return instance({
    method: "GET",
    url: "/api/common/template",
    responseEncoding: "utf8"
  });
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以看到返回的数据一串乱码
在这里插入图片描述

在这里插入图片描述

解决:请求时添加·responseType: "blob"


export const downloadTemplate = () => {
  return instance({
    method: "GET",
    url: "/api/basic/temp",
    responseType: "blob",
    responseEncoding: "utf8"
  });
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

可以看到返回的数据时blob
在这里插入图片描述

前端上传Excel文件解析内容展示到table中

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

安装依赖

npm install xlsx
  • 1
XLSX.utils.sheet_to_json(workbook.Sheets[sheet])
  • 1
sheet_to_json<T>(worksheet: WorkSheet, opts?: Sheet2JSONOpts): T[];
  • 1
export interface Sheet2JSONOpts extends DateNFOption {
    /** Output format */
    header?: "A"|number|string[];

    /** Override worksheet range */
    range?: any;

    /** Include or omit blank lines in the output */
    blankrows?: boolean;

    /** Default value for null/undefined values */
    defval?: any;

    /** if true, return raw data; if false, return formatted text */
    raw?: boolean;

    /** if true, skip hidden rows and columns */
    skipHidden?: boolean;

    /** if true, return raw numbers; if false, return formatted numbers */
    rawNumbers?: boolean;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

解析xlsx文件封装函数,带入参数

const excelColumn = [
  "A",
  "B",
  "C",
  "D",
  "E",
  "F",
  "G",
  "H",
  "I",
  "J",
  "K",
  "L",
  "M",
  "N",
  "O",
  "P",
  "Q",
];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
let XLSX = require("xlsx");

export const readfileByExcel = async (file) => {
  return new Promise((resolve, reject) => {
    let fileReader = new FileReader();
    fileReader.onload = function (event) {
      let workbook;
      let result = []; // 存储获取到的数据
      try {
        let data = event.target.result;
        workbook = XLSX.read(data, {
          type: "binary", // 以二进制流方式读取得到整份excel表格对象
        });
      } catch (e) {
        reject(e);
        return;
      }
      const sheet2JSONOpts = {
        header: excelColumn,
        defval: "",
      };

      // 遍历每张表读取
      for (let sheet in workbook.Sheets) {
        if (workbook.Sheets.hasOwnProperty(sheet)) {
          result = result.concat(
            XLSX.utils.sheet_to_json(workbook.Sheets[sheet], sheet2JSONOpts)
          );
          break; // 如果只取第一张表,就取消注释这行
        }
      }
      resolve(result);
    };

    // 以二进制方式打开文件
    fileReader.readAsBinaryString(file);
  });
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
const sheet2JSONOpts = {
  header: excelColumn,
  defval: "",
};
  • 1
  • 2
  • 3
  • 4

可以看出返回的结果

  • 每一行一个数组元素返回,第一行表头也会返回
  • 数组的索引为指定传入的参数,value值为单元格内容

在这里插入图片描述

注明(此处无关紧要):数组最后一个元素都是空值,是因为导入的excel表里面最后一行有元素,但是是空值,后面默认情况下那样空值一行是因为改例子把模板的最后一行删除了

默认

for (let sheet in workbook.Sheets) {
 if (workbook.Sheets.hasOwnProperty(sheet)) {
   result = result.concat(
     XLSX.utils.sheet_to_json(workbook.Sheets[sheet])
   );
   break; // 如果只取第一张表,就取消注释这行
 }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以看出结果

  • 每一行一个数组元素返回,第一行表头不会返回
  • 数组的索引为表头单元格内容,value值为单元格内容
    在这里插入图片描述

前端实现将一个字符串在浏览器中预览并且下载至本地log.txt

前端将字符串内容下载至本地

export const downloadContentFile = (filename, text) => {
  const element = document.createElement('a');
  element.setAttribute('href', `data:text/plain;charset=utf-8,${encodeURIComponent(text)}`);
  element.setAttribute('download', filename);
  element.style.display = 'none';
  element.click();
  element.remove();
} ;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

前端支持将字符串文本内容生成URL在浏览器中预览

//假设,与后文截图无关
const context = “\n hello world \n this is pencil”
  • 1
  • 2
const url =  URL.createObjectURL(new Blob([context], { type: 'text/plain }));
window.open(url);
  • 1
  • 2

在这里插入图片描述
可以看到,在浏览中打开,中文符号会乱码

解决在浏览器中打开中文符号乱码问题

const url =  URL.createObjectURL(new Blob([context], { type: 'application/json;charset=UTF-8' }));
window.open(url);
  • 1
  • 2

或者

const url =  URL.createObjectURL(new Blob([item?.shellLog], { type: 'text/plain;charset=UTF-8' }));
window.open(url);
  • 1
  • 2

在这里插入图片描述

后端返回URL,前端点击下载

同源

 function download(url, filename){
      const elelink = document.createElement("a");
      elelink.style.display = 'none';
      elelink.target = '_blank';
      elelink.href = url;
      elelink.download = filename;
      document.body.appendChild(elelink);
      elelink.click();
      document.body.removeChild(elelink);
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

直接将url赋值

window.location.href= url;
  • 1

使用href 的下载地址 和 当前网站地址 必须是 同源的,否则download不生效。

不同源

export const downloadUrl = (url, filename) => {
  const x = new window.XMLHttpRequest();
  x.open('GET', url, true);
  x.responseType = 'blob';
  x.onload = () => {
    const url = window.URL.createObjectURL(x.response);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    a.click();
  };
  x.send();
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/144988?site
推荐阅读
相关标签
  

闽ICP备14008679号