插件

171 阅读1分钟

文件导入导出

插件: file-saver-npm github

 // .text .json
 // 导出
 const fileType  = {
     text: "text/plain;charset=utf-8",
     json:  "application/json"
 }
 const blob = new Blob([JSON.stringify(data)], {type:fileType[xxx] });
 saveAs(blob, "test.json");
 
 // 导入
 const beforeUpload = (file, fileList) => {
    return new Promise((resolve, reject) => {
      var reader = new window.FileReader();
      reader.readAsText(file);
      reader.onload = async function(e) {
        const importJson = e.target.result;
        JSON.parse(importJson);
      };
      reject();
    });
  };
 <Upload accept="application/json" beforeUpload>导入</Upload>   //AntDesign
 // .excel
   // 导出
    import XLSX from 'xlsx';
  // jsonList = [{name:'Li', age: 3 }]
  // sortTitle {name:'姓名', age: '年龄' }
  export const exportExcel = (jsonList, sortTitle, fileName) => {
    // 数据表格
    const table = [{ ...sortTitle }, ...jsonList];
    // 创建book
    const wb = XLSX.utils.book_new();
    const titles = Object.getOwnPropertyNames(sortTitle);
    // json转sheet
    const ws = XLSX.utils.json_to_sheet(table, {
        header: titles,
        skipHeader: true,
    });
    // 设置列宽
    ws['!cols'] = Array(titles.length).fill({ width: 20 });
    // sheet写入book
    XLSX.utils.book_append_sheet(wb, ws, 'file');
    // 下载
    XLSX.writeFile(wb, `${fileName || `表${new Date().getTime()}`}.xlsx`);
  };


// 导入
 import XLSX from 'xlsx';
 // 转化excel数据
const transImportList = list => {
  const [keys, ...values] = list;
  return values.reduce((acc, val) => {
    const entries = keys.map((k, idx) => ([
      k.replace(/\s+/g, ''),
      val[idx].toString().replace(/\s+/g, '')
    ]));
    const rs = Object.fromEntries(entries);
    return acc.concat(rs)
  }, [])
}

export default function UploadExcel({
  text = '上传文件',
  size,
  onChange,
  disabled
}) {
  const [{ isLoading }, setState] = useSetState({
    isLoading: false,
  });

  const beforeUpload = file => {
    setState({ isLoading: true });
    const reader = new FileReader();
    const isCsv = file.type === 'text/csv'
    if (isCsv) {
      reader.readAsText(file, 'gb2312');
    } else {
      reader.readAsBinaryString(file);
    }

    reader.onerror = () => {
      message.error('文件读取失败,请重试');
      setState({ isLoading: false });
    };

    reader.onload = e => {
      try {
        const data = e.target.result;
        let jsonArr = [];
        let lastSheetName = '';
        // csv
        if (isCsv) {
          jsonArr = data.split(/\n/).map(m => m.split(','));
        } else {
          // xlsx
          const workbook = XLSX.read(data, { type: 'binary' });
          lastSheetName = workbook.SheetNames.pop();
          const first_worksheet = workbook.Sheets[lastSheetName]; // 拿最后一个sheet的内容
          jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 }); // 转成array
        }

        const list = transImportList(jsonArr);
        const name = `${file.name}_${lastSheetName}`;
        onChange(list, name);
      } catch (err) {
        console.log(err);
        message.error('文件解析失败,请确认文件内容');
      } finally {
        setState({ isLoading: false });
      }
    };
    return false;
  }


  return (
    <Upload
      name="file"
      fileList={[]}
      accept=".csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      disabled={isLoading}
      beforeUpload={beforeUpload}
    >
      <Button
        disabled={disabled}
        size={size}
        loading={isLoading}
        icon="upload"
        type="primary"
      >
        {text}
      </Button>
    </Upload >
  )
}

 ps: 参考 
 https://www.cnblogs.com/cynthia-wuqian/p/14153997.html
 https://blog.csdn.net/qq_29698805/article/details/111183326