不管是作項目仍是本身學習過程當中,咱們可能會遇到導出數據的需求,好比導出數據到Excel文件。react
爲了方便你們的學習和開發,這裏介紹一種導出數據到Excel文件的方法。git
我在這裏使用 exceljs 包來導出數據,若是你有興趣,能夠閱讀一下他們的文檔:github
英文文檔:github.com/exceljs/exc…數組
中文文檔:github.com/exceljs/exc…markdown
若是你想直接看Demo和源碼,能夠直接訪問我在codesandbox部署的代碼:codesandbox.io/s/react-exp…app
導出後的數據以下:oop
首先咱們須要引入依賴包,定義導出Excel文件須要的數據,這裏提供一個對象數組便可,後面的代碼會從該數組中提取須要的數據。實例代碼以下:學習
import ExcelJs from "exceljs";
const mockData = [
{
Name: "Allen",
Gender: "Male",
Height: "175"
},
{
Name: "Tom",
Gender: "Male",
Height: "180"
},
{
Name: "Jane",
Gender: "Female",
Height: "170"
}
];
複製代碼
// 獲取sheet對象,設置當前sheet的樣式
// showGridLines: false 表示不顯示錶格邊框
let workbook = new ExcelJs.Workbook();
let sheetName = "Allen_test.xlsx";
let sheet = workbook.addWorksheet(sheetName, {
views: [{ showGridLines: false }]
});
// 每個sheet對象對應一個Excel文件中的表,若是你想子一個Excel中顯示多個表,能夠定義多個sheet
// let sheet2 = workbook.addWorksheet("Second sheet", { views: [{ showGridLines: false }] });
複製代碼
咱們在製做Excel表格的時候,通常都須要給每一列設置一個表頭,用來講明這一列展現的是什麼信息,咱們以前只定義了表格數據(前面的對象數組),這裏根據表格數據,獲取對應的表頭信息:優化
let columnArr = [];
for (let i in mockData[0]) {
let tempObj = { name: "" };
tempObj.name = i;
columnArr.push(tempObj);
}
複製代碼
在表格中,頂部能夠展現該表格的標題,說明,注意事項等信息。如上圖中的「This is the header text」 和「As of: 07/09/2021」。spa
咱們可使用以下代碼進行設置頂部信息,設置過程當中,能夠定義一個起始單元格,而後從該單元格開始,根據columns和rows數組,以此向右和向下的單元格中進行繪製。
sheet.addTable({
name: `Header`,
ref: "A1", // 頭部信息從A1單元格開始顯示
headerRow: true,
totalsRow: false,
style: {
theme: "",
showRowStripes: false,
showFirstColumn: true,
width: 200
},
columns: [{ name: "This is the header text" }], // 若是傳遞多個數組元素,會以此在B1, C3...單元格中繪製
rows: [[`As of: 07/09/2021`]] // 若是傳遞多個數組元素,會以此在A2, A3...單元格中繪製
});
複製代碼
頂部數據繪製完成以後,下面繼續繪製主題的數據部分,這是最關鍵的,咱們導出Excel文件就是爲了導出這些數據嘛。
// 設置表格的主要數據部分
let headerName = "RequestsList";
sheet.addTable({
name: headerName,
ref: "A5", // 主要數據從A5單元格開始
headerRow: true,
totalsRow: false,
style: {
theme: "TableStyleMedium2",
showRowStripes: false,
width: 200
},
columns: columnArr ? columnArr : [{ name: "" }], // 把以前定義的表頭數據傳遞進來
rows: mockData.map((e) => {
let arr = [];
for (let i in e) {
arr.push(e[i]);
}
return arr;
})
});
複製代碼
如今數據能夠正常導出了,可是導出的數據樣式是比較醜的,能夠參考一下代碼,優化這部分的樣式。對代碼不明白能夠閱讀註釋。
// 設置單元格的文字樣式
sheet.getCell("A1").font = { size: 20, bold: true };
// 設置每一列的寬度
sheet.columns = sheet.columns.map((e) => {
const expr = e.values[5];
switch (expr) {
case "Name":
return { width: 50 };
case "Gender":
return { width: 40 };
case "Height":
return { width: 30 };
default:
return { width: 20 };
}
});
const table = sheet.getTable(headerName);
for (let i = 0; i < table.table.columns.length; i++) {
// 表格主體數據是從A5開始繪製的,一共有三列。這裏是獲取A5到,B5,C5單元格,定義表格的頭部樣式
sheet.getCell(`${String.fromCharCode(65 + i)}5`).font = { size: 12 };
sheet.getCell(`${String.fromCharCode(65 + i)}5`).fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "c5d9f1" }
};
// 獲取表格數據部分,定義其樣式
for (let j = 0; j < table.table.rows.length; j++) {
let rowCell = sheet.getCell(`${String.fromCharCode(65 + i)}${j + 6}`);
rowCell.alignment = { wrapText: true };
rowCell.border = {
bottom: {
style: "thin",
color: { argb: "a6a6a6" }
}
};
}
}
table.commit();
複製代碼
如今Excel已經繪製完成了,咱們須要把數據導出到本地,代碼以下,很是簡單:
// 定義下載文件的方法
const writeFile = (fileName, content) => {
const link = document.createElement("a");
const blob = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = fileName;
link.href = URL.createObjectURL(blob);
link.click();
};
// 表格的數據繪製完成,定義下載方法,將數據導出到Excel文件
workbook.xlsx.writeBuffer().then((buffer) => {
writeFile(sheetName, buffer);
});
複製代碼
到這裏就完成了導出Excel的全部工做,這裏列出全部代碼,方便你進一步參考。
若是你想設置表格的其餘屬性,能夠查看官方文檔,我認爲是很是詳細的。
import React from "react";
import ExcelJs from "exceljs";
const mockData = [
{
Name: "Allen",
Gender: "Male",
Height: "175"
},
{
Name: "Tom",
Gender: "Male",
Height: "180"
},
{
Name: "Jane",
Gender: "Female",
Height: "170"
}
];
const ExportToExcel = () => {
const exportToExcel = (data) => {
let sheetName = "Allen_test.xlsx";
let headerName = "RequestsList";
// 獲取sheet對象,設置當前sheet的樣式
// showGridLines: false 表示不顯示錶格邊框
let workbook = new ExcelJs.Workbook();
let sheet = workbook.addWorksheet(sheetName, {
views: [{ showGridLines: false }]
});
// let sheet2 = workbook.addWorksheet("Second sheet", { views: [{ showGridLines: false }] });
// 獲取每一列的header
let columnArr = [];
for (let i in data[0]) {
let tempObj = { name: "" };
tempObj.name = i;
columnArr.push(tempObj);
}
// 設置表格的頭部信息,能夠用來設置標題,說明或者注意事項
sheet.addTable({
name: `Header`,
ref: "A1", // 頭部信息從A1單元格開始顯示
headerRow: true,
totalsRow: false,
style: {
theme: "",
showRowStripes: false,
showFirstColumn: true,
width: 200
},
columns: [{ name: "This is the header text" }, { name: "Hahaha" }],
rows: [[`As of: 07/09/2021`], [`Allen`]]
});
// 設置表格的主要數據部分
sheet.addTable({
name: headerName,
ref: "A5", // 主要數據從A5單元格開始
headerRow: true,
totalsRow: false,
style: {
theme: "TableStyleMedium2",
showRowStripes: false,
width: 200
},
columns: columnArr ? columnArr : [{ name: "" }],
rows: data.map((e) => {
let arr = [];
for (let i in e) {
arr.push(e[i]);
}
return arr;
})
});
sheet.getCell("A1").font = { size: 20, bold: true }; // 設置單元格的文字樣式
// 設置每一列的寬度
sheet.columns = sheet.columns.map((e) => {
const expr = e.values[5];
switch (expr) {
case "Name":
return { width: 50 };
case "Gender":
return { width: 40 };
case "Height":
return { width: 30 };
default:
return { width: 20 };
}
});
const table = sheet.getTable(headerName);
for (let i = 0; i < table.table.columns.length; i++) {
// 表格主體數據是從A5開始繪製的,一共有三列。這裏是獲取A5到,B5,C5單元格,定義表格的頭部樣式
sheet.getCell(`${String.fromCharCode(65 + i)}5`).font = { size: 12 };
sheet.getCell(`${String.fromCharCode(65 + i)}5`).fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "c5d9f1" }
};
// 獲取表格數據部分,定義其樣式
for (let j = 0; j < table.table.rows.length; j++) {
let rowCell = sheet.getCell(`${String.fromCharCode(65 + i)}${j + 6}`);
rowCell.alignment = { wrapText: true };
rowCell.border = {
bottom: {
style: "thin",
color: { argb: "a6a6a6" }
}
};
}
}
table.commit();
const writeFile = (fileName, content) => {
const link = document.createElement("a");
const blob = new Blob([content], {
type: "application/vnd.ms-excel;charset=utf-8;"
});
link.download = fileName;
link.href = URL.createObjectURL(blob);
link.click();
};
// 表格的數據繪製完成,定義下載方法,將數據導出到Excel文件
workbook.xlsx.writeBuffer().then((buffer) => {
writeFile(sheetName, buffer);
});
};
return (
<button
onClick={() => {
exportToExcel(mockData);
}}
>
Export to Excel
</button>
);
};
export default ExportToExcel;
複製代碼