如何封装React组件实现接收Excel文件并下载导出的功能?

2026-04-02 06:511阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1813个文字,预计阅读时间需要8分钟。

如何封装React组件实现接收Excel文件并下载导出的功能?

目录 + React 接收 Excel 文件下载导出功能封装 + React 导出 Excel 文件的几种方式 + 1. 原生 JS 导出(带样式) + 2. 使用 xlsx 导出(此方法导出的 Excel 文件无样式,但文件格式是 xlsx) + 3. 使用 js-ex

目录
  • React接收excel文件下载导出功能封装
  • react导出excel文件的几种方式
    • 1.原生js导出(带样式)
    • 2.使用xlsx导出(此方法导出的excel文件无样式,但导出的文件格式是 xlsx格式)
    • 3.使用 js-export-excel (可以导出多张sheet表)
    • 4.第四种 使用react-html-table-to-excel 不推荐使用

React接收excel文件下载导出功能封装

因为最近项目又需求要导出excel,所以封装了这部分的功能,对fetch的封装做了修改,使之后的调用导出功能更为方便

首先这个项目请求是对fetch进行过封装的 ,如果对fetch有了解的话,我们知道fetch种response返回的是一个实现了Body接口的对象, 所以可以使用Body接口中的方法 json()处理json,blob ()处理成blob文件对象 方法, 所以要先对封装的请求方法做如下修改

export default function request(url, option,noToken = false,type = 'json') {   //这是封装request方法 noToken判断是否写代token  type用来区别 json/blob 这里我们需要下载文件所以传入blob     ...     .then(response => {           if (newOptions.method === 'DELETE' || response.status === 204) {             return response.text();           }           if(type == 'blob') {            return  response.blob();  //处理成blob文件类型           }           return response.json();         })      .then(response => {         if(type == 'blob') {         return URL.createObjectURL(response); //使用URL.createObjectURL将blob放入一个object'         ...         }        }     } }

上面我们通过一个参数,将blob文件处理成url

export async function exportExcel(params) {   return request(`/api/xxxxx/${params}`,{method: 'GET'} ,false ,'blob' ); }  

上面就是我们导出文件的请求接口,获得的是一个url,然后我们在effect中接受url

* exportExcel({payload}, {call,put}) {   try {     const url = yield call(exportExcel, payload); //收到一个url      let link = document.createElement('a') //创建一个a标签      link.style.display = 'none' //不显示      link.href = url  //将地址填入      link.setAttribute('download', '表格.xlsx') //设置下载属性,取个文件名      document.body.appendChild(link) //添加到页面上      link.click() //点击触发下载   } catch (e) {   } },

到这里就是实现了文件的导出,基本原理就是将接受的文件处理成url,用a标签触发下载

其实本来到这里就应该结束了,但是作为一个有原则的程序员, 反复添加a标签显示让我们觉得很不规范, 所以我们来改写成一直复用一个a标签来下载,动态修改url\\现在BasicLayout里加个a标签,因为这个是登陆都最先加载的,保证每个模块都能使用

   <a      style={{display: 'none'}}     ref={(link)=> {this.props.dispatch({type: 'global/saveLink', payload: link})}} //这个是用来讲a标签的ref存到redux里,随时可以调用    ></a>

**然后我们在modes/global里写两个reducer**

  reducers: {     saveLink(state, { payload }) {     //保存a标签       return {         ...state,         link: payload,       }     },     exportFile(state, { payload }) {     //设置a标签的地址并触发点击下载       state.link.href = payload.url       state.link.setAttribute('download',payload.name)       state.link.click()       return {         ...state,       };     }, }

然后我们在普通的模块中effect调用时只需要这么写

* exportExcel({payload}, {call,put}) {   try {     const url = yield call(exportExcel, payload); //收到一个url     yield put({type: 'global/exportFile',payload: {url,name: `表格.xlsx`}}) //设置地址并触发下载    } catch (e) {   } },

这样写方便了很多 ,其实最好的方式是将这部分代码封装到一个组件中,单独调用,这里就不演示了,写法差不多

react导出excel文件的几种方式

一共总结了四种方法 前两种适用范围比较广泛 可以适用导出多级表头合并等,第三种方法导出的文件比较中规中矩,但是支持导出多张sheet表。第四种方法导出不推荐使用

1.原生js导出(带样式)

/**  *  原生JS导出为excel文件  */ export const jsToExcel = (id, name) => {     //window.location.href='<%=basePath%>pmb/excelShowInfo.do';     //获取表格     var exportFileContent = document.getElementById(id).outerHTML;     //设置格式为Excel,表格内容通过btoa转化为base64,此方法只在文件较小时使用(小于1M)     //exportFileContent=window.btoa(unescape(encodeURIComponent(exportFileContent)));     //var link = "data:"+MIMEType+";base64," + exportFileContent;     //使用Blob     var blob = new Blob([exportFileContent], { type: "text/plain;charset=utf-8" });         //解决中文乱码问题     blob = new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type });     //设置链接     var link = window.URL.createObjectURL(blob);     var a = document.createElement("a");    //创建a标签     a.download = name;  //设置被下载的超链接目标(文件名)   建议文件后缀为 .xls     a.href = link;                            //设置a标签的链接     document.body.appendChild(a);            //a标签添加到页面     a.click();                                //设置a标签触发单击事件     document.body.removeChild(a);            //移除a标签 }

使用方式

<table id='table_report'>...</table>   <div onClick={() => jsToExcel('table_report', '现券交易异常日报.xls')}>导出</div>

如果想导出xlsx格式请参考方法2,方法1仅改文件后缀 不会被Excel识别 但是wps可以

2.使用xlsx导出(此方法导出的excel文件无样式,但导出的文件格式是 xlsx格式)

首先安装xlsx : yarn add xlsx

import XLSX from "xlsx"     /**  *  用XLSX导出 (导出无样式)  */ export const exportExcel = (id, name) => {     var exportFileContent = document.getElementById(id).cloneNode(true);     var wb = XLSX.utils.table_to_book(exportFileContent, { sheet: "sheet1" });     XLSX.writeFile(wb, name); }    

使用方式

<table id='table_report'>...</table>   <div onClick = {() => exportExcel('table_report', '现券交易异常日报.xlsx')}>导出</div>

3.使用 js-export-excel (可以导出多张sheet表)

首先安装 js-export-excel : yarn add js-export-excel

import { Table } from 'antd'; import { columns } from './config'; import ExportJsonExcel from "js-export-excel"; import { PlusCircleOutlined } from '@ant-design/icons';   function Tables(props) {   const { isLoading, viewData, data } = props;   // data格式   const data1 = [     {       adID: "张三",       leaveCount: 26,       leaveDuration: 82,       leaveType: "调休",       name: "张三"     },     {       adID: "张三1",       leaveCount: 526,       leaveDuration: 82,       leaveType: "调休",       name: "张三1"     },     {       adID: "张三1",       leaveCount: 26,       leaveDuration: 852,       leaveType: "调休",       name: "张三1"     },     {       adID: "张三1",       leaveCount: 256,       leaveDuration: 82,       leaveType: "调休",       name: "张三1"     },   ]   /**    *  导出数据    */   const handleExportCurrentExcel = (data) => {     let sheetFilter = ["name", "leaveType", "leaveCount", "leaveDuration"];     let sheetFilter2 = ["name", "leaveType", "leaveCount", "leaveDuration"];     let option = {};     option.fileName = '考勤分析结果';     option.datas = [       {         sheetData: data1,         sheetName: '考勤分析结果',         sheetFilter: sheetFilter,         sheetHeader: ['姓名', '类型', '次数', '时长'],         columnWidths: [10, 10, 10, 10]       },       {         sheetData: data1,  //比较懒得造数据了  跟表1数据一样         sheetName: '考勤分析结果222',         sheetFilter: sheetFilter2,         sheetHeader: ['姓名22', '类型22', '次数22', '时长22'],         columnWidths: [10, 10, 10, 10]       },     ];     var toExcel = new ExportJsonExcel(option); //new     toExcel.saveExcel(); //保存   }     return (     <div>       <div className='exportButton' onClick={() => handleExportCurrentExcel(data)}>         <PlusCircleOutlined className='icon-but' />         导出当前数据       </div>       <Table         loading={isLoading}         columns={columns}         dataSource={viewData}         pagination={false}       />     </div>   ) } export default Tables;

4.第四种 使用react-html-table-to-excel 不推荐使用

安装 react-html-table-to-excel : yarn add react-html-table-to-excel

import React, {  useRef, useEffect } from 'react'; import { Table } from "antd"; import {  columns } from './config'; import ReactHTMLTableToExcel from 'react-html-table-to-excel'; import styles from './index.module.less'; function StudyExcel() {       const data = [         {             key: '0',             name: '张三'         },         {             key: '1',             name: '赵四'         },         {             key: '2',             name: '王五'         },         {             key: '3',             name: '齐六'         }     ];       // 用ref来获取组件按钮实例,使用里面的方法     const buttonRef = useRef(null);       // 禁止组件按钮的默认点击事件     useEffect(() => {         const button = document.querySelector('#test-table-xls-button');         button.style['pointer-events'] = ('none');     }, []);         // 导出表格     const exportTable = (e) => {         e.stopPropagation();         const table = document.getElementsByTagName('table');         const container = document.querySelector('#hiddenBox');         const tempTable = document.createElement('table');         tempTable.appendChild(table[0]);         tempTable.setAttribute('id', 'table-to-xls');                    // 给table添加id,值与按钮上的table字段对应         container.appendChild(tempTable);                                // 把创建的节点添加到页面容器中         buttonRef.current.handleDownload();                              // 手动触发下载     };     return (         <div style={{ backgroundColor: '#fff' }} className={styles.container}>             <span onClick={(e) => exportTable(e)}>                 <ReactHTMLTableToExcel                     width={1900}                     ref={buttonRef}                     table="table-to-xls"                     id='test-table-xls-button'                     filename='回购日报'                     sheet='表1'                     buttonText='导出Excel'                 />             </span>             <Table                 columns={columns}                 dataSource={data}                 bordered                 pagination={false}             />             <div id='hiddenBox' style={{ position: 'absolute', zIndex: -1, top: 0, left: 0 }} />         </div>     ) } export default StudyExcel;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

如何封装React组件实现接收Excel文件并下载导出的功能?

本文共计1813个文字,预计阅读时间需要8分钟。

如何封装React组件实现接收Excel文件并下载导出的功能?

目录 + React 接收 Excel 文件下载导出功能封装 + React 导出 Excel 文件的几种方式 + 1. 原生 JS 导出(带样式) + 2. 使用 xlsx 导出(此方法导出的 Excel 文件无样式,但文件格式是 xlsx) + 3. 使用 js-ex

目录
  • React接收excel文件下载导出功能封装
  • react导出excel文件的几种方式
    • 1.原生js导出(带样式)
    • 2.使用xlsx导出(此方法导出的excel文件无样式,但导出的文件格式是 xlsx格式)
    • 3.使用 js-export-excel (可以导出多张sheet表)
    • 4.第四种 使用react-html-table-to-excel 不推荐使用

React接收excel文件下载导出功能封装

因为最近项目又需求要导出excel,所以封装了这部分的功能,对fetch的封装做了修改,使之后的调用导出功能更为方便

首先这个项目请求是对fetch进行过封装的 ,如果对fetch有了解的话,我们知道fetch种response返回的是一个实现了Body接口的对象, 所以可以使用Body接口中的方法 json()处理json,blob ()处理成blob文件对象 方法, 所以要先对封装的请求方法做如下修改

export default function request(url, option,noToken = false,type = 'json') {   //这是封装request方法 noToken判断是否写代token  type用来区别 json/blob 这里我们需要下载文件所以传入blob     ...     .then(response => {           if (newOptions.method === 'DELETE' || response.status === 204) {             return response.text();           }           if(type == 'blob') {            return  response.blob();  //处理成blob文件类型           }           return response.json();         })      .then(response => {         if(type == 'blob') {         return URL.createObjectURL(response); //使用URL.createObjectURL将blob放入一个object'         ...         }        }     } }

上面我们通过一个参数,将blob文件处理成url

export async function exportExcel(params) {   return request(`/api/xxxxx/${params}`,{method: 'GET'} ,false ,'blob' ); }  

上面就是我们导出文件的请求接口,获得的是一个url,然后我们在effect中接受url

* exportExcel({payload}, {call,put}) {   try {     const url = yield call(exportExcel, payload); //收到一个url      let link = document.createElement('a') //创建一个a标签      link.style.display = 'none' //不显示      link.href = url  //将地址填入      link.setAttribute('download', '表格.xlsx') //设置下载属性,取个文件名      document.body.appendChild(link) //添加到页面上      link.click() //点击触发下载   } catch (e) {   } },

到这里就是实现了文件的导出,基本原理就是将接受的文件处理成url,用a标签触发下载

其实本来到这里就应该结束了,但是作为一个有原则的程序员, 反复添加a标签显示让我们觉得很不规范, 所以我们来改写成一直复用一个a标签来下载,动态修改url\\现在BasicLayout里加个a标签,因为这个是登陆都最先加载的,保证每个模块都能使用

   <a      style={{display: 'none'}}     ref={(link)=> {this.props.dispatch({type: 'global/saveLink', payload: link})}} //这个是用来讲a标签的ref存到redux里,随时可以调用    ></a>

**然后我们在modes/global里写两个reducer**

  reducers: {     saveLink(state, { payload }) {     //保存a标签       return {         ...state,         link: payload,       }     },     exportFile(state, { payload }) {     //设置a标签的地址并触发点击下载       state.link.href = payload.url       state.link.setAttribute('download',payload.name)       state.link.click()       return {         ...state,       };     }, }

然后我们在普通的模块中effect调用时只需要这么写

* exportExcel({payload}, {call,put}) {   try {     const url = yield call(exportExcel, payload); //收到一个url     yield put({type: 'global/exportFile',payload: {url,name: `表格.xlsx`}}) //设置地址并触发下载    } catch (e) {   } },

这样写方便了很多 ,其实最好的方式是将这部分代码封装到一个组件中,单独调用,这里就不演示了,写法差不多

react导出excel文件的几种方式

一共总结了四种方法 前两种适用范围比较广泛 可以适用导出多级表头合并等,第三种方法导出的文件比较中规中矩,但是支持导出多张sheet表。第四种方法导出不推荐使用

1.原生js导出(带样式)

/**  *  原生JS导出为excel文件  */ export const jsToExcel = (id, name) => {     //window.location.href='<%=basePath%>pmb/excelShowInfo.do';     //获取表格     var exportFileContent = document.getElementById(id).outerHTML;     //设置格式为Excel,表格内容通过btoa转化为base64,此方法只在文件较小时使用(小于1M)     //exportFileContent=window.btoa(unescape(encodeURIComponent(exportFileContent)));     //var link = "data:"+MIMEType+";base64," + exportFileContent;     //使用Blob     var blob = new Blob([exportFileContent], { type: "text/plain;charset=utf-8" });         //解决中文乱码问题     blob = new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type });     //设置链接     var link = window.URL.createObjectURL(blob);     var a = document.createElement("a");    //创建a标签     a.download = name;  //设置被下载的超链接目标(文件名)   建议文件后缀为 .xls     a.href = link;                            //设置a标签的链接     document.body.appendChild(a);            //a标签添加到页面     a.click();                                //设置a标签触发单击事件     document.body.removeChild(a);            //移除a标签 }

使用方式

<table id='table_report'>...</table>   <div onClick={() => jsToExcel('table_report', '现券交易异常日报.xls')}>导出</div>

如果想导出xlsx格式请参考方法2,方法1仅改文件后缀 不会被Excel识别 但是wps可以

2.使用xlsx导出(此方法导出的excel文件无样式,但导出的文件格式是 xlsx格式)

首先安装xlsx : yarn add xlsx

import XLSX from "xlsx"     /**  *  用XLSX导出 (导出无样式)  */ export const exportExcel = (id, name) => {     var exportFileContent = document.getElementById(id).cloneNode(true);     var wb = XLSX.utils.table_to_book(exportFileContent, { sheet: "sheet1" });     XLSX.writeFile(wb, name); }    

使用方式

<table id='table_report'>...</table>   <div onClick = {() => exportExcel('table_report', '现券交易异常日报.xlsx')}>导出</div>

3.使用 js-export-excel (可以导出多张sheet表)

首先安装 js-export-excel : yarn add js-export-excel

import { Table } from 'antd'; import { columns } from './config'; import ExportJsonExcel from "js-export-excel"; import { PlusCircleOutlined } from '@ant-design/icons';   function Tables(props) {   const { isLoading, viewData, data } = props;   // data格式   const data1 = [     {       adID: "张三",       leaveCount: 26,       leaveDuration: 82,       leaveType: "调休",       name: "张三"     },     {       adID: "张三1",       leaveCount: 526,       leaveDuration: 82,       leaveType: "调休",       name: "张三1"     },     {       adID: "张三1",       leaveCount: 26,       leaveDuration: 852,       leaveType: "调休",       name: "张三1"     },     {       adID: "张三1",       leaveCount: 256,       leaveDuration: 82,       leaveType: "调休",       name: "张三1"     },   ]   /**    *  导出数据    */   const handleExportCurrentExcel = (data) => {     let sheetFilter = ["name", "leaveType", "leaveCount", "leaveDuration"];     let sheetFilter2 = ["name", "leaveType", "leaveCount", "leaveDuration"];     let option = {};     option.fileName = '考勤分析结果';     option.datas = [       {         sheetData: data1,         sheetName: '考勤分析结果',         sheetFilter: sheetFilter,         sheetHeader: ['姓名', '类型', '次数', '时长'],         columnWidths: [10, 10, 10, 10]       },       {         sheetData: data1,  //比较懒得造数据了  跟表1数据一样         sheetName: '考勤分析结果222',         sheetFilter: sheetFilter2,         sheetHeader: ['姓名22', '类型22', '次数22', '时长22'],         columnWidths: [10, 10, 10, 10]       },     ];     var toExcel = new ExportJsonExcel(option); //new     toExcel.saveExcel(); //保存   }     return (     <div>       <div className='exportButton' onClick={() => handleExportCurrentExcel(data)}>         <PlusCircleOutlined className='icon-but' />         导出当前数据       </div>       <Table         loading={isLoading}         columns={columns}         dataSource={viewData}         pagination={false}       />     </div>   ) } export default Tables;

4.第四种 使用react-html-table-to-excel 不推荐使用

安装 react-html-table-to-excel : yarn add react-html-table-to-excel

import React, {  useRef, useEffect } from 'react'; import { Table } from "antd"; import {  columns } from './config'; import ReactHTMLTableToExcel from 'react-html-table-to-excel'; import styles from './index.module.less'; function StudyExcel() {       const data = [         {             key: '0',             name: '张三'         },         {             key: '1',             name: '赵四'         },         {             key: '2',             name: '王五'         },         {             key: '3',             name: '齐六'         }     ];       // 用ref来获取组件按钮实例,使用里面的方法     const buttonRef = useRef(null);       // 禁止组件按钮的默认点击事件     useEffect(() => {         const button = document.querySelector('#test-table-xls-button');         button.style['pointer-events'] = ('none');     }, []);         // 导出表格     const exportTable = (e) => {         e.stopPropagation();         const table = document.getElementsByTagName('table');         const container = document.querySelector('#hiddenBox');         const tempTable = document.createElement('table');         tempTable.appendChild(table[0]);         tempTable.setAttribute('id', 'table-to-xls');                    // 给table添加id,值与按钮上的table字段对应         container.appendChild(tempTable);                                // 把创建的节点添加到页面容器中         buttonRef.current.handleDownload();                              // 手动触发下载     };     return (         <div style={{ backgroundColor: '#fff' }} className={styles.container}>             <span onClick={(e) => exportTable(e)}>                 <ReactHTMLTableToExcel                     width={1900}                     ref={buttonRef}                     table="table-to-xls"                     id='test-table-xls-button'                     filename='回购日报'                     sheet='表1'                     buttonText='导出Excel'                 />             </span>             <Table                 columns={columns}                 dataSource={data}                 bordered                 pagination={false}             />             <div id='hiddenBox' style={{ position: 'absolute', zIndex: -1, top: 0, left: 0 }} />         </div>     ) } export default StudyExcel;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

如何封装React组件实现接收Excel文件并下载导出的功能?