【React】上传下载CSV文件

参考文章

1、react下 antd js前端实现在线解析csv文件
2、导出数据生成csv文件,以及导入csv文件读取数据
3、React读取Excel——js-xlsx 插件的使用

1、引入npm包

//引入生成csv文件的插件
import FileSaver from 'file-saver';
//引入根据csv文件生成数据插件
import Papa from "papaparse";
import jschardet from "jschardet";
import iconv from "iconv-lite";
import encoding from "encoding";

2、下载模板生成csv文件

  // 点击下载模板生成csv文件
  handleDownloadTemplate = () => {
    //拿到所有的数据
    let data = [{
      "orderId": 1234567890,
      "passager": "小明"
    }];
    //定义数据拼接
    //str:table的每一列的标题,即为导出后的csv文件的每一列的标题
    let str = '号码' + ',' + '姓名';
    //通过循环拿出data数据源里的数据,并塞到str中
    for (const i in data) {
      //如果是第一行,不换行
      str += '\n' + data[i].orderId + ',' + data[i].passager
    }
    //Excel打开后中文乱码添加如下字符串解决
    let exportContent = "\uFEFF";
    let blob = new Blob([exportContent + str], {
      type: "text/plain;charset=utf-8"
    });
    //根据数据生成生成文件
    FileSaver.saveAs(blob, "template.csv");
  };

3、读取csv文件解析

/**
   * 解析上传的CSV文件得到数据,然后在根据callback方法对数据进行处理
   */
  parseUploadCSVData = (file, callback) => {
    const fReader = new FileReader();
    fReader.readAsBinaryString(file);
    fReader.onload = (event) => { // 读取文件成功
      let fileBuf = event.target.result;
      const encodeType = jschardet.detect(fileBuf).encoding;
      if (encodeType !== "UTF-8") {
        fileBuf = encoding.convert(fileBuf, "utf8", encodeType);
      }
      iconv.skipDecodeWarning = true;
      const textData = iconv.decode(fileBuf, "utf8");
      //papaparse.js 用来解析转换成二维数组
      Papa.parse(textData, {
        encoding: "UTF-8",
        complete: function (results) {  // UTF8 \r\n与\n混用时有可能会出问题
          let csvDataOri = results.data;
          console.log("csvDataOri", csvDataOri);
          const csvDataSize = csvDataOri.length;
          let validData = [];
          let errorFlag = false;
          for (let index = 1; index < csvDataSize; index++) {
            let item = csvDataOri[index];
            // 校验一行数据中,如果只有一个字段且全为空格,则略过。
            if (item.length == 1 && item[0].match(/^[ ]*$/)) {
              continue;
            } else if ((item.length == 1 && !item[0].match(/^[ ]*$/)) || item.length > 2) {
              // 校验一行数据中,如果只有一个字段且不全为空格、或者有大于两个字段,则格式错误。
              notification.error({ message: 'csv文件格式错误', description: "第" + index + "行数据格式错误。请输入并用" + ",隔开" });
              errorFlag = true;
              break;
            } else {
              // 此时一行数据只有两个字段
              let orderID = item[0].replace(/^\s+|\s+$/g, "");
              let passenger = item[1].replace(/^\s+|\s+$/g, "");
              // 校验一行数据中,第一个字段是否为纯数字。
              let isNum = /^\d+$/.test(orderID)
              if (isNum) {
                let lineData = { orderID: orderID, passenger: passenger };
                validData.push(lineData);
              } else {
                notification.error({ message: 'csv文件格式错误', description: "第" + index + "行数据格式错误。号必须为纯数字" });
                errorFlag = true;
                break;
              }
            }
          }
          console.log("validData", validData);
          let resultData = [];
          if (errorFlag == false) {
            resultData = validData;
          }
          if (resultData.length == 0) {
            notification.error({ message: 'csv文件中没有有效的数据,请确认后重新导入' });
          } else {
            notification.info({ message: '开始处理数据,请稍候...' });
            callback(resultData);
          }
        }
      });
    }
  }

你可能感兴趣的:(React,react)