react 实现导出功能

方法一、不与后端接口联调,使用插件
xlsx-oc插件

安装

npm i xlsx-oc

使用,实例

import React, { useState, useEffect } from 'react'
import { Button, message, Table } from 'antd';
import { exportExcel } from 'xlsx-oc'

interface PostData {
    current: number
    pageSize: number
    companyId?: number
    tel?: number
    startTime?: number
    endTime?: number
    stockCode?: number
}

export default function Jsplumb() {
    //分页参数
    const [postObj, setPostObj] = useState<PostData>({
        current: 1,
        pageSize: 10
    })
    const [total] = useState(10)
    const [data] = useState([{
        companyName: 'nnn',
        phone: '123456',
        stockCode: 'www',
        link: 'jj',
        createTime: 'ooo'
    }])


    //定义表头
    const columns = [
        {
            title: '序号',
            render: (text: any, record: any, index: any) => `${(postObj.current - 1) * postObj.pageSize + index + 1}`,
        },
        {
            title: '公司',
            dataIndex: 'companyName',
            key: 'companyName',
        },
        {
            title: '电话',
            dataIndex: 'phone',
            key: 'phone',
        },
        {
            title: '股票代码',
            dataIndex: 'stockCode',
            key: 'stockCode',
        },
        {
            title: '链接',
            dataIndex: 'link',
            key: 'link',
        },
        {
            title: '时间',
            dataIndex: 'createTime',
            key: 'createTime',
        },
    ];

    const exportFile = () => {
        const list = []
        for (let i = 0; i < data.length; i++) {
            const item = data[i]
            list.push({
                key: i,
                companyName: item.companyName,
                phone: item.phone,
                stockCode: item.stockCode,
                link: item.link,
                createTime: item.createTime,

            })
        }
        const header = [{ k: 'companyName', v: '公司' }, { k: 'phone', v: '电话' }, { k: 'stockCode', v: '股票代码' }, { k: 'link', v: '链接' }, { k: 'createTime', v: '时间' },]
        exportExcel(header, list)
    }
    return (
        <div style={{ width: '100%' }}>
            <div style={{ background: '#fff', width: '100%', padding: '28px' }}>
                <Button type="primary" style={{ marginBottom: '15px' }} onClick={exportFile}>导出</Button>
                <Table columns={columns} dataSource={data} pagination={{ pageSize: postObj.pageSize, total: total, current: postObj.current, showSizeChanger: true }} />
            </div>
        </div>
    )
}

react 实现导出功能_第1张图片
react 实现导出功能_第2张图片
方法二、与后端联调,后端返回文件流

  //导出
  const exportFile = () => {
    service.exportFile(postObj).then((res: any) => {
      //后端返回blob格式文件流,前端进行转码,得到url,实现下载文件功能
      let blob = new Blob([res], {
        type: 'application/vnd.ms-excel'
      })
      let objectUrl = URL.createObjectURL(blob)
      downloadFile(objectUrl, '我的资源.xlsx')
      message.success('导出成功')
    })
  }

  //下载文件
  const downloadFile = (content, filename) => {
    let a = document.createElement('a')
    a.href = content
    a.download = filename
    a.click()
  }
  
<Button type="primary" onClick={exportFile}>导出</Button>

前端使用arraybufferblob导出文本流,成功与失败格式不一样,当成功时是文本流,失败时是json

const exportFile = () => {
    service.exportFileSaller(postObj).then((res: any) => {
      let tempBlob = new Blob([res], {
        type: 'application/json',
      })
      const reader = new FileReader()
      reader.onload = e => {
      	// 此处对fileReader读出的结果进行JSON解析
   		// 可能会出现错误,需要进行捕获
        const result: any = e.target && e.target.result
        //判断返回格式是不是json,如果是,提示错误信息,不是就导出文件
        try {
          //json
          const json = JSON.parse(result)
          message.error(json.errorMsg)
        } catch (err) {
          // 该异常为无法将字符串转为json
     	  // 说明返回的数据是一个流文件
    	  // 不需要处理该异常,只需要捕获即刻
          let blob = new Blob([res], {
            type: 'application/vnd.ms-excel',
          })
          let objectUrl = URL.createObjectURL(blob)
          method.downloadFile(objectUrl, '资源管理.xlsx')
          message.success('导出成功')
        }
      }
      // 将blob对象以文本的方式读出,读出完成后将会执行 onload 方法
      reader.readAsText(tempBlob)
    })
  }

以上能实现导出功能,但文件不能打开
注意点
1、在axios请求时,设置responseType
responseType='blob'responseType = 'arraybuffer'都行

let baseConfig: AxiosRequestConfig = {
    baseURL: config.domain,
    headers: {
        token: sessionStorage.getItem('token') || '',
    },
    timeout: 8000,
    responseType: 'blob',
}

2、看项目中是否使用mock.js,若使用,把mock注释掉
原因:mock.js初始化时,给拦截响应设置了responseType:’’
注意两者都要满足

vs code 插件 live server

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