React實(shí)現(xiàn)導(dǎo)出excel文件的操作步驟
在 React 項(xiàng)目中實(shí)現(xiàn)點(diǎn)擊按鈕后導(dǎo)出數(shù)據(jù)為 Excel 文件,可以使用 xlsx 和 file-saver 這兩個(gè)庫。
一、安裝依賴
在項(xiàng)目中安裝必要的庫:
npm install xlsx file-saver
- xlsx:用于生成 Excel 文件。
- file-saver:用于觸發(fā)文件下載。
二、實(shí)現(xiàn)導(dǎo)出功能
import React from 'react'; import * as XLSX from 'xlsx'; // 用于操作 Excel 文件 import { saveAs } from 'file-saver'; // 用于保存文件 const ExportExcel = () => { const handleExport = () => { // 示例數(shù)據(jù) const data = [ { Name: 'John Doe', Age: 28, City: 'New York' }, { Name: 'Jane Smith', Age: 34, City: 'San Francisco' }, { Name: 'Sam Green', Age: 45, City: 'Chicago' }, ]; // 將數(shù)據(jù)轉(zhuǎn)換為工作表 const worksheet = XLSX.utils.json_to_sheet(data); // 創(chuàng)建一個(gè)新的工作簿 const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); // 導(dǎo)出為 Blob const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }); // 使用 FileSaver 保存文件 saveAs(blob, 'example.xlsx'); }; return ( <div> <button onClick={handleExport}>導(dǎo)出 Excel</button> </div> ); }; export default ExportExcel;
三、自定義列標(biāo)題
在使用 xlsx 時(shí),如果需要自定義列標(biāo)題,可以通過手動(dòng)創(chuàng)建數(shù)據(jù)表頭,然后將其與數(shù)據(jù)合并為新的數(shù)組,最后生成工作表。
import React from 'react'; import * as XLSX from 'xlsx'; // 用于操作 Excel 文件 import { saveAs } from 'file-saver'; // 用于保存文件 const ExportExcelWithHeaders = () => { const handleExport = () => { // 示例數(shù)據(jù) const data = [ { name: 'John Doe', age: 28, city: 'New York' }, { name: 'Jane Smith', age: 34, city: 'San Francisco' }, { name: 'Sam Green', age: 45, city: 'Chicago' }, ]; // 自定義列標(biāo)題 const headers = ['Name', 'Age', 'City']; // 數(shù)據(jù)按自定義順序排序 const formattedData = data.map((item) => [item.name, item.age, item.city]); // 將列標(biāo)題與數(shù)據(jù)合并 const worksheetData = [headers, ...formattedData]; // 創(chuàng)建工作表 const worksheet = XLSX.utils.aoa_to_sheet(worksheetData); // 創(chuàng)建工作簿并添加工作表 const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); // 導(dǎo)出為 Blob const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }); // 使用 FileSaver 保存文件 saveAs(blob, 'example_with_headers.xlsx'); }; return ( <div> <button onClick={handleExport}>導(dǎo)出帶自定義標(biāo)題的 Excel</button> </div> ); }; export default ExportExcelWithHeaders;
四、設(shè)置列寬度
在 xlsx 中,可以通過設(shè)置工作表的 !cols 屬性來自定義每一列的寬度。
import React from 'react'; import * as XLSX from 'xlsx'; import { saveAs } from 'file-saver'; const ExportExcelWithColumnWidths = () => { ... ... // 創(chuàng)建工作表 const worksheet = XLSX.utils.aoa_to_sheet(worksheetData); // 設(shè)置列寬 worksheet['!cols'] = [ { wch: 15 }, // 第一列寬度:15字符 { wch: 5 }, // 第二列寬度:5字符 { wch: 20 }, // 第三列寬度:20字符 ]; // 創(chuàng)建工作簿并添加工作表 const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); ... ... }; ... ... }; export default ExportExcelWithColumnWidths;
- 列寬與內(nèi)容長度匹配: 如果列內(nèi)容長度可能變化,可以動(dòng)態(tài)計(jì)算 wch:
const columnWidths = [ { wch: Math.max(...data.map(item => item.name.length), 10) }, // 動(dòng)態(tài)計(jì)算第一列寬度 { wch: 5 }, { wch: Math.max(...data.map(item => item.city.length), 15) }, ]; worksheet['!cols'] = columnWidths;
- 注意事項(xiàng)
1.如果未設(shè)置 !cols,默認(rèn)列寬會(huì)很窄,可能導(dǎo)致數(shù)據(jù)被截?cái)唷?br />2.wch 值可以設(shè)置為整數(shù)或浮點(diǎn)數(shù),決定寬度的字符數(shù)。
3.列寬不會(huì)強(qiáng)制影響單元格內(nèi)容換行。若希望內(nèi)容換行,需要在單元格內(nèi)容中加入換行符 \n 并配合樣式(需借助 xlsx-style 或其他擴(kuò)展庫)。
五、樣式優(yōu)化
在 xlsx 中,默認(rèn)的導(dǎo)出樣式較為基礎(chǔ)。如果需要對(duì) Excel 文件進(jìn)行樣式優(yōu)化(如字體、顏色、邊框、對(duì)齊方式等),可以通過擴(kuò)展庫 xlsx-style 或 sheetjs-style 實(shí)現(xiàn)。
1、安裝擴(kuò)展庫
這是一種擴(kuò)展版的 xlsx,可以在導(dǎo)出的 Excel 中應(yīng)用樣式
npm install sheetjs-style
2、設(shè)置樣式
import React from 'react'; import * as XLSX from 'sheetjs-style'; // 替代 xlsx 庫 import { saveAs } from 'file-saver'; // 用于保存文件 const ExportExcelWithStyles = () => { const handleExport = () => { // 示例數(shù)據(jù) const data = [ { name: 'John Doe', age: 28, city: 'New York' }, { name: 'Jane Smith', age: 34, city: 'San Francisco' }, { name: 'Sam Green', age: 45, city: 'Chicago' }, ]; // 自定義列標(biāo)題 const headers = ['Name', 'Age', 'City']; // 格式化數(shù)據(jù) const formattedData = data.map((item) => [item.name, item.age, item.city]); // 將標(biāo)題與數(shù)據(jù)合并 const worksheetData = [headers, ...formattedData]; // 創(chuàng)建工作表 const worksheet = XLSX.utils.aoa_to_sheet(worksheetData); // 設(shè)置樣式 const headerStyle = { font: { bold: true, color: { rgb: 'FFFFFF' } }, // 粗體,白色字體 fill: { fgColor: { rgb: '4F81BD' } }, // 藍(lán)色背景 alignment: { horizontal: 'center', vertical: 'center' }, // 居中對(duì)齊 }; const bodyStyle = { font: { color: { rgb: '000000' } }, // 黑色字體 alignment: { horizontal: 'left', vertical: 'center' }, // 左對(duì)齊 border: { top: { style: 'thin', color: { rgb: 'CCCCCC' } }, bottom: { style: 'thin', color: { rgb: 'CCCCCC' } }, left: { style: 'thin', color: { rgb: 'CCCCCC' } }, right: { style: 'thin', color: { rgb: 'CCCCCC' } }, }, }; // 使用 XLSX.utils.encode_cell 獲取單元格的地址,應(yīng)用樣式到標(biāo)題行 headers.forEach((_, colIndex) => { const cellAddress = XLSX.utils.encode_cell({ r: 0, c: colIndex }); //設(shè)置單元格樣式 worksheet[cellAddress].s = headerStyle; }); // 應(yīng)用樣式到數(shù)據(jù)行 formattedData.forEach((row, rowIndex) => { row.forEach((_, colIndex) => { const cellAddress = XLSX.utils.encode_cell({ r: rowIndex + 1, c: colIndex }); if (worksheet[cellAddress]) { worksheet[cellAddress].s = bodyStyle; } }); }); // 設(shè)置列寬 worksheet['!cols'] = [ { wch: 15 }, // 第一列寬度:15字符 { wch: 5 }, // 第二列寬度:5字符 { wch: 20 }, // 第三列寬度:20字符 ]; // 創(chuàng)建工作簿并添加工作表 const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Styled Sheet'); // 導(dǎo)出為 Blob const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }); // 使用 FileSaver 保存文件 saveAs(blob, 'styled_example.xlsx'); }; return ( <div> <button onClick={handleExport}>導(dǎo)出帶樣式的 Excel</button> </div> ); }; export default ExportExcelWithStyles;
效果:
3、擴(kuò)展樣式功能
- 單元格合并: 使用 worksheet[‘!merges’] 屬性:
worksheet['!merges'] = [ { s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }, // 合并第1行,第1~第3列 ];
語法結(jié)構(gòu):
worksheet['!merges'] = [ { s: { r: 起始行, c: 起始列 }, e: { r: 結(jié)束行, c: 結(jié)束列 } }, ];
s
:表示合并范圍的 起始單元格,包含兩個(gè)屬性:
r
:行號(hào),從 0 開始(例如,第 1 行為 0)。c
:列號(hào),從 0 開始(例如,A 列為 0,B 列為 1)。
e
:表示合并范圍的 結(jié)束單元格,包含同樣的 r 和 c 屬性。
- 動(dòng)態(tài)樣式: 根據(jù)數(shù)據(jù)動(dòng)態(tài)調(diào)整單元格樣式,例如:
if (row.age > 30) { worksheet[cellAddress].s = { fill: { fgColor: { rgb: 'FFC7CE' } } }; // 背景變紅 }
- 自動(dòng)篩選: 設(shè)置自動(dòng)篩選功能(表頭下的篩選按鈕):
worksheet['!autofilter'] = { ref: 'A1:C1' }; // 設(shè)置 A1:C1 的自動(dòng)篩選
到此這篇關(guān)于React實(shí)現(xiàn)導(dǎo)出excel文件的操作步驟的文章就介紹到這了,更多相關(guān)React導(dǎo)出excel文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React 進(jìn)入頁面后自動(dòng) focus 到某個(gè)輸入框的解決方案
React.js 當(dāng)中提供了 ref 屬性來幫助我們獲取已經(jīng)掛載的元素的 DOM 節(jié)點(diǎn),你可以給某個(gè) JSX 元素加上 ref屬性,這篇文章主要介紹了React 進(jìn)入頁面以后自動(dòng) focus 到某個(gè)輸入框,需要的朋友可以參考下2024-02-02react-redux的connect與React.forwardRef結(jié)合ref失效的解決
這篇文章主要介紹了react-redux的connect與React.forwardRef結(jié)合ref失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能
這篇文章主要介紹了react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能,大概思路是用一個(gè)div包裹echarts, 然后在echarts的同級(jí)新建一個(gè)div用來用來模擬真實(shí)tooltip,通過鼠標(biāo)移入移出事件控制真實(shí)tooltip的顯示與隱藏,需要的朋友可以參考下2023-05-05在react項(xiàng)目中webpack使用mock數(shù)據(jù)的操作方法
這篇文章主要介紹了在react項(xiàng)目中webpack使用mock數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06React中useCallback useMemo到底該怎么用
在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時(shí),默認(rèn)情況下整個(gè)組件都會(huì)重新渲染。換句話說,如果組件中的任何值更新,整個(gè)組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender2023-02-02ReactNative-JS 調(diào)用原生方法實(shí)例代碼
這篇文章主要介紹了ReactNative-JS 調(diào)用原生方法實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10