React實現excel導入導出

說實話 公司 閒着很無聊 不知道幹嗎 寫寫博客記錄一下html

1、環境搭建

環境搭建暫時很少說本人是使用本身的簡易腳手架搭建的,與excel無關的代碼不少,建議你們仍是使用本身搭建的腳手架好一點。這是個人github項目地址掘金Demo。自行百度create-react-app等官方推薦的腳手架吧。這裏只對excel核心功能進行講解。react

2、excel導入

1.新建tsx文件

其實本人不太熟悉ts,因此對於tsx就當作樂呵樂呵。空有ts的後綴,其實是js(語法)。總共就一個頁面,頁面地址tsx文件git

2.引用antd部分組件

爲了簡潔大方明瞭 咱們這裏直接引用了antd的部分組件github

import { Button,Table,Upload } from 'antd';

<Upload {...uploadProps}>
    <Button type="primary" >Excel導入</Button>
</Upload>

<Button type="primary" onClick={this.handleExportAll}>Excel導出數據</Button>

<Button type="primary" onClick={this.handleExportDocument}>Excel導出格式文件</Button>

<Table columns={columns} dataSource={data} bordered></Table>
複製代碼

3.核心插件xlsx介紹

1.安裝

npm install xlsx --save-dev
複製代碼

2.使用api介紹

1.XLSX.read(data,type)

嘗試解析data數據 解析的類型
複製代碼

2.workbook.Sheets[workbook.SheetNames[0]]

是工做簿中的工做表的有序列表
複製代碼

3.XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });

將工做簿對象轉換爲JSON對象數組
複製代碼

更多api可查看 xlsx git 官網npm

3.導入實現

1.首先react render部分寫入antd組件

/*組件部分*/
<Upload {...uploadProps}>
    <Button type="primary" >Excel導入</Button>
</Upload>
複製代碼
/*js部分*/
const uploadProps={
    onRemove: file => {
        this.setState(state => ({
            data:[],
            fileList:[]
        }));
    },
    accept: ".xls,.xlsx,application/vnd.ms-excel",
    beforeUpload: (file) => {
        const _this=this;
        const f = file;
        const reader = new FileReader();
        reader.onload = function (e) {
        const datas = e.target.result;
        const workbook = XLSX.read(datas, {
            type: 'binary'
        });//嘗試解析datas
        const first_worksheet = workbook.Sheets[workbook.SheetNames[0]];//是工做簿中的工做表的有序列表
        const jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });//將工做簿對象轉換爲JSON對象數組
         _this.handleImpotedJson(jsonArr, file);
        };
        reader.readAsBinaryString(f);
        return false;
    },
    fileList,
};
複製代碼
  1. onRemove是當移除文件時觸發的操做,這裏的操做就是清除數據。
  2. accept是接受上傳的文件類型。
  3. beforeUpload是上傳文件以前的鉤子,參數爲上傳的文件,若返回 false 則中止上傳,此處只是進行數據的轉化,沒有真實上傳。
  4. fileList是文件列表。

更多api請看antd upload官網json

2.核心代碼理解

總共就那麼幾行api

const f = file;
const reader = new FileReader();
reader.onload = function (e) {
    const datas = e.target.result;
    const workbook = XLSX.read(datas, {
        type: 'binary'
    });//嘗試解析datas

    const first_worksheet = workbook.Sheets[workbook.SheetNames[0]];//是工做簿中的工做表的有序列表
    const jsonArr = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });//將工做簿對象轉換爲JSON對象數組
    _this.handleImpotedJson(jsonArr, file);
};
reader.readAsBinaryString(f);
複製代碼

1 .首先FileReader對象實例化一個file對象數組

2 .在file對象onload事件裏進行處理微信

3 .使用XLSX.read解析dataantd

4 .first_worksheet是解析的數據

5 .XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });將工做簿對象轉化爲JSON對象

6 .handleImpotedJson方法能夠將json對象進行一系列操做 轉化到表格裏

handleImpotedJson = (array, file) => {
       
        const header = array[0];//頭部數據 ["姓名",...]
        const entozh = this.formatTitleOrFileld('title', 'dataIndex');//將表字段數組形式轉化爲對象形式,如:{"姓名":"name",...}
        const firstRow = header.map(item => entozh[item]);//能夠獲取到行屬性 ["name",...]

        const newArray = [...array];

        newArray.splice(0, 1);//去除表頭

        const json = newArray.map((item, index) => {
            const newitem = {};
            item.forEach((im, i) => {
                const newKey = firstRow[i] || i;
                newitem[newKey] = im
            })
            return newitem;
        });//將存在表頭定義字段的值賦值

        const formatData = json.map(item => ({
            name: item.name,
            age: item.age,
            address: item.address,
        }))//篩選出本身須要的屬性

        this.setState({ data: formatData, fileList: [file] });

        return formatData;
}

formatTitleOrFileld = (a, b) => {
        const entozh = {};
        this.state.columns.forEach(item => {
            entozh[item[a]] = item[b]
        })
        return entozh;
}
複製代碼

3.效果圖

3、excel導出

1.excel導出表格數據

1.先上代碼

<Button type="primary" onClick={this.handleExportAll}>Excel導出數據</Button>

handleExportAll = (e) => {
        const entozh = {
          "name":"姓名",
          "age":"年齡",
          "address":"地址"
        }

        const nowdata = this.state.data;

        const json = nowdata.map((item) => {
          return Object.keys(item).reduce((newData, key) => {
            const newKey = entozh[key] || key
            newData[newKey] = item[key]
            return newData
          }, {})
        });
  
  
        const sheet = XLSX.utils.json_to_sheet(json);
 
        this.openDownloadDialog(this.sheet2blob(sheet,undefined), `所有信息.xlsx`);
   
}
openDownloadDialog = (url, saveName) => {
        if (typeof url == 'object' && url instanceof Blob) {
          url = URL.createObjectURL(url); // 建立blob地址
        }
        var aLink = document.createElement('a');
        aLink.href = url;
        aLink.download = saveName || ''; // HTML5新增的屬性,指定保存文件名,能夠不要後綴,注意,file:///模式下不會生效
        var event;
        if (window.MouseEvent) event = new MouseEvent('click');
        else {
          event = document.createEvent('MouseEvents');
          event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        }
        aLink.dispatchEvent(event);
}
sheet2blob = (sheet, sheetName) => {
        sheetName = sheetName || 'sheet1';
        var workbook = {
          SheetNames: [sheetName],
          Sheets: {}
        };
        workbook.Sheets[sheetName] = sheet; // 生成excel的配置項
  
        var wopts = {
          bookType: 'xlsx', // 要生成的文件類型
          bookSST: false, // 是否生成Shared String Table,官方解釋是,若是開啓生成速度會降低,但在低版本IOS設備上有更好的兼容性
          type: 'binary'
        };
        var wbout = XLSX.write(workbook, wopts);
        var blob = new Blob([s2ab(wbout)], {
          type: "application/octet-stream"
        }); // 字符串轉ArrayBuffer
        function s2ab(s) {
          var buf = new ArrayBuffer(s.length);
          var view = new Uint8Array(buf);
          for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
          return buf;
        }
  
        return blob;
}
複製代碼

2.核心代碼講解

1.XLSX.utils.json_to_sheet

字面意思,能夠將工做簿對象轉化爲json對象
複製代碼

2.openDownloadDialog

此方法建立了a標籤 利用a標籤的download屬性進行下載文件
複製代碼

3.sheet2blob

能夠將工做簿對象轉化爲咱們須要的
複製代碼

3.效果圖

2.表格導出標準格式文件

其實和上面同樣 惟獨把表頭數據保存下來就行惟一的區別就是

let nowdata = [
            {"name":""},
            {"age":""},
            {"address":""},
            
];
複製代碼

將state中的data對象轉化爲空數組形式便可。

有不懂的能夠加我微信詢問我

相關文章
相關標籤/搜索