React實現(xiàn)導(dǎo)出excel文件的操作步驟
在 React 項目中實現(xiàn)點擊按鈕后導(dǎo)出數(shù)據(jù)為 Excel 文件,可以使用 xlsx 和 file-saver 這兩個庫。
一、安裝依賴
在項目中安裝必要的庫:
npm install xlsx file-saver
- xlsx:用于生成 Excel 文件。
- file-saver:用于觸發(fā)文件下載。
二、實現(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)建一個新的工作簿
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 時,如果需要自定義列標(biāo)題,可以通過手動創(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)容長度可能變化,可以動態(tài)計算 wch:
const columnWidths = [
{ wch: Math.max(...data.map(item => item.name.length), 10) }, // 動態(tài)計算第一列寬度
{ wch: 5 },
{ wch: Math.max(...data.map(item => item.city.length), 15) },
];
worksheet['!cols'] = columnWidths;
- 注意事項
1.如果未設(shè)置 !cols,默認(rèn)列寬會很窄,可能導(dǎo)致數(shù)據(jù)被截斷。
2.wch 值可以設(shè)置為整數(shù)或浮點數(shù),決定寬度的字符數(shù)。
3.列寬不會強制影響單元格內(nèi)容換行。若希望內(nèi)容換行,需要在單元格內(nèi)容中加入換行符 \n 并配合樣式(需借助 xlsx-style 或其他擴展庫)。
五、樣式優(yōu)化
在 xlsx 中,默認(rèn)的導(dǎo)出樣式較為基礎(chǔ)。如果需要對 Excel 文件進(jìn)行樣式優(yōu)化(如字體、顏色、邊框、對齊方式等),可以通過擴展庫 xlsx-style 或 sheetjs-style 實現(xiàn)。
1、安裝擴展庫
這是一種擴展版的 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' }, // 居中對齊
};
const bodyStyle = {
font: { color: { rgb: '000000' } }, // 黑色字體
alignment: { horizontal: 'left', vertical: 'center' }, // 左對齊
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、擴展樣式功能
- 單元格合并: 使用 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:表示合并范圍的 起始單元格,包含兩個屬性:
r:行號,從 0 開始(例如,第 1 行為 0)。c:列號,從 0 開始(例如,A 列為 0,B 列為 1)。
e:表示合并范圍的 結(jié)束單元格,包含同樣的 r 和 c 屬性。
- 動態(tài)樣式: 根據(jù)數(shù)據(jù)動態(tài)調(diào)整單元格樣式,例如:
if (row.age > 30) {
worksheet[cellAddress].s = { fill: { fgColor: { rgb: 'FFC7CE' } } }; // 背景變紅
}
- 自動篩選: 設(shè)置自動篩選功能(表頭下的篩選按鈕):
worksheet['!autofilter'] = { ref: 'A1:C1' }; // 設(shè)置 A1:C1 的自動篩選
到此這篇關(guān)于React實現(xiàn)導(dǎo)出excel文件的操作步驟的文章就介紹到這了,更多相關(guān)React導(dǎo)出excel文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React 進(jìn)入頁面后自動 focus 到某個輸入框的解決方案
React.js 當(dāng)中提供了 ref 屬性來幫助我們獲取已經(jīng)掛載的元素的 DOM 節(jié)點,你可以給某個 JSX 元素加上 ref屬性,這篇文章主要介紹了React 進(jìn)入頁面以后自動 focus 到某個輸入框,需要的朋友可以參考下2024-02-02
react-redux的connect與React.forwardRef結(jié)合ref失效的解決
這篇文章主要介紹了react-redux的connect與React.forwardRef結(jié)合ref失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能
這篇文章主要介紹了react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能,大概思路是用一個div包裹echarts, 然后在echarts的同級新建一個div用來用來模擬真實tooltip,通過鼠標(biāo)移入移出事件控制真實tooltip的顯示與隱藏,需要的朋友可以參考下2023-05-05
在react項目中webpack使用mock數(shù)據(jù)的操作方法
這篇文章主要介紹了在react項目中webpack使用mock數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06
React中useCallback useMemo到底該怎么用
在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時,默認(rèn)情況下整個組件都會重新渲染。換句話說,如果組件中的任何值更新,整個組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender2023-02-02
ReactNative-JS 調(diào)用原生方法實例代碼
這篇文章主要介紹了ReactNative-JS 調(diào)用原生方法實例代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10

